blob: 268c5b4e5fb4df5164d0032cdb82216be35d71e4 [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 "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
28#include "clang/Basic/Version.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
31#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000032#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000033#include "clang/Lex/HeaderSearch.h"
34#include "clang/Lex/Lexer.h"
35#include "clang/Lex/PreprocessingRecord.h"
36#include "clang/Lex/Preprocessor.h"
37#include "llvm/ADT/Optional.h"
38#include "llvm/ADT/STLExtras.h"
39#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000040#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/Support/Compiler.h"
42#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/MemoryBuffer.h"
45#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/Program.h"
47#include "llvm/Support/SaveAndRestore.h"
48#include "llvm/Support/Signals.h"
49#include "llvm/Support/Threading.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000052
53#if HAVE_PTHREAD_H
54#include <pthread.h>
55#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000056
57using namespace clang;
58using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000059using namespace clang::cxtu;
60using namespace clang::cxindex;
61
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000062CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
63 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000064 return 0;
65 CXTranslationUnit D = new CXTranslationUnitImpl();
66 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000067 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000068 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000069 D->Diagnostics = 0;
70 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000071 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000072 return D;
73}
74
75cxtu::CXTUOwner::~CXTUOwner() {
76 if (TU)
77 clang_disposeTranslationUnit(TU);
78}
79
80/// \brief Compare two source ranges to determine their relative position in
81/// the translation unit.
82static RangeComparisonResult RangeCompare(SourceManager &SM,
83 SourceRange R1,
84 SourceRange R2) {
85 assert(R1.isValid() && "First range is invalid?");
86 assert(R2.isValid() && "Second range is invalid?");
87 if (R1.getEnd() != R2.getBegin() &&
88 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
89 return RangeBefore;
90 if (R2.getEnd() != R1.getBegin() &&
91 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
92 return RangeAfter;
93 return RangeOverlap;
94}
95
96/// \brief Determine if a source location falls within, before, or after a
97/// a given source range.
98static RangeComparisonResult LocationCompare(SourceManager &SM,
99 SourceLocation L, SourceRange R) {
100 assert(R.isValid() && "First range is invalid?");
101 assert(L.isValid() && "Second range is invalid?");
102 if (L == R.getBegin() || L == R.getEnd())
103 return RangeOverlap;
104 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
105 return RangeBefore;
106 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
107 return RangeAfter;
108 return RangeOverlap;
109}
110
111/// \brief Translate a Clang source range into a CIndex source range.
112///
113/// Clang internally represents ranges where the end location points to the
114/// start of the token at the end. However, for external clients it is more
115/// useful to have a CXSourceRange be a proper half-open interval. This routine
116/// does the appropriate translation.
117CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
118 const LangOptions &LangOpts,
119 const CharSourceRange &R) {
120 // We want the last character in this location, so we will adjust the
121 // location accordingly.
122 SourceLocation EndLoc = R.getEnd();
123 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
124 EndLoc = SM.getExpansionRange(EndLoc).second;
125 if (R.isTokenRange() && !EndLoc.isInvalid()) {
126 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
127 SM, LangOpts);
128 EndLoc = EndLoc.getLocWithOffset(Length);
129 }
130
Bill Wendlingeade3622013-01-23 08:25:41 +0000131 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000132 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000133 R.getBegin().getRawEncoding(),
134 EndLoc.getRawEncoding()
135 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000136 return Result;
137}
138
139//===----------------------------------------------------------------------===//
140// Cursor visitor.
141//===----------------------------------------------------------------------===//
142
143static SourceRange getRawCursorExtent(CXCursor C);
144static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
145
146
147RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
148 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
149}
150
151/// \brief Visit the given cursor and, if requested by the visitor,
152/// its children.
153///
154/// \param Cursor the cursor to visit.
155///
156/// \param CheckedRegionOfInterest if true, then the caller already checked
157/// that this cursor is within the region of interest.
158///
159/// \returns true if the visitation should be aborted, false if it
160/// should continue.
161bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
162 if (clang_isInvalid(Cursor.kind))
163 return false;
164
165 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000166 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000167 if (!D) {
168 assert(0 && "Invalid declaration cursor");
169 return true; // abort.
170 }
171
172 // Ignore implicit declarations, unless it's an objc method because
173 // currently we should report implicit methods for properties when indexing.
174 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
175 return false;
176 }
177
178 // If we have a range of interest, and this cursor doesn't intersect with it,
179 // we're done.
180 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
181 SourceRange Range = getRawCursorExtent(Cursor);
182 if (Range.isInvalid() || CompareRegionOfInterest(Range))
183 return false;
184 }
185
186 switch (Visitor(Cursor, Parent, ClientData)) {
187 case CXChildVisit_Break:
188 return true;
189
190 case CXChildVisit_Continue:
191 return false;
192
193 case CXChildVisit_Recurse: {
194 bool ret = VisitChildren(Cursor);
195 if (PostChildrenVisitor)
196 if (PostChildrenVisitor(Cursor, ClientData))
197 return true;
198 return ret;
199 }
200 }
201
202 llvm_unreachable("Invalid CXChildVisitResult!");
203}
204
205static bool visitPreprocessedEntitiesInRange(SourceRange R,
206 PreprocessingRecord &PPRec,
207 CursorVisitor &Visitor) {
208 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
209 FileID FID;
210
211 if (!Visitor.shouldVisitIncludedEntities()) {
212 // If the begin/end of the range lie in the same FileID, do the optimization
213 // where we skip preprocessed entities that do not come from the same FileID.
214 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
215 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
216 FID = FileID();
217 }
218
219 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
220 Entities = PPRec.getPreprocessedEntitiesInRange(R);
221 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
222 PPRec, FID);
223}
224
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000225bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000226 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000227 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000228
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000229 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000230 SourceManager &SM = Unit->getSourceManager();
231
232 std::pair<FileID, unsigned>
233 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
234 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
235
236 if (End.first != Begin.first) {
237 // If the end does not reside in the same file, try to recover by
238 // picking the end of the file of begin location.
239 End.first = Begin.first;
240 End.second = SM.getFileIDSize(Begin.first);
241 }
242
243 assert(Begin.first == End.first);
244 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000246
247 FileID File = Begin.first;
248 unsigned Offset = Begin.second;
249 unsigned Length = End.second - Begin.second;
250
251 if (!VisitDeclsOnly && !VisitPreprocessorLast)
252 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000253 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000254
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000255 if (visitDeclsFromFileRegion(File, Offset, Length))
256 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000257
258 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000259 return visitPreprocessedEntitiesInRegion();
260
261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262}
263
264static bool isInLexicalContext(Decl *D, DeclContext *DC) {
265 if (!DC)
266 return false;
267
268 for (DeclContext *DeclDC = D->getLexicalDeclContext();
269 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
270 if (DeclDC == DC)
271 return true;
272 }
273 return false;
274}
275
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000277 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000278 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000279 SourceManager &SM = Unit->getSourceManager();
280 SourceRange Range = RegionOfInterest;
281
282 SmallVector<Decl *, 16> Decls;
283 Unit->findFileRegionDecls(File, Offset, Length, Decls);
284
285 // If we didn't find any file level decls for the file, try looking at the
286 // file that it was included from.
287 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
288 bool Invalid = false;
289 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
290 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000291 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000292
293 SourceLocation Outer;
294 if (SLEntry.isFile())
295 Outer = SLEntry.getFile().getIncludeLoc();
296 else
297 Outer = SLEntry.getExpansion().getExpansionLocStart();
298 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000300
301 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
302 Length = 0;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304 }
305
306 assert(!Decls.empty());
307
308 bool VisitedAtLeastOnce = false;
309 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000310 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
311 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000312 Decl *D = *DIt;
313 if (D->getSourceRange().isInvalid())
314 continue;
315
316 if (isInLexicalContext(D, CurDC))
317 continue;
318
319 CurDC = dyn_cast<DeclContext>(D);
320
321 if (TagDecl *TD = dyn_cast<TagDecl>(D))
322 if (!TD->isFreeStanding())
323 continue;
324
325 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
326 if (CompRes == RangeBefore)
327 continue;
328 if (CompRes == RangeAfter)
329 break;
330
331 assert(CompRes == RangeOverlap);
332 VisitedAtLeastOnce = true;
333
334 if (isa<ObjCContainerDecl>(D)) {
335 FileDI_current = &DIt;
336 FileDE_current = DE;
337 } else {
338 FileDI_current = 0;
339 }
340
341 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000342 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000343 }
344
345 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000346 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000347
348 // No Decls overlapped with the range. Move up the lexical context until there
349 // is a context that contains the range or we reach the translation unit
350 // level.
351 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
352 : (*(DIt-1))->getLexicalDeclContext();
353
354 while (DC && !DC->isTranslationUnit()) {
355 Decl *D = cast<Decl>(DC);
356 SourceRange CurDeclRange = D->getSourceRange();
357 if (CurDeclRange.isInvalid())
358 break;
359
360 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 DC = D->getLexicalDeclContext();
366 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367
368 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000369}
370
371bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
372 if (!AU->getPreprocessor().getPreprocessingRecord())
373 return false;
374
375 PreprocessingRecord &PPRec
376 = *AU->getPreprocessor().getPreprocessingRecord();
377 SourceManager &SM = AU->getSourceManager();
378
379 if (RegionOfInterest.isValid()) {
380 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
381 SourceLocation B = MappedRange.getBegin();
382 SourceLocation E = MappedRange.getEnd();
383
384 if (AU->isInPreambleFileID(B)) {
385 if (SM.isLoadedSourceLocation(E))
386 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
387 PPRec, *this);
388
389 // Beginning of range lies in the preamble but it also extends beyond
390 // it into the main file. Split the range into 2 parts, one covering
391 // the preamble and another covering the main file. This allows subsequent
392 // calls to visitPreprocessedEntitiesInRange to accept a source range that
393 // lies in the same FileID, allowing it to skip preprocessed entities that
394 // do not come from the same FileID.
395 bool breaked =
396 visitPreprocessedEntitiesInRange(
397 SourceRange(B, AU->getEndOfPreambleFileID()),
398 PPRec, *this);
399 if (breaked) return true;
400 return visitPreprocessedEntitiesInRange(
401 SourceRange(AU->getStartOfMainFileID(), E),
402 PPRec, *this);
403 }
404
405 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
406 }
407
408 bool OnlyLocalDecls
409 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
410
411 if (OnlyLocalDecls)
412 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
413 PPRec);
414
415 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
416}
417
418template<typename InputIterator>
419bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
420 InputIterator Last,
421 PreprocessingRecord &PPRec,
422 FileID FID) {
423 for (; First != Last; ++First) {
424 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
425 continue;
426
427 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000428 if (!PPE)
429 continue;
430
Guy Benyei11169dd2012-12-18 14:30:41 +0000431 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
432 if (Visit(MakeMacroExpansionCursor(ME, TU)))
433 return true;
434
435 continue;
436 }
437
438 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
439 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
440 return true;
441
442 continue;
443 }
444
445 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
446 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
447 return true;
448
449 continue;
450 }
451 }
452
453 return false;
454}
455
456/// \brief Visit the children of the given cursor.
457///
458/// \returns true if the visitation should be aborted, false if it
459/// should continue.
460bool CursorVisitor::VisitChildren(CXCursor Cursor) {
461 if (clang_isReference(Cursor.kind) &&
462 Cursor.kind != CXCursor_CXXBaseSpecifier) {
463 // By definition, references have no children.
464 return false;
465 }
466
467 // Set the Parent field to Cursor, then back to its old value once we're
468 // done.
469 SetParentRAII SetParent(Parent, StmtParent, Cursor);
470
471 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000472 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000473 if (!D)
474 return false;
475
476 return VisitAttributes(D) || Visit(D);
477 }
478
479 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000480 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000481 return Visit(S);
482
483 return false;
484 }
485
486 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000487 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 return Visit(E);
489
490 return false;
491 }
492
493 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000494 CXTranslationUnit TU = getCursorTU(Cursor);
495 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000496
497 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
498 for (unsigned I = 0; I != 2; ++I) {
499 if (VisitOrder[I]) {
500 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
501 RegionOfInterest.isInvalid()) {
502 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
503 TLEnd = CXXUnit->top_level_end();
504 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000505 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000506 return true;
507 }
508 } else if (VisitDeclContext(
509 CXXUnit->getASTContext().getTranslationUnitDecl()))
510 return true;
511 continue;
512 }
513
514 // Walk the preprocessing record.
515 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
516 visitPreprocessedEntitiesInRegion();
517 }
518
519 return false;
520 }
521
522 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000523 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000524 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
525 return Visit(BaseTSInfo->getTypeLoc());
526 }
527 }
528 }
529
530 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000531 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000532 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000533 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000534 return Visit(cxcursor::MakeCursorObjCClassRef(
535 ObjT->getInterface(),
536 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000537 }
538
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000539 // If pointing inside a macro definition, check if the token is an identifier
540 // that was ever defined as a macro. In such a case, create a "pseudo" macro
541 // expansion cursor for that token.
542 SourceLocation BeginLoc = RegionOfInterest.getBegin();
543 if (Cursor.kind == CXCursor_MacroDefinition &&
544 BeginLoc == RegionOfInterest.getEnd()) {
545 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 const MacroInfo *MI =
547 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000548 if (MacroDefinition *MacroDef =
549 checkForMacroInMacroDefinition(MI, Loc, TU))
550 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
551 }
552
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 // Nothing to visit at the moment.
554 return false;
555}
556
557bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
558 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
559 if (Visit(TSInfo->getTypeLoc()))
560 return true;
561
562 if (Stmt *Body = B->getBody())
563 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
564
565 return false;
566}
567
Ted Kremenek03325582013-02-21 01:29:01 +0000568Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 if (RegionOfInterest.isValid()) {
570 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
571 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000572 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000573
574 switch (CompareRegionOfInterest(Range)) {
575 case RangeBefore:
576 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000577 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000578
579 case RangeAfter:
580 // This declaration comes after the region of interest; we're done.
581 return false;
582
583 case RangeOverlap:
584 // This declaration overlaps the region of interest; visit it.
585 break;
586 }
587 }
588 return true;
589}
590
591bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
592 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
593
594 // FIXME: Eventually remove. This part of a hack to support proper
595 // iteration over all Decls contained lexically within an ObjC container.
596 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
597 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
598
599 for ( ; I != E; ++I) {
600 Decl *D = *I;
601 if (D->getLexicalDeclContext() != DC)
602 continue;
603 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
604
605 // Ignore synthesized ivars here, otherwise if we have something like:
606 // @synthesize prop = _prop;
607 // and '_prop' is not declared, we will encounter a '_prop' ivar before
608 // encountering the 'prop' synthesize declaration and we will think that
609 // we passed the region-of-interest.
610 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
611 if (ivarD->getSynthesize())
612 continue;
613 }
614
615 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
616 // declarations is a mismatch with the compiler semantics.
617 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
618 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
619 if (!ID->isThisDeclarationADefinition())
620 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
621
622 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
623 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
624 if (!PD->isThisDeclarationADefinition())
625 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
626 }
627
Ted Kremenek03325582013-02-21 01:29:01 +0000628 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000629 if (!V.hasValue())
630 continue;
631 if (!V.getValue())
632 return false;
633 if (Visit(Cursor, true))
634 return true;
635 }
636 return false;
637}
638
639bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
640 llvm_unreachable("Translation units are visited directly by Visit()");
641}
642
643bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
644 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
645 return Visit(TSInfo->getTypeLoc());
646
647 return false;
648}
649
650bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
651 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
652 return Visit(TSInfo->getTypeLoc());
653
654 return false;
655}
656
657bool CursorVisitor::VisitTagDecl(TagDecl *D) {
658 return VisitDeclContext(D);
659}
660
661bool CursorVisitor::VisitClassTemplateSpecializationDecl(
662 ClassTemplateSpecializationDecl *D) {
663 bool ShouldVisitBody = false;
664 switch (D->getSpecializationKind()) {
665 case TSK_Undeclared:
666 case TSK_ImplicitInstantiation:
667 // Nothing to visit
668 return false;
669
670 case TSK_ExplicitInstantiationDeclaration:
671 case TSK_ExplicitInstantiationDefinition:
672 break;
673
674 case TSK_ExplicitSpecialization:
675 ShouldVisitBody = true;
676 break;
677 }
678
679 // Visit the template arguments used in the specialization.
680 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
681 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000682 if (TemplateSpecializationTypeLoc TSTLoc =
683 TL.getAs<TemplateSpecializationTypeLoc>()) {
684 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
685 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000686 return true;
687 }
688 }
689
690 if (ShouldVisitBody && VisitCXXRecordDecl(D))
691 return true;
692
693 return false;
694}
695
696bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
697 ClassTemplatePartialSpecializationDecl *D) {
698 // FIXME: Visit the "outer" template parameter lists on the TagDecl
699 // before visiting these template parameters.
700 if (VisitTemplateParameters(D->getTemplateParameters()))
701 return true;
702
703 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000704 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
705 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
706 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000707 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
708 return true;
709
710 return VisitCXXRecordDecl(D);
711}
712
713bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
714 // Visit the default argument.
715 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
716 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
717 if (Visit(DefArg->getTypeLoc()))
718 return true;
719
720 return false;
721}
722
723bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
724 if (Expr *Init = D->getInitExpr())
725 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
726 return false;
727}
728
729bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000730 unsigned NumParamList = DD->getNumTemplateParameterLists();
731 for (unsigned i = 0; i < NumParamList; i++) {
732 TemplateParameterList* Params = DD->getTemplateParameterList(i);
733 if (VisitTemplateParameters(Params))
734 return true;
735 }
736
Guy Benyei11169dd2012-12-18 14:30:41 +0000737 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
738 if (Visit(TSInfo->getTypeLoc()))
739 return true;
740
741 // Visit the nested-name-specifier, if present.
742 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
743 if (VisitNestedNameSpecifierLoc(QualifierLoc))
744 return true;
745
746 return false;
747}
748
749/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000750static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
751 CXXCtorInitializer *const *Y) {
752 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000753}
754
755bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000756 unsigned NumParamList = ND->getNumTemplateParameterLists();
757 for (unsigned i = 0; i < NumParamList; i++) {
758 TemplateParameterList* Params = ND->getTemplateParameterList(i);
759 if (VisitTemplateParameters(Params))
760 return true;
761 }
762
Guy Benyei11169dd2012-12-18 14:30:41 +0000763 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
764 // Visit the function declaration's syntactic components in the order
765 // written. This requires a bit of work.
766 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000767 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000768
769 // If we have a function declared directly (without the use of a typedef),
770 // visit just the return type. Otherwise, just visit the function's type
771 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000772 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000773 (!FTL && Visit(TL)))
774 return true;
775
776 // Visit the nested-name-specifier, if present.
777 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
778 if (VisitNestedNameSpecifierLoc(QualifierLoc))
779 return true;
780
781 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000782 if (!isa<CXXDestructorDecl>(ND))
783 if (VisitDeclarationNameInfo(ND->getNameInfo()))
784 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000785
786 // FIXME: Visit explicitly-specified template arguments!
787
788 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000789 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000790 return true;
791
Bill Wendling44426052012-12-20 19:22:21 +0000792 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 }
794
795 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
796 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
797 // Find the initializers that were written in the source.
798 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
799 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
800 IEnd = Constructor->init_end();
801 I != IEnd; ++I) {
802 if (!(*I)->isWritten())
803 continue;
804
805 WrittenInits.push_back(*I);
806 }
807
808 // Sort the initializers in source order
809 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
810 &CompareCXXCtorInitializers);
811
812 // Visit the initializers in source order
813 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
814 CXXCtorInitializer *Init = WrittenInits[I];
815 if (Init->isAnyMemberInitializer()) {
816 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
817 Init->getMemberLocation(), TU)))
818 return true;
819 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
820 if (Visit(TInfo->getTypeLoc()))
821 return true;
822 }
823
824 // Visit the initializer value.
825 if (Expr *Initializer = Init->getInit())
826 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
827 return true;
828 }
829 }
830
831 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
832 return true;
833 }
834
835 return false;
836}
837
838bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
839 if (VisitDeclaratorDecl(D))
840 return true;
841
842 if (Expr *BitWidth = D->getBitWidth())
843 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
844
845 return false;
846}
847
848bool CursorVisitor::VisitVarDecl(VarDecl *D) {
849 if (VisitDeclaratorDecl(D))
850 return true;
851
852 if (Expr *Init = D->getInit())
853 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
854
855 return false;
856}
857
858bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
859 if (VisitDeclaratorDecl(D))
860 return true;
861
862 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
863 if (Expr *DefArg = D->getDefaultArgument())
864 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
870 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
871 // before visiting these template parameters.
872 if (VisitTemplateParameters(D->getTemplateParameters()))
873 return true;
874
875 return VisitFunctionDecl(D->getTemplatedDecl());
876}
877
878bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
879 // FIXME: Visit the "outer" template parameter lists on the TagDecl
880 // before visiting these template parameters.
881 if (VisitTemplateParameters(D->getTemplateParameters()))
882 return true;
883
884 return VisitCXXRecordDecl(D->getTemplatedDecl());
885}
886
887bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
892 VisitTemplateArgumentLoc(D->getDefaultArgument()))
893 return true;
894
895 return false;
896}
897
898bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000899 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000900 if (Visit(TSInfo->getTypeLoc()))
901 return true;
902
903 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
904 PEnd = ND->param_end();
905 P != PEnd; ++P) {
906 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
907 return true;
908 }
909
910 if (ND->isThisDeclarationADefinition() &&
911 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
912 return true;
913
914 return false;
915}
916
917template <typename DeclIt>
918static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
919 SourceManager &SM, SourceLocation EndLoc,
920 SmallVectorImpl<Decl *> &Decls) {
921 DeclIt next = *DI_current;
922 while (++next != DE_current) {
923 Decl *D_next = *next;
924 if (!D_next)
925 break;
926 SourceLocation L = D_next->getLocStart();
927 if (!L.isValid())
928 break;
929 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
930 *DI_current = next;
931 Decls.push_back(D_next);
932 continue;
933 }
934 break;
935 }
936}
937
938namespace {
939 struct ContainerDeclsSort {
940 SourceManager &SM;
941 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
942 bool operator()(Decl *A, Decl *B) {
943 SourceLocation L_A = A->getLocStart();
944 SourceLocation L_B = B->getLocStart();
945 assert(L_A.isValid() && L_B.isValid());
946 return SM.isBeforeInTranslationUnit(L_A, L_B);
947 }
948 };
949}
950
951bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
952 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
953 // an @implementation can lexically contain Decls that are not properly
954 // nested in the AST. When we identify such cases, we need to retrofit
955 // this nesting here.
956 if (!DI_current && !FileDI_current)
957 return VisitDeclContext(D);
958
959 // Scan the Decls that immediately come after the container
960 // in the current DeclContext. If any fall within the
961 // container's lexical region, stash them into a vector
962 // for later processing.
963 SmallVector<Decl *, 24> DeclsInContainer;
964 SourceLocation EndLoc = D->getSourceRange().getEnd();
965 SourceManager &SM = AU->getSourceManager();
966 if (EndLoc.isValid()) {
967 if (DI_current) {
968 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
969 DeclsInContainer);
970 } else {
971 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
972 DeclsInContainer);
973 }
974 }
975
976 // The common case.
977 if (DeclsInContainer.empty())
978 return VisitDeclContext(D);
979
980 // Get all the Decls in the DeclContext, and sort them with the
981 // additional ones we've collected. Then visit them.
982 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
983 I!=E; ++I) {
984 Decl *subDecl = *I;
985 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
986 subDecl->getLocStart().isInvalid())
987 continue;
988 DeclsInContainer.push_back(subDecl);
989 }
990
991 // Now sort the Decls so that they appear in lexical order.
992 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
993 ContainerDeclsSort(SM));
994
995 // Now visit the decls.
996 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
997 E = DeclsInContainer.end(); I != E; ++I) {
998 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +0000999 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001000 if (!V.hasValue())
1001 continue;
1002 if (!V.getValue())
1003 return false;
1004 if (Visit(Cursor, true))
1005 return true;
1006 }
1007 return false;
1008}
1009
1010bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1011 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1012 TU)))
1013 return true;
1014
1015 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1016 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1017 E = ND->protocol_end(); I != E; ++I, ++PL)
1018 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1019 return true;
1020
1021 return VisitObjCContainerDecl(ND);
1022}
1023
1024bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1025 if (!PID->isThisDeclarationADefinition())
1026 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1027
1028 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1029 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1030 E = PID->protocol_end(); I != E; ++I, ++PL)
1031 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1032 return true;
1033
1034 return VisitObjCContainerDecl(PID);
1035}
1036
1037bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1038 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1039 return true;
1040
1041 // FIXME: This implements a workaround with @property declarations also being
1042 // installed in the DeclContext for the @interface. Eventually this code
1043 // should be removed.
1044 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1045 if (!CDecl || !CDecl->IsClassExtension())
1046 return false;
1047
1048 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1049 if (!ID)
1050 return false;
1051
1052 IdentifierInfo *PropertyId = PD->getIdentifier();
1053 ObjCPropertyDecl *prevDecl =
1054 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1055
1056 if (!prevDecl)
1057 return false;
1058
1059 // Visit synthesized methods since they will be skipped when visiting
1060 // the @interface.
1061 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1062 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1063 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1064 return true;
1065
1066 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1067 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1068 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1069 return true;
1070
1071 return false;
1072}
1073
1074bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1075 if (!D->isThisDeclarationADefinition()) {
1076 // Forward declaration is treated like a reference.
1077 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1078 }
1079
1080 // Issue callbacks for super class.
1081 if (D->getSuperClass() &&
1082 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1083 D->getSuperClassLoc(),
1084 TU)))
1085 return true;
1086
1087 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1088 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1089 E = D->protocol_end(); I != E; ++I, ++PL)
1090 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1091 return true;
1092
1093 return VisitObjCContainerDecl(D);
1094}
1095
1096bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1101 // 'ID' could be null when dealing with invalid code.
1102 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1103 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1104 return true;
1105
1106 return VisitObjCImplDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1110#if 0
1111 // Issue callbacks for super class.
1112 // FIXME: No source location information!
1113 if (D->getSuperClass() &&
1114 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1115 D->getSuperClassLoc(),
1116 TU)))
1117 return true;
1118#endif
1119
1120 return VisitObjCImplDecl(D);
1121}
1122
1123bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1124 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1125 if (PD->isIvarNameSpecified())
1126 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1127
1128 return false;
1129}
1130
1131bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1132 return VisitDeclContext(D);
1133}
1134
1135bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1136 // Visit nested-name-specifier.
1137 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1138 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1139 return true;
1140
1141 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1142 D->getTargetNameLoc(), TU));
1143}
1144
1145bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150 }
1151
1152 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1153 return true;
1154
1155 return VisitDeclarationNameInfo(D->getNameInfo());
1156}
1157
1158bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1159 // Visit nested-name-specifier.
1160 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1161 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1162 return true;
1163
1164 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1165 D->getIdentLocation(), TU));
1166}
1167
1168bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173 }
1174
1175 return VisitDeclarationNameInfo(D->getNameInfo());
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1179 UnresolvedUsingTypenameDecl *D) {
1180 // Visit nested-name-specifier.
1181 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1182 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1183 return true;
1184
1185 return false;
1186}
1187
1188bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1189 switch (Name.getName().getNameKind()) {
1190 case clang::DeclarationName::Identifier:
1191 case clang::DeclarationName::CXXLiteralOperatorName:
1192 case clang::DeclarationName::CXXOperatorName:
1193 case clang::DeclarationName::CXXUsingDirective:
1194 return false;
1195
1196 case clang::DeclarationName::CXXConstructorName:
1197 case clang::DeclarationName::CXXDestructorName:
1198 case clang::DeclarationName::CXXConversionFunctionName:
1199 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1200 return Visit(TSInfo->getTypeLoc());
1201 return false;
1202
1203 case clang::DeclarationName::ObjCZeroArgSelector:
1204 case clang::DeclarationName::ObjCOneArgSelector:
1205 case clang::DeclarationName::ObjCMultiArgSelector:
1206 // FIXME: Per-identifier location info?
1207 return false;
1208 }
1209
1210 llvm_unreachable("Invalid DeclarationName::Kind!");
1211}
1212
1213bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1214 SourceRange Range) {
1215 // FIXME: This whole routine is a hack to work around the lack of proper
1216 // source information in nested-name-specifiers (PR5791). Since we do have
1217 // a beginning source location, we can visit the first component of the
1218 // nested-name-specifier, if it's a single-token component.
1219 if (!NNS)
1220 return false;
1221
1222 // Get the first component in the nested-name-specifier.
1223 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1224 NNS = Prefix;
1225
1226 switch (NNS->getKind()) {
1227 case NestedNameSpecifier::Namespace:
1228 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1229 TU));
1230
1231 case NestedNameSpecifier::NamespaceAlias:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1233 Range.getBegin(), TU));
1234
1235 case NestedNameSpecifier::TypeSpec: {
1236 // If the type has a form where we know that the beginning of the source
1237 // range matches up with a reference cursor. Visit the appropriate reference
1238 // cursor.
1239 const Type *T = NNS->getAsType();
1240 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1241 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1242 if (const TagType *Tag = dyn_cast<TagType>(T))
1243 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1244 if (const TemplateSpecializationType *TST
1245 = dyn_cast<TemplateSpecializationType>(T))
1246 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1247 break;
1248 }
1249
1250 case NestedNameSpecifier::TypeSpecWithTemplate:
1251 case NestedNameSpecifier::Global:
1252 case NestedNameSpecifier::Identifier:
1253 break;
1254 }
1255
1256 return false;
1257}
1258
1259bool
1260CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1261 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1262 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1263 Qualifiers.push_back(Qualifier);
1264
1265 while (!Qualifiers.empty()) {
1266 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1267 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1268 switch (NNS->getKind()) {
1269 case NestedNameSpecifier::Namespace:
1270 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1271 Q.getLocalBeginLoc(),
1272 TU)))
1273 return true;
1274
1275 break;
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::TypeSpec:
1286 case NestedNameSpecifier::TypeSpecWithTemplate:
1287 if (Visit(Q.getTypeLoc()))
1288 return true;
1289
1290 break;
1291
1292 case NestedNameSpecifier::Global:
1293 case NestedNameSpecifier::Identifier:
1294 break;
1295 }
1296 }
1297
1298 return false;
1299}
1300
1301bool CursorVisitor::VisitTemplateParameters(
1302 const TemplateParameterList *Params) {
1303 if (!Params)
1304 return false;
1305
1306 for (TemplateParameterList::const_iterator P = Params->begin(),
1307 PEnd = Params->end();
1308 P != PEnd; ++P) {
1309 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1310 return true;
1311 }
1312
1313 return false;
1314}
1315
1316bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1317 switch (Name.getKind()) {
1318 case TemplateName::Template:
1319 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1320
1321 case TemplateName::OverloadedTemplate:
1322 // Visit the overloaded template set.
1323 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1324 return true;
1325
1326 return false;
1327
1328 case TemplateName::DependentTemplate:
1329 // FIXME: Visit nested-name-specifier.
1330 return false;
1331
1332 case TemplateName::QualifiedTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return Visit(MakeCursorTemplateRef(
1335 Name.getAsQualifiedTemplateName()->getDecl(),
1336 Loc, TU));
1337
1338 case TemplateName::SubstTemplateTemplateParm:
1339 return Visit(MakeCursorTemplateRef(
1340 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1341 Loc, TU));
1342
1343 case TemplateName::SubstTemplateTemplateParmPack:
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1346 Loc, TU));
1347 }
1348
1349 llvm_unreachable("Invalid TemplateName::Kind!");
1350}
1351
1352bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1353 switch (TAL.getArgument().getKind()) {
1354 case TemplateArgument::Null:
1355 case TemplateArgument::Integral:
1356 case TemplateArgument::Pack:
1357 return false;
1358
1359 case TemplateArgument::Type:
1360 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1361 return Visit(TSInfo->getTypeLoc());
1362 return false;
1363
1364 case TemplateArgument::Declaration:
1365 if (Expr *E = TAL.getSourceDeclExpression())
1366 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1367 return false;
1368
1369 case TemplateArgument::NullPtr:
1370 if (Expr *E = TAL.getSourceNullPtrExpression())
1371 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1372 return false;
1373
1374 case TemplateArgument::Expression:
1375 if (Expr *E = TAL.getSourceExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::Template:
1380 case TemplateArgument::TemplateExpansion:
1381 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1382 return true;
1383
1384 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1385 TAL.getTemplateNameLoc());
1386 }
1387
1388 llvm_unreachable("Invalid TemplateArgument::Kind!");
1389}
1390
1391bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1392 return VisitDeclContext(D);
1393}
1394
1395bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1396 return Visit(TL.getUnqualifiedLoc());
1397}
1398
1399bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1400 ASTContext &Context = AU->getASTContext();
1401
1402 // Some builtin types (such as Objective-C's "id", "sel", and
1403 // "Class") have associated declarations. Create cursors for those.
1404 QualType VisitType;
1405 switch (TL.getTypePtr()->getKind()) {
1406
1407 case BuiltinType::Void:
1408 case BuiltinType::NullPtr:
1409 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001410 case BuiltinType::OCLImage1d:
1411 case BuiltinType::OCLImage1dArray:
1412 case BuiltinType::OCLImage1dBuffer:
1413 case BuiltinType::OCLImage2d:
1414 case BuiltinType::OCLImage2dArray:
1415 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001416 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001417 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001418#define BUILTIN_TYPE(Id, SingletonId)
1419#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1420#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#include "clang/AST/BuiltinTypes.def"
1424 break;
1425
1426 case BuiltinType::ObjCId:
1427 VisitType = Context.getObjCIdType();
1428 break;
1429
1430 case BuiltinType::ObjCClass:
1431 VisitType = Context.getObjCClassType();
1432 break;
1433
1434 case BuiltinType::ObjCSel:
1435 VisitType = Context.getObjCSelType();
1436 break;
1437 }
1438
1439 if (!VisitType.isNull()) {
1440 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1441 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1442 TU));
1443 }
1444
1445 return false;
1446}
1447
1448bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1450}
1451
1452bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1457 if (TL.isDefinition())
1458 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1459
1460 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1468 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1469 return true;
1470
1471 return false;
1472}
1473
1474bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1475 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1476 return true;
1477
1478 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1479 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1480 TU)))
1481 return true;
1482 }
1483
1484 return false;
1485}
1486
1487bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1492 return Visit(TL.getInnerLoc());
1493}
1494
1495bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1516 return Visit(TL.getModifiedLoc());
1517}
1518
1519bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1520 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001521 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001522 return true;
1523
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001524 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1525 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001526 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1527 return true;
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1533 if (Visit(TL.getElementLoc()))
1534 return true;
1535
1536 if (Expr *Size = TL.getSizeExpr())
1537 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1538
1539 return false;
1540}
1541
Reid Kleckner8a365022013-06-24 17:51:48 +00001542bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1543 return Visit(TL.getOriginalLoc());
1544}
1545
Reid Kleckner0503a872013-12-05 01:23:43 +00001546bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1547 return Visit(TL.getOriginalLoc());
1548}
1549
Guy Benyei11169dd2012-12-18 14:30:41 +00001550bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1551 TemplateSpecializationTypeLoc TL) {
1552 // Visit the template name.
1553 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1554 TL.getTemplateNameLoc()))
1555 return true;
1556
1557 // Visit the template arguments.
1558 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1559 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1560 return true;
1561
1562 return false;
1563}
1564
1565bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1566 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1567}
1568
1569bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1570 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1571 return Visit(TSInfo->getTypeLoc());
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1577 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1578 return Visit(TSInfo->getTypeLoc());
1579
1580 return false;
1581}
1582
1583bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1584 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1585 return true;
1586
1587 return false;
1588}
1589
1590bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1591 DependentTemplateSpecializationTypeLoc TL) {
1592 // Visit the nested-name-specifier, if there is one.
1593 if (TL.getQualifierLoc() &&
1594 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1595 return true;
1596
1597 // Visit the template arguments.
1598 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1599 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1600 return true;
1601
1602 return false;
1603}
1604
1605bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1606 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1607 return true;
1608
1609 return Visit(TL.getNamedTypeLoc());
1610}
1611
1612bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1613 return Visit(TL.getPatternLoc());
1614}
1615
1616bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1617 if (Expr *E = TL.getUnderlyingExpr())
1618 return Visit(MakeCXCursor(E, StmtParent, TU));
1619
1620 return false;
1621}
1622
1623bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1624 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1625}
1626
1627bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1628 return Visit(TL.getValueLoc());
1629}
1630
1631#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1632bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1633 return Visit##PARENT##Loc(TL); \
1634}
1635
1636DEFAULT_TYPELOC_IMPL(Complex, Type)
1637DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1638DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1642DEFAULT_TYPELOC_IMPL(Vector, Type)
1643DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1644DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1645DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1646DEFAULT_TYPELOC_IMPL(Record, TagType)
1647DEFAULT_TYPELOC_IMPL(Enum, TagType)
1648DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1649DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1650DEFAULT_TYPELOC_IMPL(Auto, Type)
1651
1652bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1653 // Visit the nested-name-specifier, if present.
1654 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1655 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1656 return true;
1657
1658 if (D->isCompleteDefinition()) {
1659 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1660 E = D->bases_end(); I != E; ++I) {
1661 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1662 return true;
1663 }
1664 }
1665
1666 return VisitTagDecl(D);
1667}
1668
1669bool CursorVisitor::VisitAttributes(Decl *D) {
1670 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1671 i != e; ++i)
1672 if (Visit(MakeCXCursor(*i, D, TU)))
1673 return true;
1674
1675 return false;
1676}
1677
1678//===----------------------------------------------------------------------===//
1679// Data-recursive visitor methods.
1680//===----------------------------------------------------------------------===//
1681
1682namespace {
1683#define DEF_JOB(NAME, DATA, KIND)\
1684class NAME : public VisitorJob {\
1685public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 NAME(const DATA *d, CXCursor parent) : \
1687 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001688 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001690};
1691
1692DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1693DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1694DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1695DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1696DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1697 ExplicitTemplateArgsVisitKind)
1698DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1699DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1700DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1701#undef DEF_JOB
1702
1703class DeclVisit : public VisitorJob {
1704public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001707 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == DeclVisitKind;
1710 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 bool isFirst() const { return data[1] ? true : false; }
1713};
1714class TypeLocVisit : public VisitorJob {
1715public:
1716 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1717 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1718 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1719
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == TypeLocVisitKind;
1722 }
1723
1724 TypeLoc get() const {
1725 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001726 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001727 }
1728};
1729
1730class LabelRefVisit : public VisitorJob {
1731public:
1732 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1733 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1734 labelLoc.getPtrEncoding()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1738 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const LabelDecl *get() const {
1740 return static_cast<const LabelDecl *>(data[0]);
1741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001742 SourceLocation getLoc() const {
1743 return SourceLocation::getFromPtrEncoding(data[1]); }
1744};
1745
1746class NestedNameSpecifierLocVisit : public VisitorJob {
1747public:
1748 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1750 Qualifier.getNestedNameSpecifier(),
1751 Qualifier.getOpaqueData()) { }
1752
1753 static bool classof(const VisitorJob *VJ) {
1754 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1755 }
1756
1757 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001758 return NestedNameSpecifierLoc(
1759 const_cast<NestedNameSpecifier *>(
1760 static_cast<const NestedNameSpecifier *>(data[0])),
1761 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 }
1763};
1764
1765class DeclarationNameInfoVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001768 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1771 }
1772 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 switch (S->getStmtClass()) {
1775 default:
1776 llvm_unreachable("Unhandled Stmt");
1777 case clang::Stmt::MSDependentExistsStmtClass:
1778 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1779 case Stmt::CXXDependentScopeMemberExprClass:
1780 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1781 case Stmt::DependentScopeDeclRefExprClass:
1782 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1783 }
1784 }
1785};
1786class MemberRefVisit : public VisitorJob {
1787public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1790 L.getPtrEncoding()) {}
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const FieldDecl *get() const {
1795 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 }
1797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1799 }
1800};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001802 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 VisitorWorkList &WL;
1804 CXCursor Parent;
1805public:
1806 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1807 : WL(wl), Parent(parent) {}
1808
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1810 void VisitBlockExpr(const BlockExpr *B);
1811 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1812 void VisitCompoundStmt(const CompoundStmt *S);
1813 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1814 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1815 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1816 void VisitCXXNewExpr(const CXXNewExpr *E);
1817 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1818 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1819 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1820 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1821 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1822 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1823 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1824 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1825 void VisitDeclRefExpr(const DeclRefExpr *D);
1826 void VisitDeclStmt(const DeclStmt *S);
1827 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1828 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1829 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1830 void VisitForStmt(const ForStmt *FS);
1831 void VisitGotoStmt(const GotoStmt *GS);
1832 void VisitIfStmt(const IfStmt *If);
1833 void VisitInitListExpr(const InitListExpr *IE);
1834 void VisitMemberExpr(const MemberExpr *M);
1835 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1836 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1837 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1838 void VisitOverloadExpr(const OverloadExpr *E);
1839 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1840 void VisitStmt(const Stmt *S);
1841 void VisitSwitchStmt(const SwitchStmt *S);
1842 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001852 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1853 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001854
Guy Benyei11169dd2012-12-18 14:30:41 +00001855private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1858 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1860 void AddStmt(const Stmt *S);
1861 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865};
1866} // end anonyous namespace
1867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 // 'S' should always be non-null, since it comes from the
1870 // statement we are visiting.
1871 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1872}
1873
1874void
1875EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1876 if (Qualifier)
1877 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1878}
1879
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 if (S)
1882 WL.push_back(StmtVisit(S, Parent));
1883}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (D)
1886 WL.push_back(DeclVisit(D, Parent, isFirst));
1887}
1888void EnqueueVisitor::
1889 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1890 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(MemberRefVisit(D, L, Parent));
1896}
1897void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1898 if (TI)
1899 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1900 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 AddStmt(*Child);
1905 }
1906 if (size == WL.size())
1907 return;
1908 // Now reverse the entries we just added. This will match the DFS
1909 // ordering performed by the worklist.
1910 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1911 std::reverse(I, E);
1912}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001913namespace {
1914class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1915 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001916 /// \brief Process clauses with list of variables.
1917 template <typename T>
1918 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919public:
1920 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1921#define OPENMP_CLAUSE(Name, Class) \
1922 void Visit##Class(const Class *C);
1923#include "clang/Basic/OpenMPKinds.def"
1924};
1925
1926void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001927
1928template<typename T>
1929void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1930 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1931 E = Node->varlist_end();
1932 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001933 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001934}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935
1936void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001937 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001939void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1940 const OMPFirstprivateClause *C) {
1941 VisitOMPClauseList(C);
1942}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001943void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001944 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946}
Alexey Bataev756c1962013-09-24 03:17:45 +00001947
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1949 unsigned size = WL.size();
1950 OMPClauseEnqueue Visitor(this);
1951 Visitor.Visit(S);
1952 if (size == WL.size())
1953 return;
1954 // Now reverse the entries we just added. This will match the DFS
1955 // ordering performed by the worklist.
1956 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1957 std::reverse(I, E);
1958}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001959void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1961}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 AddDecl(B->getBlockDecl());
1964}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 EnqueueChildren(E);
1967 AddTypeLoc(E->getTypeSourceInfo());
1968}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1970 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001971 E = S->body_rend(); I != E; ++I) {
1972 AddStmt(*I);
1973 }
1974}
1975void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 AddStmt(S->getSubStmt());
1978 AddDeclarationNameInfo(S);
1979 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1980 AddNestedNameSpecifierLoc(QualifierLoc);
1981}
1982
1983void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1986 AddDeclarationNameInfo(E);
1987 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1988 AddNestedNameSpecifierLoc(QualifierLoc);
1989 if (!E->isImplicitAccess())
1990 AddStmt(E->getBase());
1991}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 // Enqueue the initializer , if any.
1994 AddStmt(E->getInitializer());
1995 // Enqueue the array size, if any.
1996 AddStmt(E->getArraySize());
1997 // Enqueue the allocated type.
1998 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1999 // Enqueue the placement arguments.
2000 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2001 AddStmt(E->getPlacementArg(I-1));
2002}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002004 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2005 AddStmt(CE->getArg(I-1));
2006 AddStmt(CE->getCallee());
2007 AddStmt(CE->getArg(0));
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2010 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 // Visit the name of the type being destroyed.
2012 AddTypeLoc(E->getDestroyedTypeInfo());
2013 // Visit the scope type that looks disturbingly like the nested-name-specifier
2014 // but isn't.
2015 AddTypeLoc(E->getScopeTypeInfo());
2016 // Visit the nested-name-specifier.
2017 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2018 AddNestedNameSpecifierLoc(QualifierLoc);
2019 // Visit base expression.
2020 AddStmt(E->getBase());
2021}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2023 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 AddTypeLoc(E->getTypeSourceInfo());
2025}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2027 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 EnqueueChildren(E);
2029 AddTypeLoc(E->getTypeSourceInfo());
2030}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002031void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002032 EnqueueChildren(E);
2033 if (E->isTypeOperand())
2034 AddTypeLoc(E->getTypeOperandSourceInfo());
2035}
2036
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002037void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2038 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 EnqueueChildren(E);
2040 AddTypeLoc(E->getTypeSourceInfo());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 EnqueueChildren(E);
2044 if (E->isTypeOperand())
2045 AddTypeLoc(E->getTypeOperandSourceInfo());
2046}
2047
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 EnqueueChildren(S);
2050 AddDecl(S->getExceptionDecl());
2051}
2052
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 if (DR->hasExplicitTemplateArgs()) {
2055 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2056 }
2057 WL.push_back(DeclRefExprParts(DR, Parent));
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2060 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2062 AddDeclarationNameInfo(E);
2063 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 unsigned size = WL.size();
2067 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002069 D != DEnd; ++D) {
2070 AddDecl(*D, isFirst);
2071 isFirst = false;
2072 }
2073 if (size == WL.size())
2074 return;
2075 // Now reverse the entries we just added. This will match the DFS
2076 // ordering performed by the worklist.
2077 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2078 std::reverse(I, E);
2079}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 D = E->designators_rbegin(), DEnd = E->designators_rend();
2084 D != DEnd; ++D) {
2085 if (D->isFieldDesignator()) {
2086 if (FieldDecl *Field = D->getField())
2087 AddMemberRef(Field, D->getFieldLoc());
2088 continue;
2089 }
2090 if (D->isArrayDesignator()) {
2091 AddStmt(E->getArrayIndex(*D));
2092 continue;
2093 }
2094 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2095 AddStmt(E->getArrayRangeEnd(*D));
2096 AddStmt(E->getArrayRangeStart(*D));
2097 }
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 EnqueueChildren(E);
2101 AddTypeLoc(E->getTypeInfoAsWritten());
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 AddStmt(FS->getBody());
2105 AddStmt(FS->getInc());
2106 AddStmt(FS->getCond());
2107 AddDecl(FS->getConditionVariable());
2108 AddStmt(FS->getInit());
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 AddStmt(If->getElse());
2115 AddStmt(If->getThen());
2116 AddStmt(If->getCond());
2117 AddDecl(If->getConditionVariable());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 // We care about the syntactic form of the initializer list, only.
2121 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2122 IE = Syntactic;
2123 EnqueueChildren(IE);
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 WL.push_back(MemberExprParts(M, Parent));
2127
2128 // If the base of the member access expression is an implicit 'this', don't
2129 // visit it.
2130 // FIXME: If we ever want to show these implicit accesses, this will be
2131 // unfortunate. However, clang_getCursor() relies on this behavior.
2132 if (!M->isImplicitAccess())
2133 AddStmt(M->getBase());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 AddTypeLoc(E->getEncodedTypeSourceInfo());
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 EnqueueChildren(M);
2140 AddTypeLoc(M->getClassReceiverTypeInfo());
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 // Visit the components of the offsetof expression.
2144 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2145 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2146 const OffsetOfNode &Node = E->getComponent(I-1);
2147 switch (Node.getKind()) {
2148 case OffsetOfNode::Array:
2149 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2150 break;
2151 case OffsetOfNode::Field:
2152 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2153 break;
2154 case OffsetOfNode::Identifier:
2155 case OffsetOfNode::Base:
2156 continue;
2157 }
2158 }
2159 // Visit the type into which we're computing the offset.
2160 AddTypeLoc(E->getTypeSourceInfo());
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2164 WL.push_back(OverloadExprParts(E, Parent));
2165}
2166void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 EnqueueChildren(E);
2169 if (E->isArgumentType())
2170 AddTypeLoc(E->getArgumentTypeInfo());
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 EnqueueChildren(S);
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddStmt(S->getBody());
2177 AddStmt(S->getCond());
2178 AddDecl(S->getConditionVariable());
2179}
2180
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 AddStmt(W->getBody());
2183 AddStmt(W->getCond());
2184 AddDecl(W->getConditionVariable());
2185}
2186
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 for (unsigned I = E->getNumArgs(); I > 0; --I)
2189 AddTypeLoc(E->getArg(I-1));
2190}
2191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddTypeLoc(E->getQueriedTypeSourceInfo());
2194}
2195
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 EnqueueChildren(E);
2198}
2199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 VisitOverloadExpr(U);
2202 if (!U->isImplicitAccess())
2203 AddStmt(U->getBase());
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddStmt(E->getSubExpr());
2207 AddTypeLoc(E->getWrittenTypeInfo());
2208}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 WL.push_back(SizeOfPackExprParts(E, Parent));
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 // If the opaque value has a source expression, just transparently
2214 // visit that. This is useful for (e.g.) pseudo-object expressions.
2215 if (Expr *SourceExpr = E->getSourceExpr())
2216 return Visit(SourceExpr);
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(E->getBody());
2220 WL.push_back(LambdaExprParts(E, Parent));
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 // Treat the expression like its syntactic form.
2224 Visit(E->getSyntacticForm());
2225}
2226
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002227void EnqueueVisitor::VisitOMPExecutableDirective(
2228 const OMPExecutableDirective *D) {
2229 EnqueueChildren(D);
2230 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2231 E = D->clauses().end();
2232 I != E; ++I)
2233 EnqueueChildren(*I);
2234}
2235
2236void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2237 VisitOMPExecutableDirective(D);
2238}
2239
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2242}
2243
2244bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2245 if (RegionOfInterest.isValid()) {
2246 SourceRange Range = getRawCursorExtent(C);
2247 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2248 return false;
2249 }
2250 return true;
2251}
2252
2253bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2254 while (!WL.empty()) {
2255 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002256 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002257
2258 // Set the Parent field, then back to its old value once we're done.
2259 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2260
2261 switch (LI.getKind()) {
2262 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 if (!D)
2265 continue;
2266
2267 // For now, perform default visitation for Decls.
2268 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2269 cast<DeclVisit>(&LI)->isFirst())))
2270 return true;
2271
2272 continue;
2273 }
2274 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2275 const ASTTemplateArgumentListInfo *ArgList =
2276 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2277 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2278 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2279 Arg != ArgEnd; ++Arg) {
2280 if (VisitTemplateArgumentLoc(*Arg))
2281 return true;
2282 }
2283 continue;
2284 }
2285 case VisitorJob::TypeLocVisitKind: {
2286 // Perform default visitation for TypeLocs.
2287 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2288 return true;
2289 continue;
2290 }
2291 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 if (LabelStmt *stmt = LS->getStmt()) {
2294 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2295 TU))) {
2296 return true;
2297 }
2298 }
2299 continue;
2300 }
2301
2302 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2303 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2304 if (VisitNestedNameSpecifierLoc(V->get()))
2305 return true;
2306 continue;
2307 }
2308
2309 case VisitorJob::DeclarationNameInfoVisitKind: {
2310 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2311 ->get()))
2312 return true;
2313 continue;
2314 }
2315 case VisitorJob::MemberRefVisitKind: {
2316 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2317 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2318 return true;
2319 continue;
2320 }
2321 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 if (!S)
2324 continue;
2325
2326 // Update the current cursor.
2327 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2328 if (!IsInRegionOfInterest(Cursor))
2329 continue;
2330 switch (Visitor(Cursor, Parent, ClientData)) {
2331 case CXChildVisit_Break: return true;
2332 case CXChildVisit_Continue: break;
2333 case CXChildVisit_Recurse:
2334 if (PostChildrenVisitor)
2335 WL.push_back(PostChildrenVisit(0, Cursor));
2336 EnqueueWorkList(WL, S);
2337 break;
2338 }
2339 continue;
2340 }
2341 case VisitorJob::MemberExprPartsKind: {
2342 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002344
2345 // Visit the nested-name-specifier
2346 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2347 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2348 return true;
2349
2350 // Visit the declaration name.
2351 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2352 return true;
2353
2354 // Visit the explicitly-specified template arguments, if any.
2355 if (M->hasExplicitTemplateArgs()) {
2356 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2357 *ArgEnd = Arg + M->getNumTemplateArgs();
2358 Arg != ArgEnd; ++Arg) {
2359 if (VisitTemplateArgumentLoc(*Arg))
2360 return true;
2361 }
2362 }
2363 continue;
2364 }
2365 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002366 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002367 // Visit nested-name-specifier, if present.
2368 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2369 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2370 return true;
2371 // Visit declaration name.
2372 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2373 return true;
2374 continue;
2375 }
2376 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 // Visit the nested-name-specifier.
2379 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2380 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2381 return true;
2382 // Visit the declaration name.
2383 if (VisitDeclarationNameInfo(O->getNameInfo()))
2384 return true;
2385 // Visit the overloaded declaration reference.
2386 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2387 return true;
2388 continue;
2389 }
2390 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 NamedDecl *Pack = E->getPack();
2393 if (isa<TemplateTypeParmDecl>(Pack)) {
2394 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2395 E->getPackLoc(), TU)))
2396 return true;
2397
2398 continue;
2399 }
2400
2401 if (isa<TemplateTemplateParmDecl>(Pack)) {
2402 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2403 E->getPackLoc(), TU)))
2404 return true;
2405
2406 continue;
2407 }
2408
2409 // Non-type template parameter packs and function parameter packs are
2410 // treated like DeclRefExpr cursors.
2411 continue;
2412 }
2413
2414 case VisitorJob::LambdaExprPartsKind: {
2415 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2418 CEnd = E->explicit_capture_end();
2419 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002420 // FIXME: Lambda init-captures.
2421 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002423
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2425 C->getLocation(),
2426 TU)))
2427 return true;
2428 }
2429
2430 // Visit parameters and return type, if present.
2431 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2432 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2433 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2434 // Visit the whole type.
2435 if (Visit(TL))
2436 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002437 } else if (FunctionProtoTypeLoc Proto =
2438 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 if (E->hasExplicitParameters()) {
2440 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002441 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2442 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 return true;
2444 } else {
2445 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002446 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 return true;
2448 }
2449 }
2450 }
2451 break;
2452 }
2453
2454 case VisitorJob::PostChildrenVisitKind:
2455 if (PostChildrenVisitor(Parent, ClientData))
2456 return true;
2457 break;
2458 }
2459 }
2460 return false;
2461}
2462
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 VisitorWorkList *WL = 0;
2465 if (!WorkListFreeList.empty()) {
2466 WL = WorkListFreeList.back();
2467 WL->clear();
2468 WorkListFreeList.pop_back();
2469 }
2470 else {
2471 WL = new VisitorWorkList();
2472 WorkListCache.push_back(WL);
2473 }
2474 EnqueueWorkList(*WL, S);
2475 bool result = RunVisitorWorkList(*WL);
2476 WorkListFreeList.push_back(WL);
2477 return result;
2478}
2479
2480namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002481typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002482RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2483 const DeclarationNameInfo &NI,
2484 const SourceRange &QLoc,
2485 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2486 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2487 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2488 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2489
2490 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2491
2492 RefNamePieces Pieces;
2493
2494 if (WantQualifier && QLoc.isValid())
2495 Pieces.push_back(QLoc);
2496
2497 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2498 Pieces.push_back(NI.getLoc());
2499
2500 if (WantTemplateArgs && TemplateArgs)
2501 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2502 TemplateArgs->RAngleLoc));
2503
2504 if (Kind == DeclarationName::CXXOperatorName) {
2505 Pieces.push_back(SourceLocation::getFromRawEncoding(
2506 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2507 Pieces.push_back(SourceLocation::getFromRawEncoding(
2508 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2509 }
2510
2511 if (WantSinglePiece) {
2512 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2513 Pieces.clear();
2514 Pieces.push_back(R);
2515 }
2516
2517 return Pieces;
2518}
2519}
2520
2521//===----------------------------------------------------------------------===//
2522// Misc. API hooks.
2523//===----------------------------------------------------------------------===//
2524
2525static llvm::sys::Mutex EnableMultithreadingMutex;
2526static bool EnabledMultithreading;
2527
Chad Rosier05c71aa2013-03-27 18:28:23 +00002528static void fatal_error_handler(void *user_data, const std::string& reason,
2529 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002530 // Write the result out to stderr avoiding errs() because raw_ostreams can
2531 // call report_fatal_error.
2532 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2533 ::abort();
2534}
2535
2536extern "C" {
2537CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2538 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002539 // We use crash recovery to make some of our APIs more reliable, implicitly
2540 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002541 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2542 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002543
2544 // Enable support for multithreading in LLVM.
2545 {
2546 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2547 if (!EnabledMultithreading) {
2548 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2549 llvm::llvm_start_multithreaded();
2550 EnabledMultithreading = true;
2551 }
2552 }
2553
2554 CIndexer *CIdxr = new CIndexer();
2555 if (excludeDeclarationsFromPCH)
2556 CIdxr->setOnlyLocalDecls();
2557 if (displayDiagnostics)
2558 CIdxr->setDisplayDiagnostics();
2559
2560 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2561 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2562 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2563 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2564 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2565 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2566
2567 return CIdxr;
2568}
2569
2570void clang_disposeIndex(CXIndex CIdx) {
2571 if (CIdx)
2572 delete static_cast<CIndexer *>(CIdx);
2573}
2574
2575void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2576 if (CIdx)
2577 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2578}
2579
2580unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2581 if (CIdx)
2582 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2583 return 0;
2584}
2585
2586void clang_toggleCrashRecovery(unsigned isEnabled) {
2587 if (isEnabled)
2588 llvm::CrashRecoveryContext::Enable();
2589 else
2590 llvm::CrashRecoveryContext::Disable();
2591}
2592
2593CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2594 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002595 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 return 0;
2597
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002598 LOG_FUNC_SECTION {
2599 *Log << ast_filename;
2600 }
2601
Guy Benyei11169dd2012-12-18 14:30:41 +00002602 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2603 FileSystemOptions FileSystemOpts;
2604
2605 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2606 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002607 CXXIdx->getOnlyLocalDecls(), None,
2608 /*CaptureDiagnostics=*/true,
2609 /*AllowPCHWithCompilerErrors=*/true,
2610 /*UserFilesAreVolatile=*/true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002611 return MakeCXTranslationUnit(CXXIdx, TU);
2612}
2613
2614unsigned clang_defaultEditingTranslationUnitOptions() {
2615 return CXTranslationUnit_PrecompiledPreamble |
2616 CXTranslationUnit_CacheCompletionResults;
2617}
2618
2619CXTranslationUnit
2620clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2621 const char *source_filename,
2622 int num_command_line_args,
2623 const char * const *command_line_args,
2624 unsigned num_unsaved_files,
2625 struct CXUnsavedFile *unsaved_files) {
2626 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2627 return clang_parseTranslationUnit(CIdx, source_filename,
2628 command_line_args, num_command_line_args,
2629 unsaved_files, num_unsaved_files,
2630 Options);
2631}
2632
2633struct ParseTranslationUnitInfo {
2634 CXIndex CIdx;
2635 const char *source_filename;
2636 const char *const *command_line_args;
2637 int num_command_line_args;
2638 struct CXUnsavedFile *unsaved_files;
2639 unsigned num_unsaved_files;
2640 unsigned options;
2641 CXTranslationUnit result;
2642};
2643static void clang_parseTranslationUnit_Impl(void *UserData) {
2644 ParseTranslationUnitInfo *PTUI =
2645 static_cast<ParseTranslationUnitInfo*>(UserData);
2646 CXIndex CIdx = PTUI->CIdx;
2647 const char *source_filename = PTUI->source_filename;
2648 const char * const *command_line_args = PTUI->command_line_args;
2649 int num_command_line_args = PTUI->num_command_line_args;
2650 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2651 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2652 unsigned options = PTUI->options;
2653 PTUI->result = 0;
2654
2655 if (!CIdx)
2656 return;
2657
2658 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2659
2660 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2661 setThreadBackgroundPriority();
2662
2663 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2664 // FIXME: Add a flag for modules.
2665 TranslationUnitKind TUKind
2666 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002667 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 = options & CXTranslationUnit_CacheCompletionResults;
2669 bool IncludeBriefCommentsInCodeCompletion
2670 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2671 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2672 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2673
2674 // Configure the diagnostics.
2675 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002676 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002677
2678 // Recover resources if we crash before exiting this function.
2679 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2680 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2681 DiagCleanup(Diags.getPtr());
2682
2683 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2684 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2685
2686 // Recover resources if we crash before exiting this function.
2687 llvm::CrashRecoveryContextCleanupRegistrar<
2688 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2689
2690 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2691 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2692 const llvm::MemoryBuffer *Buffer
2693 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2694 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2695 Buffer));
2696 }
2697
2698 OwningPtr<std::vector<const char *> >
2699 Args(new std::vector<const char*>());
2700
2701 // Recover resources if we crash before exiting this method.
2702 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2703 ArgsCleanup(Args.get());
2704
2705 // Since the Clang C library is primarily used by batch tools dealing with
2706 // (often very broken) source code, where spell-checking can have a
2707 // significant negative impact on performance (particularly when
2708 // precompiled headers are involved), we disable it by default.
2709 // Only do this if we haven't found a spell-checking-related argument.
2710 bool FoundSpellCheckingArgument = false;
2711 for (int I = 0; I != num_command_line_args; ++I) {
2712 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2713 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2714 FoundSpellCheckingArgument = true;
2715 break;
2716 }
2717 }
2718 if (!FoundSpellCheckingArgument)
2719 Args->push_back("-fno-spell-checking");
2720
2721 Args->insert(Args->end(), command_line_args,
2722 command_line_args + num_command_line_args);
2723
2724 // The 'source_filename' argument is optional. If the caller does not
2725 // specify it then it is assumed that the source file is specified
2726 // in the actual argument list.
2727 // Put the source file after command_line_args otherwise if '-x' flag is
2728 // present it will be unused.
2729 if (source_filename)
2730 Args->push_back(source_filename);
2731
2732 // Do we need the detailed preprocessing record?
2733 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2734 Args->push_back("-Xclang");
2735 Args->push_back("-detailed-preprocessing-record");
2736 }
2737
2738 unsigned NumErrors = Diags->getClient()->getNumErrors();
2739 OwningPtr<ASTUnit> ErrUnit;
2740 OwningPtr<ASTUnit> Unit(
2741 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2742 /* vector::data() not portable */,
2743 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2744 Diags,
2745 CXXIdx->getClangResourcesPath(),
2746 CXXIdx->getOnlyLocalDecls(),
2747 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002748 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 /*RemappedFilesKeepOriginalName=*/true,
2750 PrecompilePreamble,
2751 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002752 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 IncludeBriefCommentsInCodeCompletion,
2754 /*AllowPCHWithCompilerErrors=*/true,
2755 SkipFunctionBodies,
2756 /*UserFilesAreVolatile=*/true,
2757 ForSerialization,
2758 &ErrUnit));
2759
2760 if (NumErrors != Diags->getClient()->getNumErrors()) {
2761 // Make sure to check that 'Unit' is non-NULL.
2762 if (CXXIdx->getDisplayDiagnostics())
2763 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2764 }
2765
2766 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2767}
2768CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2769 const char *source_filename,
2770 const char * const *command_line_args,
2771 int num_command_line_args,
2772 struct CXUnsavedFile *unsaved_files,
2773 unsigned num_unsaved_files,
2774 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002775 LOG_FUNC_SECTION {
2776 *Log << source_filename << ": ";
2777 for (int i = 0; i != num_command_line_args; ++i)
2778 *Log << command_line_args[i] << " ";
2779 }
2780
Guy Benyei11169dd2012-12-18 14:30:41 +00002781 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2782 num_command_line_args, unsaved_files,
2783 num_unsaved_files, options, 0 };
2784 llvm::CrashRecoveryContext CRC;
2785
2786 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2787 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2788 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2789 fprintf(stderr, " 'command_line_args' : [");
2790 for (int i = 0; i != num_command_line_args; ++i) {
2791 if (i)
2792 fprintf(stderr, ", ");
2793 fprintf(stderr, "'%s'", command_line_args[i]);
2794 }
2795 fprintf(stderr, "],\n");
2796 fprintf(stderr, " 'unsaved_files' : [");
2797 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2798 if (i)
2799 fprintf(stderr, ", ");
2800 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2801 unsaved_files[i].Length);
2802 }
2803 fprintf(stderr, "],\n");
2804 fprintf(stderr, " 'options' : %d,\n", options);
2805 fprintf(stderr, "}\n");
2806
2807 return 0;
2808 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2809 PrintLibclangResourceUsage(PTUI.result);
2810 }
2811
2812 return PTUI.result;
2813}
2814
2815unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2816 return CXSaveTranslationUnit_None;
2817}
2818
2819namespace {
2820
2821struct SaveTranslationUnitInfo {
2822 CXTranslationUnit TU;
2823 const char *FileName;
2824 unsigned options;
2825 CXSaveError result;
2826};
2827
2828}
2829
2830static void clang_saveTranslationUnit_Impl(void *UserData) {
2831 SaveTranslationUnitInfo *STUI =
2832 static_cast<SaveTranslationUnitInfo*>(UserData);
2833
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002834 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2836 setThreadBackgroundPriority();
2837
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002838 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002839 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2840}
2841
2842int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2843 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002844 LOG_FUNC_SECTION {
2845 *Log << TU << ' ' << FileName;
2846 }
2847
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002848 if (isNotUseableTU(TU)) {
2849 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002850 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002851 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002852
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002853 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002854 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2855 if (!CXXUnit->hasSema())
2856 return CXSaveError_InvalidTU;
2857
2858 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2859
2860 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2861 getenv("LIBCLANG_NOTHREADS")) {
2862 clang_saveTranslationUnit_Impl(&STUI);
2863
2864 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2865 PrintLibclangResourceUsage(TU);
2866
2867 return STUI.result;
2868 }
2869
2870 // We have an AST that has invalid nodes due to compiler errors.
2871 // Use a crash recovery thread for protection.
2872
2873 llvm::CrashRecoveryContext CRC;
2874
2875 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2876 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2877 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2878 fprintf(stderr, " 'options' : %d,\n", options);
2879 fprintf(stderr, "}\n");
2880
2881 return CXSaveError_Unknown;
2882
2883 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2884 PrintLibclangResourceUsage(TU);
2885 }
2886
2887 return STUI.result;
2888}
2889
2890void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2891 if (CTUnit) {
2892 // If the translation unit has been marked as unsafe to free, just discard
2893 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002894 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 return;
2896
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002897 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002898 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2900 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002901 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002902 delete CTUnit;
2903 }
2904}
2905
2906unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2907 return CXReparse_None;
2908}
2909
2910struct ReparseTranslationUnitInfo {
2911 CXTranslationUnit TU;
2912 unsigned num_unsaved_files;
2913 struct CXUnsavedFile *unsaved_files;
2914 unsigned options;
2915 int result;
2916};
2917
2918static void clang_reparseTranslationUnit_Impl(void *UserData) {
2919 ReparseTranslationUnitInfo *RTUI =
2920 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002921 RTUI->result = 1; // Error.
2922
Guy Benyei11169dd2012-12-18 14:30:41 +00002923 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002924 if (isNotUseableTU(TU)) {
2925 LOG_BAD_TU(TU);
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002926 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002927 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002928
2929 // Reset the associated diagnostics.
2930 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2931 TU->Diagnostics = 0;
2932
2933 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2934 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2935 unsigned options = RTUI->options;
2936 (void) options;
Guy Benyei11169dd2012-12-18 14:30:41 +00002937
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002938 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002939 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2940 setThreadBackgroundPriority();
2941
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002942 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002943 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2944
2945 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2946 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2947
2948 // Recover resources if we crash before exiting this function.
2949 llvm::CrashRecoveryContextCleanupRegistrar<
2950 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2951
2952 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2953 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2954 const llvm::MemoryBuffer *Buffer
2955 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2956 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2957 Buffer));
2958 }
2959
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002960 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002961 RTUI->result = 0;
2962}
2963
2964int clang_reparseTranslationUnit(CXTranslationUnit TU,
2965 unsigned num_unsaved_files,
2966 struct CXUnsavedFile *unsaved_files,
2967 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002968 LOG_FUNC_SECTION {
2969 *Log << TU;
2970 }
2971
Guy Benyei11169dd2012-12-18 14:30:41 +00002972 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2973 options, 0 };
2974
2975 if (getenv("LIBCLANG_NOTHREADS")) {
2976 clang_reparseTranslationUnit_Impl(&RTUI);
2977 return RTUI.result;
2978 }
2979
2980 llvm::CrashRecoveryContext CRC;
2981
2982 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2983 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002984 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002985 return 1;
2986 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2987 PrintLibclangResourceUsage(TU);
2988
2989 return RTUI.result;
2990}
2991
2992
2993CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002994 if (isNotUseableTU(CTUnit)) {
2995 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002996 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002997 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002998
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002999 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003000 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003001}
3002
3003CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003004 if (isNotUseableTU(TU)) {
3005 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003006 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003007 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003008
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3011}
3012
3013} // end: extern "C"
3014
3015//===----------------------------------------------------------------------===//
3016// CXFile Operations.
3017//===----------------------------------------------------------------------===//
3018
3019extern "C" {
3020CXString clang_getFileName(CXFile SFile) {
3021 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003022 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003023
3024 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003025 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003026}
3027
3028time_t clang_getFileTime(CXFile SFile) {
3029 if (!SFile)
3030 return 0;
3031
3032 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3033 return FEnt->getModificationTime();
3034}
3035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003036CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003037 if (isNotUseableTU(TU)) {
3038 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003039 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003040 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003041
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003042 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003043
3044 FileManager &FMgr = CXXUnit->getFileManager();
3045 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3046}
3047
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003048unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3049 CXFile file) {
3050 if (isNotUseableTU(TU)) {
3051 LOG_BAD_TU(TU);
3052 return 0;
3053 }
3054
3055 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 return 0;
3057
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003058 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003059 FileEntry *FEnt = static_cast<FileEntry *>(file);
3060 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3061 .isFileMultipleIncludeGuarded(FEnt);
3062}
3063
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003064int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3065 if (!file || !outID)
3066 return 1;
3067
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003068 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003069 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3070 outID->data[0] = ID.getDevice();
3071 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003072 outID->data[2] = FEnt->getModificationTime();
3073 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003074}
3075
Guy Benyei11169dd2012-12-18 14:30:41 +00003076} // end: extern "C"
3077
3078//===----------------------------------------------------------------------===//
3079// CXCursor Operations.
3080//===----------------------------------------------------------------------===//
3081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003082static const Decl *getDeclFromExpr(const Stmt *E) {
3083 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 return getDeclFromExpr(CE->getSubExpr());
3085
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003086 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003087 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003088 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003090 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003091 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003092 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 if (PRE->isExplicitProperty())
3094 return PRE->getExplicitProperty();
3095 // It could be messaging both getter and setter as in:
3096 // ++myobj.myprop;
3097 // in which case prefer to associate the setter since it is less obvious
3098 // from inspecting the source that the setter is going to get called.
3099 if (PRE->isMessagingSetter())
3100 return PRE->getImplicitPropertySetter();
3101 return PRE->getImplicitPropertyGetter();
3102 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003103 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003105 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 if (Expr *Src = OVE->getSourceExpr())
3107 return getDeclFromExpr(Src);
3108
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003109 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003111 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 if (!CE->isElidable())
3113 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003114 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 return OME->getMethodDecl();
3116
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003117 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003119 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3121 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003122 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3124 isa<ParmVarDecl>(SizeOfPack->getPack()))
3125 return SizeOfPack->getPack();
3126
3127 return 0;
3128}
3129
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003130static SourceLocation getLocationFromExpr(const Expr *E) {
3131 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 return getLocationFromExpr(CE->getSubExpr());
3133
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003134 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003136 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003138 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003140 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003142 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003144 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003145 return PropRef->getLocation();
3146
3147 return E->getLocStart();
3148}
3149
3150extern "C" {
3151
3152unsigned clang_visitChildren(CXCursor parent,
3153 CXCursorVisitor visitor,
3154 CXClientData client_data) {
3155 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3156 /*VisitPreprocessorLast=*/false);
3157 return CursorVis.VisitChildren(parent);
3158}
3159
3160#ifndef __has_feature
3161#define __has_feature(x) 0
3162#endif
3163#if __has_feature(blocks)
3164typedef enum CXChildVisitResult
3165 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3166
3167static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3168 CXClientData client_data) {
3169 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3170 return block(cursor, parent);
3171}
3172#else
3173// If we are compiled with a compiler that doesn't have native blocks support,
3174// define and call the block manually, so the
3175typedef struct _CXChildVisitResult
3176{
3177 void *isa;
3178 int flags;
3179 int reserved;
3180 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3181 CXCursor);
3182} *CXCursorVisitorBlock;
3183
3184static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3185 CXClientData client_data) {
3186 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3187 return block->invoke(block, cursor, parent);
3188}
3189#endif
3190
3191
3192unsigned clang_visitChildrenWithBlock(CXCursor parent,
3193 CXCursorVisitorBlock block) {
3194 return clang_visitChildren(parent, visitWithBlock, block);
3195}
3196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003199 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003200
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const ObjCPropertyImplDecl *PropImpl =
3204 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003206 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003207
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003208 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003210 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003211
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003212 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 }
3214
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003215 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003216 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003217
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003218 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3220 // and returns different names. NamedDecl returns the class name and
3221 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003222 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003223
3224 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003225 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003226
3227 SmallString<1024> S;
3228 llvm::raw_svector_ostream os(S);
3229 ND->printName(os);
3230
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003231 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003232}
3233
3234CXString clang_getCursorSpelling(CXCursor C) {
3235 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003236 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003237
3238 if (clang_isReference(C.kind)) {
3239 switch (C.kind) {
3240 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003241 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003242 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 }
3244 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003245 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003246 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 }
3248 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003249 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003251 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 }
3253 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003254 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003255 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 }
3257 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003258 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 assert(Type && "Missing type decl");
3260
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003261 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 getAsString());
3263 }
3264 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003265 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 assert(Template && "Missing template decl");
3267
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003268 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 }
3270
3271 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003272 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 assert(NS && "Missing namespace decl");
3274
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003275 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 }
3277
3278 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003279 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 assert(Field && "Missing member decl");
3281
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003282 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 }
3284
3285 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003286 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 assert(Label && "Missing label");
3288
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003289 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 }
3291
3292 case CXCursor_OverloadedDeclRef: {
3293 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3295 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003297 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003299 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003300 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 OverloadedTemplateStorage *Ovl
3302 = Storage.get<OverloadedTemplateStorage*>();
3303 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003304 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003305 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 }
3307
3308 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003309 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 assert(Var && "Missing variable decl");
3311
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003312 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 }
3314
3315 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003316 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 }
3318 }
3319
3320 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003321 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 if (D)
3323 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326
3327 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003328 const Stmt *S = getCursorStmt(C);
3329 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003330 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003332 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 }
3334
3335 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003336 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 ->getNameStart());
3338
3339 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003340 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 ->getNameStart());
3342
3343 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003344 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003345
3346 if (clang_isDeclaration(C.kind))
3347 return getDeclSpelling(getCursorDecl(C));
3348
3349 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003350 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003351 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 }
3353
3354 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003355 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
3358
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003359 if (C.kind == CXCursor_PackedAttr) {
3360 return cxstring::createRef("packed");
3361 }
3362
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003363 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003364}
3365
3366CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3367 unsigned pieceIndex,
3368 unsigned options) {
3369 if (clang_Cursor_isNull(C))
3370 return clang_getNullRange();
3371
3372 ASTContext &Ctx = getCursorContext(C);
3373
3374 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003375 const Stmt *S = getCursorStmt(C);
3376 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 if (pieceIndex > 0)
3378 return clang_getNullRange();
3379 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3380 }
3381
3382 return clang_getNullRange();
3383 }
3384
3385 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003386 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3388 if (pieceIndex >= ME->getNumSelectorLocs())
3389 return clang_getNullRange();
3390 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3391 }
3392 }
3393
3394 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3395 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3398 if (pieceIndex >= MD->getNumSelectorLocs())
3399 return clang_getNullRange();
3400 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3401 }
3402 }
3403
3404 if (C.kind == CXCursor_ObjCCategoryDecl ||
3405 C.kind == CXCursor_ObjCCategoryImplDecl) {
3406 if (pieceIndex > 0)
3407 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003408 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3410 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3413 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3414 }
3415
3416 if (C.kind == CXCursor_ModuleImportDecl) {
3417 if (pieceIndex > 0)
3418 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 if (const ImportDecl *ImportD =
3420 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3422 if (!Locs.empty())
3423 return cxloc::translateSourceRange(Ctx,
3424 SourceRange(Locs.front(), Locs.back()));
3425 }
3426 return clang_getNullRange();
3427 }
3428
3429 // FIXME: A CXCursor_InclusionDirective should give the location of the
3430 // filename, but we don't keep track of this.
3431
3432 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3433 // but we don't keep track of this.
3434
3435 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3436 // but we don't keep track of this.
3437
3438 // Default handling, give the location of the cursor.
3439
3440 if (pieceIndex > 0)
3441 return clang_getNullRange();
3442
3443 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3444 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3445 return cxloc::translateSourceRange(Ctx, Loc);
3446}
3447
3448CXString clang_getCursorDisplayName(CXCursor C) {
3449 if (!clang_isDeclaration(C.kind))
3450 return clang_getCursorSpelling(C);
3451
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003452 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003454 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003455
3456 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003457 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 D = FunTmpl->getTemplatedDecl();
3459
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003460 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 SmallString<64> Str;
3462 llvm::raw_svector_ostream OS(Str);
3463 OS << *Function;
3464 if (Function->getPrimaryTemplate())
3465 OS << "<>";
3466 OS << "(";
3467 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3468 if (I)
3469 OS << ", ";
3470 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3471 }
3472
3473 if (Function->isVariadic()) {
3474 if (Function->getNumParams())
3475 OS << ", ";
3476 OS << "...";
3477 }
3478 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003479 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 }
3481
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 SmallString<64> Str;
3484 llvm::raw_svector_ostream OS(Str);
3485 OS << *ClassTemplate;
3486 OS << "<";
3487 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3488 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3489 if (I)
3490 OS << ", ";
3491
3492 NamedDecl *Param = Params->getParam(I);
3493 if (Param->getIdentifier()) {
3494 OS << Param->getIdentifier()->getName();
3495 continue;
3496 }
3497
3498 // There is no parameter name, which makes this tricky. Try to come up
3499 // with something useful that isn't too long.
3500 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3501 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3502 else if (NonTypeTemplateParmDecl *NTTP
3503 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3504 OS << NTTP->getType().getAsString(Policy);
3505 else
3506 OS << "template<...> class";
3507 }
3508
3509 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003510 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 }
3512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3515 // If the type was explicitly written, use that.
3516 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003517 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003518
Benjamin Kramer9170e912013-02-22 15:46:01 +00003519 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 llvm::raw_svector_ostream OS(Str);
3521 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003522 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 ClassSpec->getTemplateArgs().data(),
3524 ClassSpec->getTemplateArgs().size(),
3525 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003526 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528
3529 return clang_getCursorSpelling(C);
3530}
3531
3532CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3533 switch (Kind) {
3534 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003535 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003537 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003539 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003541 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003543 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003545 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003547 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003549 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003551 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003565 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003567 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003569 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003571 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003573 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003575 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003579 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003581 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003583 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003585 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003587 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003589 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003593 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003595 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003597 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003599 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003603 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003605 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003609 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003662 case CXCursor_ObjCSelfExpr:
3663 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003780 case CXCursor_PackedAttr:
3781 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003830 case CXCursor_OMPParallelDirective:
3831 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 }
3833
3834 llvm_unreachable("Unhandled CXCursorKind");
3835}
3836
3837struct GetCursorData {
3838 SourceLocation TokenBeginLoc;
3839 bool PointsAtMacroArgExpansion;
3840 bool VisitedObjCPropertyImplDecl;
3841 SourceLocation VisitedDeclaratorDeclStartLoc;
3842 CXCursor &BestCursor;
3843
3844 GetCursorData(SourceManager &SM,
3845 SourceLocation tokenBegin, CXCursor &outputCursor)
3846 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3847 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3848 VisitedObjCPropertyImplDecl = false;
3849 }
3850};
3851
3852static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3853 CXCursor parent,
3854 CXClientData client_data) {
3855 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3856 CXCursor *BestCursor = &Data->BestCursor;
3857
3858 // If we point inside a macro argument we should provide info of what the
3859 // token is so use the actual cursor, don't replace it with a macro expansion
3860 // cursor.
3861 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3862 return CXChildVisit_Recurse;
3863
3864 if (clang_isDeclaration(cursor.kind)) {
3865 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003866 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3868 if (MD->isImplicit())
3869 return CXChildVisit_Break;
3870
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003871 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3873 // Check that when we have multiple @class references in the same line,
3874 // that later ones do not override the previous ones.
3875 // If we have:
3876 // @class Foo, Bar;
3877 // source ranges for both start at '@', so 'Bar' will end up overriding
3878 // 'Foo' even though the cursor location was at 'Foo'.
3879 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3880 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003881 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3883 if (PrevID != ID &&
3884 !PrevID->isThisDeclarationADefinition() &&
3885 !ID->isThisDeclarationADefinition())
3886 return CXChildVisit_Break;
3887 }
3888
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003889 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3891 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3892 // Check that when we have multiple declarators in the same line,
3893 // that later ones do not override the previous ones.
3894 // If we have:
3895 // int Foo, Bar;
3896 // source ranges for both start at 'int', so 'Bar' will end up overriding
3897 // 'Foo' even though the cursor location was at 'Foo'.
3898 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3899 return CXChildVisit_Break;
3900 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3901
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3904 (void)PropImp;
3905 // Check that when we have multiple @synthesize in the same line,
3906 // that later ones do not override the previous ones.
3907 // If we have:
3908 // @synthesize Foo, Bar;
3909 // source ranges for both start at '@', so 'Bar' will end up overriding
3910 // 'Foo' even though the cursor location was at 'Foo'.
3911 if (Data->VisitedObjCPropertyImplDecl)
3912 return CXChildVisit_Break;
3913 Data->VisitedObjCPropertyImplDecl = true;
3914 }
3915 }
3916
3917 if (clang_isExpression(cursor.kind) &&
3918 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 // Avoid having the cursor of an expression replace the declaration cursor
3921 // when the expression source range overlaps the declaration range.
3922 // This can happen for C++ constructor expressions whose range generally
3923 // include the variable declaration, e.g.:
3924 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3925 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3926 D->getLocation() == Data->TokenBeginLoc)
3927 return CXChildVisit_Break;
3928 }
3929 }
3930
3931 // If our current best cursor is the construction of a temporary object,
3932 // don't replace that cursor with a type reference, because we want
3933 // clang_getCursor() to point at the constructor.
3934 if (clang_isExpression(BestCursor->kind) &&
3935 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3936 cursor.kind == CXCursor_TypeRef) {
3937 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3938 // as having the actual point on the type reference.
3939 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3940 return CXChildVisit_Recurse;
3941 }
3942
3943 *BestCursor = cursor;
3944 return CXChildVisit_Recurse;
3945}
3946
3947CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003948 if (isNotUseableTU(TU)) {
3949 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003951 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003952
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003953 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3955
3956 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3957 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3958
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003959 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 CXFile SearchFile;
3961 unsigned SearchLine, SearchColumn;
3962 CXFile ResultFile;
3963 unsigned ResultLine, ResultColumn;
3964 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3965 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3966 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3967
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003968 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3969 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 &ResultColumn, 0);
3971 SearchFileName = clang_getFileName(SearchFile);
3972 ResultFileName = clang_getFileName(ResultFile);
3973 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3974 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003975 *Log << llvm::format("(%s:%d:%d) = %s",
3976 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3977 clang_getCString(KindSpelling))
3978 << llvm::format("(%s:%d:%d):%s%s",
3979 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3980 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 clang_disposeString(SearchFileName);
3982 clang_disposeString(ResultFileName);
3983 clang_disposeString(KindSpelling);
3984 clang_disposeString(USR);
3985
3986 CXCursor Definition = clang_getCursorDefinition(Result);
3987 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3988 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3989 CXString DefinitionKindSpelling
3990 = clang_getCursorKindSpelling(Definition.kind);
3991 CXFile DefinitionFile;
3992 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003993 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 &DefinitionLine, &DefinitionColumn, 0);
3995 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003996 *Log << llvm::format(" -> %s(%s:%d:%d)",
3997 clang_getCString(DefinitionKindSpelling),
3998 clang_getCString(DefinitionFileName),
3999 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 clang_disposeString(DefinitionFileName);
4001 clang_disposeString(DefinitionKindSpelling);
4002 }
4003 }
4004
4005 return Result;
4006}
4007
4008CXCursor clang_getNullCursor(void) {
4009 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4010}
4011
4012unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004013 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4014 // can't set consistently. For example, when visiting a DeclStmt we will set
4015 // it but we don't set it on the result of clang_getCursorDefinition for
4016 // a reference of the same declaration.
4017 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4018 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4019 // to provide that kind of info.
4020 if (clang_isDeclaration(X.kind))
4021 X.data[1] = 0;
4022 if (clang_isDeclaration(Y.kind))
4023 Y.data[1] = 0;
4024
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 return X == Y;
4026}
4027
4028unsigned clang_hashCursor(CXCursor C) {
4029 unsigned Index = 0;
4030 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4031 Index = 1;
4032
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004033 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 std::make_pair(C.kind, C.data[Index]));
4035}
4036
4037unsigned clang_isInvalid(enum CXCursorKind K) {
4038 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4039}
4040
4041unsigned clang_isDeclaration(enum CXCursorKind K) {
4042 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4043 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4044}
4045
4046unsigned clang_isReference(enum CXCursorKind K) {
4047 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4048}
4049
4050unsigned clang_isExpression(enum CXCursorKind K) {
4051 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4052}
4053
4054unsigned clang_isStatement(enum CXCursorKind K) {
4055 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4056}
4057
4058unsigned clang_isAttribute(enum CXCursorKind K) {
4059 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4060}
4061
4062unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4063 return K == CXCursor_TranslationUnit;
4064}
4065
4066unsigned clang_isPreprocessing(enum CXCursorKind K) {
4067 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4068}
4069
4070unsigned clang_isUnexposed(enum CXCursorKind K) {
4071 switch (K) {
4072 case CXCursor_UnexposedDecl:
4073 case CXCursor_UnexposedExpr:
4074 case CXCursor_UnexposedStmt:
4075 case CXCursor_UnexposedAttr:
4076 return true;
4077 default:
4078 return false;
4079 }
4080}
4081
4082CXCursorKind clang_getCursorKind(CXCursor C) {
4083 return C.kind;
4084}
4085
4086CXSourceLocation clang_getCursorLocation(CXCursor C) {
4087 if (clang_isReference(C.kind)) {
4088 switch (C.kind) {
4089 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004090 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 = getCursorObjCSuperClassRef(C);
4092 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4093 }
4094
4095 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004096 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 = getCursorObjCProtocolRef(C);
4098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 = getCursorObjCClassRef(C);
4104 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4105 }
4106
4107 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004108 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4110 }
4111
4112 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 std::pair<const TemplateDecl *, SourceLocation> P =
4114 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4116 }
4117
4118 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004119 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4121 }
4122
4123 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004124 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4126 }
4127
4128 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004129 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4131 }
4132
4133 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004134 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 if (!BaseSpec)
4136 return clang_getNullLocation();
4137
4138 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4139 return cxloc::translateSourceLocation(getCursorContext(C),
4140 TSInfo->getTypeLoc().getBeginLoc());
4141
4142 return cxloc::translateSourceLocation(getCursorContext(C),
4143 BaseSpec->getLocStart());
4144 }
4145
4146 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004147 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4149 }
4150
4151 case CXCursor_OverloadedDeclRef:
4152 return cxloc::translateSourceLocation(getCursorContext(C),
4153 getCursorOverloadedDeclRef(C).second);
4154
4155 default:
4156 // FIXME: Need a way to enumerate all non-reference cases.
4157 llvm_unreachable("Missed a reference kind");
4158 }
4159 }
4160
4161 if (clang_isExpression(C.kind))
4162 return cxloc::translateSourceLocation(getCursorContext(C),
4163 getLocationFromExpr(getCursorExpr(C)));
4164
4165 if (clang_isStatement(C.kind))
4166 return cxloc::translateSourceLocation(getCursorContext(C),
4167 getCursorStmt(C)->getLocStart());
4168
4169 if (C.kind == CXCursor_PreprocessingDirective) {
4170 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
4174 if (C.kind == CXCursor_MacroExpansion) {
4175 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004176 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 return cxloc::translateSourceLocation(getCursorContext(C), L);
4178 }
4179
4180 if (C.kind == CXCursor_MacroDefinition) {
4181 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4182 return cxloc::translateSourceLocation(getCursorContext(C), L);
4183 }
4184
4185 if (C.kind == CXCursor_InclusionDirective) {
4186 SourceLocation L
4187 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4188 return cxloc::translateSourceLocation(getCursorContext(C), L);
4189 }
4190
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004191 if (clang_isAttribute(C.kind)) {
4192 SourceLocation L
4193 = cxcursor::getCursorAttr(C)->getLocation();
4194 return cxloc::translateSourceLocation(getCursorContext(C), L);
4195 }
4196
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 if (!clang_isDeclaration(C.kind))
4198 return clang_getNullLocation();
4199
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004200 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 if (!D)
4202 return clang_getNullLocation();
4203
4204 SourceLocation Loc = D->getLocation();
4205 // FIXME: Multiple variables declared in a single declaration
4206 // currently lack the information needed to correctly determine their
4207 // ranges when accounting for the type-specifier. We use context
4208 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4209 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004210 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 if (!cxcursor::isFirstInDeclGroup(C))
4212 Loc = VD->getLocation();
4213 }
4214
4215 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004216 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 Loc = MD->getSelectorStartLoc();
4218
4219 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4220}
4221
4222} // end extern "C"
4223
4224CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4225 assert(TU);
4226
4227 // Guard against an invalid SourceLocation, or we may assert in one
4228 // of the following calls.
4229 if (SLoc.isInvalid())
4230 return clang_getNullCursor();
4231
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004232 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004233
4234 // Translate the given source location to make it point at the beginning of
4235 // the token under the cursor.
4236 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4237 CXXUnit->getASTContext().getLangOpts());
4238
4239 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4240 if (SLoc.isValid()) {
4241 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4242 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4243 /*VisitPreprocessorLast=*/true,
4244 /*VisitIncludedEntities=*/false,
4245 SourceLocation(SLoc));
4246 CursorVis.visitFileRegion();
4247 }
4248
4249 return Result;
4250}
4251
4252static SourceRange getRawCursorExtent(CXCursor C) {
4253 if (clang_isReference(C.kind)) {
4254 switch (C.kind) {
4255 case CXCursor_ObjCSuperClassRef:
4256 return getCursorObjCSuperClassRef(C).second;
4257
4258 case CXCursor_ObjCProtocolRef:
4259 return getCursorObjCProtocolRef(C).second;
4260
4261 case CXCursor_ObjCClassRef:
4262 return getCursorObjCClassRef(C).second;
4263
4264 case CXCursor_TypeRef:
4265 return getCursorTypeRef(C).second;
4266
4267 case CXCursor_TemplateRef:
4268 return getCursorTemplateRef(C).second;
4269
4270 case CXCursor_NamespaceRef:
4271 return getCursorNamespaceRef(C).second;
4272
4273 case CXCursor_MemberRef:
4274 return getCursorMemberRef(C).second;
4275
4276 case CXCursor_CXXBaseSpecifier:
4277 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4278
4279 case CXCursor_LabelRef:
4280 return getCursorLabelRef(C).second;
4281
4282 case CXCursor_OverloadedDeclRef:
4283 return getCursorOverloadedDeclRef(C).second;
4284
4285 case CXCursor_VariableRef:
4286 return getCursorVariableRef(C).second;
4287
4288 default:
4289 // FIXME: Need a way to enumerate all non-reference cases.
4290 llvm_unreachable("Missed a reference kind");
4291 }
4292 }
4293
4294 if (clang_isExpression(C.kind))
4295 return getCursorExpr(C)->getSourceRange();
4296
4297 if (clang_isStatement(C.kind))
4298 return getCursorStmt(C)->getSourceRange();
4299
4300 if (clang_isAttribute(C.kind))
4301 return getCursorAttr(C)->getRange();
4302
4303 if (C.kind == CXCursor_PreprocessingDirective)
4304 return cxcursor::getCursorPreprocessingDirective(C);
4305
4306 if (C.kind == CXCursor_MacroExpansion) {
4307 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004308 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 return TU->mapRangeFromPreamble(Range);
4310 }
4311
4312 if (C.kind == CXCursor_MacroDefinition) {
4313 ASTUnit *TU = getCursorASTUnit(C);
4314 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4315 return TU->mapRangeFromPreamble(Range);
4316 }
4317
4318 if (C.kind == CXCursor_InclusionDirective) {
4319 ASTUnit *TU = getCursorASTUnit(C);
4320 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4321 return TU->mapRangeFromPreamble(Range);
4322 }
4323
4324 if (C.kind == CXCursor_TranslationUnit) {
4325 ASTUnit *TU = getCursorASTUnit(C);
4326 FileID MainID = TU->getSourceManager().getMainFileID();
4327 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4328 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4329 return SourceRange(Start, End);
4330 }
4331
4332 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004333 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 if (!D)
4335 return SourceRange();
4336
4337 SourceRange R = D->getSourceRange();
4338 // FIXME: Multiple variables declared in a single declaration
4339 // currently lack the information needed to correctly determine their
4340 // ranges when accounting for the type-specifier. We use context
4341 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4342 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004343 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 if (!cxcursor::isFirstInDeclGroup(C))
4345 R.setBegin(VD->getLocation());
4346 }
4347 return R;
4348 }
4349 return SourceRange();
4350}
4351
4352/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4353/// the decl-specifier-seq for declarations.
4354static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4355 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004356 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 if (!D)
4358 return SourceRange();
4359
4360 SourceRange R = D->getSourceRange();
4361
4362 // Adjust the start of the location for declarations preceded by
4363 // declaration specifiers.
4364 SourceLocation StartLoc;
4365 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4366 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4367 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004368 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4370 StartLoc = TI->getTypeLoc().getLocStart();
4371 }
4372
4373 if (StartLoc.isValid() && R.getBegin().isValid() &&
4374 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4375 R.setBegin(StartLoc);
4376
4377 // FIXME: Multiple variables declared in a single declaration
4378 // currently lack the information needed to correctly determine their
4379 // ranges when accounting for the type-specifier. We use context
4380 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4381 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004382 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 if (!cxcursor::isFirstInDeclGroup(C))
4384 R.setBegin(VD->getLocation());
4385 }
4386
4387 return R;
4388 }
4389
4390 return getRawCursorExtent(C);
4391}
4392
4393extern "C" {
4394
4395CXSourceRange clang_getCursorExtent(CXCursor C) {
4396 SourceRange R = getRawCursorExtent(C);
4397 if (R.isInvalid())
4398 return clang_getNullRange();
4399
4400 return cxloc::translateSourceRange(getCursorContext(C), R);
4401}
4402
4403CXCursor clang_getCursorReferenced(CXCursor C) {
4404 if (clang_isInvalid(C.kind))
4405 return clang_getNullCursor();
4406
4407 CXTranslationUnit tu = getCursorTU(C);
4408 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004409 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 if (!D)
4411 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004414 if (const ObjCPropertyImplDecl *PropImpl =
4415 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4417 return MakeCXCursor(Property, tu);
4418
4419 return C;
4420 }
4421
4422 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 const Expr *E = getCursorExpr(C);
4424 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 if (D) {
4426 CXCursor declCursor = MakeCXCursor(D, tu);
4427 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4428 declCursor);
4429 return declCursor;
4430 }
4431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004432 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 return MakeCursorOverloadedDeclRef(Ovl, tu);
4434
4435 return clang_getNullCursor();
4436 }
4437
4438 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004439 const Stmt *S = getCursorStmt(C);
4440 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 if (LabelDecl *label = Goto->getLabel())
4442 if (LabelStmt *labelS = label->getStmt())
4443 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4444
4445 return clang_getNullCursor();
4446 }
4447
4448 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004449 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 return MakeMacroDefinitionCursor(Def, tu);
4451 }
4452
4453 if (!clang_isReference(C.kind))
4454 return clang_getNullCursor();
4455
4456 switch (C.kind) {
4457 case CXCursor_ObjCSuperClassRef:
4458 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4459
4460 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004461 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4462 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 return MakeCXCursor(Def, tu);
4464
4465 return MakeCXCursor(Prot, tu);
4466 }
4467
4468 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004469 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4470 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 return MakeCXCursor(Def, tu);
4472
4473 return MakeCXCursor(Class, tu);
4474 }
4475
4476 case CXCursor_TypeRef:
4477 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4478
4479 case CXCursor_TemplateRef:
4480 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4481
4482 case CXCursor_NamespaceRef:
4483 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4484
4485 case CXCursor_MemberRef:
4486 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4487
4488 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004489 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4491 tu ));
4492 }
4493
4494 case CXCursor_LabelRef:
4495 // FIXME: We end up faking the "parent" declaration here because we
4496 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004497 return MakeCXCursor(getCursorLabelRef(C).first,
4498 cxtu::getASTUnit(tu)->getASTContext()
4499 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 tu);
4501
4502 case CXCursor_OverloadedDeclRef:
4503 return C;
4504
4505 case CXCursor_VariableRef:
4506 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4507
4508 default:
4509 // We would prefer to enumerate all non-reference cursor kinds here.
4510 llvm_unreachable("Unhandled reference cursor kind");
4511 }
4512}
4513
4514CXCursor clang_getCursorDefinition(CXCursor C) {
4515 if (clang_isInvalid(C.kind))
4516 return clang_getNullCursor();
4517
4518 CXTranslationUnit TU = getCursorTU(C);
4519
4520 bool WasReference = false;
4521 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4522 C = clang_getCursorReferenced(C);
4523 WasReference = true;
4524 }
4525
4526 if (C.kind == CXCursor_MacroExpansion)
4527 return clang_getCursorReferenced(C);
4528
4529 if (!clang_isDeclaration(C.kind))
4530 return clang_getNullCursor();
4531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004532 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 if (!D)
4534 return clang_getNullCursor();
4535
4536 switch (D->getKind()) {
4537 // Declaration kinds that don't really separate the notions of
4538 // declaration and definition.
4539 case Decl::Namespace:
4540 case Decl::Typedef:
4541 case Decl::TypeAlias:
4542 case Decl::TypeAliasTemplate:
4543 case Decl::TemplateTypeParm:
4544 case Decl::EnumConstant:
4545 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004546 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case Decl::IndirectField:
4548 case Decl::ObjCIvar:
4549 case Decl::ObjCAtDefsField:
4550 case Decl::ImplicitParam:
4551 case Decl::ParmVar:
4552 case Decl::NonTypeTemplateParm:
4553 case Decl::TemplateTemplateParm:
4554 case Decl::ObjCCategoryImpl:
4555 case Decl::ObjCImplementation:
4556 case Decl::AccessSpec:
4557 case Decl::LinkageSpec:
4558 case Decl::ObjCPropertyImpl:
4559 case Decl::FileScopeAsm:
4560 case Decl::StaticAssert:
4561 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004562 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case Decl::Label: // FIXME: Is this right??
4564 case Decl::ClassScopeFunctionSpecialization:
4565 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004566 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 return C;
4568
4569 // Declaration kinds that don't make any sense here, but are
4570 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004571 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 case Decl::TranslationUnit:
4573 break;
4574
4575 // Declaration kinds for which the definition is not resolvable.
4576 case Decl::UnresolvedUsingTypename:
4577 case Decl::UnresolvedUsingValue:
4578 break;
4579
4580 case Decl::UsingDirective:
4581 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4582 TU);
4583
4584 case Decl::NamespaceAlias:
4585 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4586
4587 case Decl::Enum:
4588 case Decl::Record:
4589 case Decl::CXXRecord:
4590 case Decl::ClassTemplateSpecialization:
4591 case Decl::ClassTemplatePartialSpecialization:
4592 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4593 return MakeCXCursor(Def, TU);
4594 return clang_getNullCursor();
4595
4596 case Decl::Function:
4597 case Decl::CXXMethod:
4598 case Decl::CXXConstructor:
4599 case Decl::CXXDestructor:
4600 case Decl::CXXConversion: {
4601 const FunctionDecl *Def = 0;
4602 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004603 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 return clang_getNullCursor();
4605 }
4606
Larisse Voufo39a1e502013-08-06 01:03:05 +00004607 case Decl::Var:
4608 case Decl::VarTemplateSpecialization:
4609 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004611 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 return MakeCXCursor(Def, TU);
4613 return clang_getNullCursor();
4614 }
4615
4616 case Decl::FunctionTemplate: {
4617 const FunctionDecl *Def = 0;
4618 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4619 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4620 return clang_getNullCursor();
4621 }
4622
4623 case Decl::ClassTemplate: {
4624 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4625 ->getDefinition())
4626 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4627 TU);
4628 return clang_getNullCursor();
4629 }
4630
Larisse Voufo39a1e502013-08-06 01:03:05 +00004631 case Decl::VarTemplate: {
4632 if (VarDecl *Def =
4633 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4634 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4635 return clang_getNullCursor();
4636 }
4637
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case Decl::Using:
4639 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4640 D->getLocation(), TU);
4641
4642 case Decl::UsingShadow:
4643 return clang_getCursorDefinition(
4644 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4645 TU));
4646
4647 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004648 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 if (Method->isThisDeclarationADefinition())
4650 return C;
4651
4652 // Dig out the method definition in the associated
4653 // @implementation, if we have it.
4654 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004655 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4657 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4658 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4659 Method->isInstanceMethod()))
4660 if (Def->isThisDeclarationADefinition())
4661 return MakeCXCursor(Def, TU);
4662
4663 return clang_getNullCursor();
4664 }
4665
4666 case Decl::ObjCCategory:
4667 if (ObjCCategoryImplDecl *Impl
4668 = cast<ObjCCategoryDecl>(D)->getImplementation())
4669 return MakeCXCursor(Impl, TU);
4670 return clang_getNullCursor();
4671
4672 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004673 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 return MakeCXCursor(Def, TU);
4675 return clang_getNullCursor();
4676
4677 case Decl::ObjCInterface: {
4678 // There are two notions of a "definition" for an Objective-C
4679 // class: the interface and its implementation. When we resolved a
4680 // reference to an Objective-C class, produce the @interface as
4681 // the definition; when we were provided with the interface,
4682 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004683 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004685 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 return MakeCXCursor(Def, TU);
4687 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4688 return MakeCXCursor(Impl, TU);
4689 return clang_getNullCursor();
4690 }
4691
4692 case Decl::ObjCProperty:
4693 // FIXME: We don't really know where to find the
4694 // ObjCPropertyImplDecls that implement this property.
4695 return clang_getNullCursor();
4696
4697 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004698 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004700 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 return MakeCXCursor(Def, TU);
4702
4703 return clang_getNullCursor();
4704
4705 case Decl::Friend:
4706 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4707 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4708 return clang_getNullCursor();
4709
4710 case Decl::FriendTemplate:
4711 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4712 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4713 return clang_getNullCursor();
4714 }
4715
4716 return clang_getNullCursor();
4717}
4718
4719unsigned clang_isCursorDefinition(CXCursor C) {
4720 if (!clang_isDeclaration(C.kind))
4721 return 0;
4722
4723 return clang_getCursorDefinition(C) == C;
4724}
4725
4726CXCursor clang_getCanonicalCursor(CXCursor C) {
4727 if (!clang_isDeclaration(C.kind))
4728 return C;
4729
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004730 if (const Decl *D = getCursorDecl(C)) {
4731 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4733 return MakeCXCursor(CatD, getCursorTU(C));
4734
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4736 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 return MakeCXCursor(IFD, getCursorTU(C));
4738
4739 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4740 }
4741
4742 return C;
4743}
4744
4745int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4746 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4747}
4748
4749unsigned clang_getNumOverloadedDecls(CXCursor C) {
4750 if (C.kind != CXCursor_OverloadedDeclRef)
4751 return 0;
4752
4753 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004754 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 return E->getNumDecls();
4756
4757 if (OverloadedTemplateStorage *S
4758 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4759 return S->size();
4760
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004761 const Decl *D = Storage.get<const Decl *>();
4762 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 return Using->shadow_size();
4764
4765 return 0;
4766}
4767
4768CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4769 if (cursor.kind != CXCursor_OverloadedDeclRef)
4770 return clang_getNullCursor();
4771
4772 if (index >= clang_getNumOverloadedDecls(cursor))
4773 return clang_getNullCursor();
4774
4775 CXTranslationUnit TU = getCursorTU(cursor);
4776 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004777 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 return MakeCXCursor(E->decls_begin()[index], TU);
4779
4780 if (OverloadedTemplateStorage *S
4781 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4782 return MakeCXCursor(S->begin()[index], TU);
4783
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004784 const Decl *D = Storage.get<const Decl *>();
4785 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 // FIXME: This is, unfortunately, linear time.
4787 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4788 std::advance(Pos, index);
4789 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4790 }
4791
4792 return clang_getNullCursor();
4793}
4794
4795void clang_getDefinitionSpellingAndExtent(CXCursor C,
4796 const char **startBuf,
4797 const char **endBuf,
4798 unsigned *startLine,
4799 unsigned *startColumn,
4800 unsigned *endLine,
4801 unsigned *endColumn) {
4802 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004803 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4805
4806 SourceManager &SM = FD->getASTContext().getSourceManager();
4807 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4808 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4809 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4810 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4811 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4812 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4813}
4814
4815
4816CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4817 unsigned PieceIndex) {
4818 RefNamePieces Pieces;
4819
4820 switch (C.kind) {
4821 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004822 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4824 E->getQualifierLoc().getSourceRange());
4825 break;
4826
4827 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004828 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4830 E->getQualifierLoc().getSourceRange(),
4831 E->getOptionalExplicitTemplateArgs());
4832 break;
4833
4834 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004835 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004837 const Expr *Callee = OCE->getCallee();
4838 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 Callee = ICE->getSubExpr();
4840
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004841 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4843 DRE->getQualifierLoc().getSourceRange());
4844 }
4845 break;
4846
4847 default:
4848 break;
4849 }
4850
4851 if (Pieces.empty()) {
4852 if (PieceIndex == 0)
4853 return clang_getCursorExtent(C);
4854 } else if (PieceIndex < Pieces.size()) {
4855 SourceRange R = Pieces[PieceIndex];
4856 if (R.isValid())
4857 return cxloc::translateSourceRange(getCursorContext(C), R);
4858 }
4859
4860 return clang_getNullRange();
4861}
4862
4863void clang_enableStackTraces(void) {
4864 llvm::sys::PrintStackTraceOnErrorSignal();
4865}
4866
4867void clang_executeOnThread(void (*fn)(void*), void *user_data,
4868 unsigned stack_size) {
4869 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4870}
4871
4872} // end: extern "C"
4873
4874//===----------------------------------------------------------------------===//
4875// Token-based Operations.
4876//===----------------------------------------------------------------------===//
4877
4878/* CXToken layout:
4879 * int_data[0]: a CXTokenKind
4880 * int_data[1]: starting token location
4881 * int_data[2]: token length
4882 * int_data[3]: reserved
4883 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4884 * otherwise unused.
4885 */
4886extern "C" {
4887
4888CXTokenKind clang_getTokenKind(CXToken CXTok) {
4889 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4890}
4891
4892CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4893 switch (clang_getTokenKind(CXTok)) {
4894 case CXToken_Identifier:
4895 case CXToken_Keyword:
4896 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004897 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 ->getNameStart());
4899
4900 case CXToken_Literal: {
4901 // We have stashed the starting pointer in the ptr_data field. Use it.
4902 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004903 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 }
4905
4906 case CXToken_Punctuation:
4907 case CXToken_Comment:
4908 break;
4909 }
4910
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004911 if (isNotUseableTU(TU)) {
4912 LOG_BAD_TU(TU);
4913 return cxstring::createEmpty();
4914 }
4915
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 // We have to find the starting buffer pointer the hard way, by
4917 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004918 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004920 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004921
4922 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4923 std::pair<FileID, unsigned> LocInfo
4924 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4925 bool Invalid = false;
4926 StringRef Buffer
4927 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4928 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004929 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004930
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004931 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004932}
4933
4934CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004935 if (isNotUseableTU(TU)) {
4936 LOG_BAD_TU(TU);
4937 return clang_getNullLocation();
4938 }
4939
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004940 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 if (!CXXUnit)
4942 return clang_getNullLocation();
4943
4944 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4945 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4946}
4947
4948CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004949 if (isNotUseableTU(TU)) {
4950 LOG_BAD_TU(TU);
4951 return clang_getNullRange();
4952 }
4953
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004954 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (!CXXUnit)
4956 return clang_getNullRange();
4957
4958 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4959 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4960}
4961
4962static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4963 SmallVectorImpl<CXToken> &CXTokens) {
4964 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4965 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004966 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004968 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004969
4970 // Cannot tokenize across files.
4971 if (BeginLocInfo.first != EndLocInfo.first)
4972 return;
4973
4974 // Create a lexer
4975 bool Invalid = false;
4976 StringRef Buffer
4977 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4978 if (Invalid)
4979 return;
4980
4981 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4982 CXXUnit->getASTContext().getLangOpts(),
4983 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4984 Lex.SetCommentRetentionState(true);
4985
4986 // Lex tokens until we hit the end of the range.
4987 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4988 Token Tok;
4989 bool previousWasAt = false;
4990 do {
4991 // Lex the next token
4992 Lex.LexFromRawLexer(Tok);
4993 if (Tok.is(tok::eof))
4994 break;
4995
4996 // Initialize the CXToken.
4997 CXToken CXTok;
4998
4999 // - Common fields
5000 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5001 CXTok.int_data[2] = Tok.getLength();
5002 CXTok.int_data[3] = 0;
5003
5004 // - Kind-specific fields
5005 if (Tok.isLiteral()) {
5006 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005007 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 } else if (Tok.is(tok::raw_identifier)) {
5009 // Lookup the identifier to determine whether we have a keyword.
5010 IdentifierInfo *II
5011 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5012
5013 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5014 CXTok.int_data[0] = CXToken_Keyword;
5015 }
5016 else {
5017 CXTok.int_data[0] = Tok.is(tok::identifier)
5018 ? CXToken_Identifier
5019 : CXToken_Keyword;
5020 }
5021 CXTok.ptr_data = II;
5022 } else if (Tok.is(tok::comment)) {
5023 CXTok.int_data[0] = CXToken_Comment;
5024 CXTok.ptr_data = 0;
5025 } else {
5026 CXTok.int_data[0] = CXToken_Punctuation;
5027 CXTok.ptr_data = 0;
5028 }
5029 CXTokens.push_back(CXTok);
5030 previousWasAt = Tok.is(tok::at);
5031 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5032}
5033
5034void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5035 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005036 LOG_FUNC_SECTION {
5037 *Log << TU << ' ' << Range;
5038 }
5039
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 if (Tokens)
5041 *Tokens = 0;
5042 if (NumTokens)
5043 *NumTokens = 0;
5044
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005045 if (isNotUseableTU(TU)) {
5046 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005047 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005048 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005049
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005050 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 if (!CXXUnit || !Tokens || !NumTokens)
5052 return;
5053
5054 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5055
5056 SourceRange R = cxloc::translateCXSourceRange(Range);
5057 if (R.isInvalid())
5058 return;
5059
5060 SmallVector<CXToken, 32> CXTokens;
5061 getTokens(CXXUnit, R, CXTokens);
5062
5063 if (CXTokens.empty())
5064 return;
5065
5066 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5067 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5068 *NumTokens = CXTokens.size();
5069}
5070
5071void clang_disposeTokens(CXTranslationUnit TU,
5072 CXToken *Tokens, unsigned NumTokens) {
5073 free(Tokens);
5074}
5075
5076} // end: extern "C"
5077
5078//===----------------------------------------------------------------------===//
5079// Token annotation APIs.
5080//===----------------------------------------------------------------------===//
5081
Guy Benyei11169dd2012-12-18 14:30:41 +00005082static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5083 CXCursor parent,
5084 CXClientData client_data);
5085static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5086 CXClientData client_data);
5087
5088namespace {
5089class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 CXToken *Tokens;
5091 CXCursor *Cursors;
5092 unsigned NumTokens;
5093 unsigned TokIdx;
5094 unsigned PreprocessingTokIdx;
5095 CursorVisitor AnnotateVis;
5096 SourceManager &SrcMgr;
5097 bool HasContextSensitiveKeywords;
5098
5099 struct PostChildrenInfo {
5100 CXCursor Cursor;
5101 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005102 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 unsigned BeforeChildrenTokenIdx;
5104 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005105 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005106
5107 CXToken &getTok(unsigned Idx) {
5108 assert(Idx < NumTokens);
5109 return Tokens[Idx];
5110 }
5111 const CXToken &getTok(unsigned Idx) const {
5112 assert(Idx < NumTokens);
5113 return Tokens[Idx];
5114 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 bool MoreTokens() const { return TokIdx < NumTokens; }
5116 unsigned NextToken() const { return TokIdx; }
5117 void AdvanceToken() { ++TokIdx; }
5118 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005119 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 }
5121 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005122 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 }
5124 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005125 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 }
5127
5128 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005129 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 SourceRange);
5131
5132public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005133 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005134 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005135 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005137 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 AnnotateTokensVisitor, this,
5139 /*VisitPreprocessorLast=*/true,
5140 /*VisitIncludedEntities=*/false,
5141 RegionOfInterest,
5142 /*VisitDeclsOnly=*/false,
5143 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005144 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 HasContextSensitiveKeywords(false) { }
5146
5147 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5148 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5149 bool postVisitChildren(CXCursor cursor);
5150 void AnnotateTokens();
5151
5152 /// \brief Determine whether the annotator saw any cursors that have
5153 /// context-sensitive keywords.
5154 bool hasContextSensitiveKeywords() const {
5155 return HasContextSensitiveKeywords;
5156 }
5157
5158 ~AnnotateTokensWorker() {
5159 assert(PostChildrenInfos.empty());
5160 }
5161};
5162}
5163
5164void AnnotateTokensWorker::AnnotateTokens() {
5165 // Walk the AST within the region of interest, annotating tokens
5166 // along the way.
5167 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005168}
Guy Benyei11169dd2012-12-18 14:30:41 +00005169
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005170static inline void updateCursorAnnotation(CXCursor &Cursor,
5171 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005172 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005174 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005175}
5176
5177/// \brief It annotates and advances tokens with a cursor until the comparison
5178//// between the cursor location and the source range is the same as
5179/// \arg compResult.
5180///
5181/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5182/// Pass RangeOverlap to annotate tokens inside a range.
5183void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5184 RangeComparisonResult compResult,
5185 SourceRange range) {
5186 while (MoreTokens()) {
5187 const unsigned I = NextToken();
5188 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005189 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5190 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005191
5192 SourceLocation TokLoc = GetTokenLoc(I);
5193 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005194 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 AdvanceToken();
5196 continue;
5197 }
5198 break;
5199 }
5200}
5201
5202/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005203/// \returns true if it advanced beyond all macro tokens, false otherwise.
5204bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 CXCursor updateC,
5206 RangeComparisonResult compResult,
5207 SourceRange range) {
5208 assert(MoreTokens());
5209 assert(isFunctionMacroToken(NextToken()) &&
5210 "Should be called only for macro arg tokens");
5211
5212 // This works differently than annotateAndAdvanceTokens; because expanded
5213 // macro arguments can have arbitrary translation-unit source order, we do not
5214 // advance the token index one by one until a token fails the range test.
5215 // We only advance once past all of the macro arg tokens if all of them
5216 // pass the range test. If one of them fails we keep the token index pointing
5217 // at the start of the macro arg tokens so that the failing token will be
5218 // annotated by a subsequent annotation try.
5219
5220 bool atLeastOneCompFail = false;
5221
5222 unsigned I = NextToken();
5223 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5224 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5225 if (TokLoc.isFileID())
5226 continue; // not macro arg token, it's parens or comma.
5227 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5228 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5229 Cursors[I] = updateC;
5230 } else
5231 atLeastOneCompFail = true;
5232 }
5233
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005234 if (atLeastOneCompFail)
5235 return false;
5236
5237 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5238 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005239}
5240
5241enum CXChildVisitResult
5242AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 SourceRange cursorRange = getRawCursorExtent(cursor);
5244 if (cursorRange.isInvalid())
5245 return CXChildVisit_Recurse;
5246
5247 if (!HasContextSensitiveKeywords) {
5248 // Objective-C properties can have context-sensitive keywords.
5249 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005250 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005251 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5252 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5253 }
5254 // Objective-C methods can have context-sensitive keywords.
5255 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5256 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005257 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5259 if (Method->getObjCDeclQualifier())
5260 HasContextSensitiveKeywords = true;
5261 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005262 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5263 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 P != PEnd; ++P) {
5265 if ((*P)->getObjCDeclQualifier()) {
5266 HasContextSensitiveKeywords = true;
5267 break;
5268 }
5269 }
5270 }
5271 }
5272 }
5273 // C++ methods can have context-sensitive keywords.
5274 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005275 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5277 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5278 HasContextSensitiveKeywords = true;
5279 }
5280 }
5281 // C++ classes can have context-sensitive keywords.
5282 else if (cursor.kind == CXCursor_StructDecl ||
5283 cursor.kind == CXCursor_ClassDecl ||
5284 cursor.kind == CXCursor_ClassTemplate ||
5285 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005286 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 if (D->hasAttr<FinalAttr>())
5288 HasContextSensitiveKeywords = true;
5289 }
5290 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005291
5292 // Don't override a property annotation with its getter/setter method.
5293 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5294 parent.kind == CXCursor_ObjCPropertyDecl)
5295 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005296
5297 if (clang_isPreprocessing(cursor.kind)) {
5298 // Items in the preprocessing record are kept separate from items in
5299 // declarations, so we keep a separate token index.
5300 unsigned SavedTokIdx = TokIdx;
5301 TokIdx = PreprocessingTokIdx;
5302
5303 // Skip tokens up until we catch up to the beginning of the preprocessing
5304 // entry.
5305 while (MoreTokens()) {
5306 const unsigned I = NextToken();
5307 SourceLocation TokLoc = GetTokenLoc(I);
5308 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5309 case RangeBefore:
5310 AdvanceToken();
5311 continue;
5312 case RangeAfter:
5313 case RangeOverlap:
5314 break;
5315 }
5316 break;
5317 }
5318
5319 // Look at all of the tokens within this range.
5320 while (MoreTokens()) {
5321 const unsigned I = NextToken();
5322 SourceLocation TokLoc = GetTokenLoc(I);
5323 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5324 case RangeBefore:
5325 llvm_unreachable("Infeasible");
5326 case RangeAfter:
5327 break;
5328 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005329 // For macro expansions, just note where the beginning of the macro
5330 // expansion occurs.
5331 if (cursor.kind == CXCursor_MacroExpansion) {
5332 if (TokLoc == cursorRange.getBegin())
5333 Cursors[I] = cursor;
5334 AdvanceToken();
5335 break;
5336 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005337 // We may have already annotated macro names inside macro definitions.
5338 if (Cursors[I].kind != CXCursor_MacroExpansion)
5339 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 continue;
5342 }
5343 break;
5344 }
5345
5346 // Save the preprocessing token index; restore the non-preprocessing
5347 // token index.
5348 PreprocessingTokIdx = TokIdx;
5349 TokIdx = SavedTokIdx;
5350 return CXChildVisit_Recurse;
5351 }
5352
5353 if (cursorRange.isInvalid())
5354 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005355
5356 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 const enum CXCursorKind K = clang_getCursorKind(parent);
5359 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005360 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5361 // Attributes are annotated out-of-order, skip tokens until we reach it.
5362 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 ? clang_getNullCursor() : parent;
5364
5365 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5366
5367 // Avoid having the cursor of an expression "overwrite" the annotation of the
5368 // variable declaration that it belongs to.
5369 // This can happen for C++ constructor expressions whose range generally
5370 // include the variable declaration, e.g.:
5371 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005372 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005373 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005374 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 const unsigned I = NextToken();
5376 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5377 E->getLocStart() == D->getLocation() &&
5378 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005379 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 AdvanceToken();
5381 }
5382 }
5383 }
5384
5385 // Before recursing into the children keep some state that we are going
5386 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5387 // extra work after the child nodes are visited.
5388 // Note that we don't call VisitChildren here to avoid traversing statements
5389 // code-recursively which can blow the stack.
5390
5391 PostChildrenInfo Info;
5392 Info.Cursor = cursor;
5393 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005394 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 Info.BeforeChildrenTokenIdx = NextToken();
5396 PostChildrenInfos.push_back(Info);
5397
5398 return CXChildVisit_Recurse;
5399}
5400
5401bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5402 if (PostChildrenInfos.empty())
5403 return false;
5404 const PostChildrenInfo &Info = PostChildrenInfos.back();
5405 if (!clang_equalCursors(Info.Cursor, cursor))
5406 return false;
5407
5408 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5409 const unsigned AfterChildren = NextToken();
5410 SourceRange cursorRange = Info.CursorRange;
5411
5412 // Scan the tokens that are at the end of the cursor, but are not captured
5413 // but the child cursors.
5414 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5415
5416 // Scan the tokens that are at the beginning of the cursor, but are not
5417 // capture by the child cursors.
5418 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5419 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5420 break;
5421
5422 Cursors[I] = cursor;
5423 }
5424
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005425 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5426 // encountered the attribute cursor.
5427 if (clang_isAttribute(cursor.kind))
5428 TokIdx = Info.BeforeReachingCursorIdx;
5429
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 PostChildrenInfos.pop_back();
5431 return false;
5432}
5433
5434static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5435 CXCursor parent,
5436 CXClientData client_data) {
5437 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5438}
5439
5440static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5441 CXClientData client_data) {
5442 return static_cast<AnnotateTokensWorker*>(client_data)->
5443 postVisitChildren(cursor);
5444}
5445
5446namespace {
5447
5448/// \brief Uses the macro expansions in the preprocessing record to find
5449/// and mark tokens that are macro arguments. This info is used by the
5450/// AnnotateTokensWorker.
5451class MarkMacroArgTokensVisitor {
5452 SourceManager &SM;
5453 CXToken *Tokens;
5454 unsigned NumTokens;
5455 unsigned CurIdx;
5456
5457public:
5458 MarkMacroArgTokensVisitor(SourceManager &SM,
5459 CXToken *tokens, unsigned numTokens)
5460 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5461
5462 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5463 if (cursor.kind != CXCursor_MacroExpansion)
5464 return CXChildVisit_Continue;
5465
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005466 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 if (macroRange.getBegin() == macroRange.getEnd())
5468 return CXChildVisit_Continue; // it's not a function macro.
5469
5470 for (; CurIdx < NumTokens; ++CurIdx) {
5471 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5472 macroRange.getBegin()))
5473 break;
5474 }
5475
5476 if (CurIdx == NumTokens)
5477 return CXChildVisit_Break;
5478
5479 for (; CurIdx < NumTokens; ++CurIdx) {
5480 SourceLocation tokLoc = getTokenLoc(CurIdx);
5481 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5482 break;
5483
5484 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5485 }
5486
5487 if (CurIdx == NumTokens)
5488 return CXChildVisit_Break;
5489
5490 return CXChildVisit_Continue;
5491 }
5492
5493private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005494 CXToken &getTok(unsigned Idx) {
5495 assert(Idx < NumTokens);
5496 return Tokens[Idx];
5497 }
5498 const CXToken &getTok(unsigned Idx) const {
5499 assert(Idx < NumTokens);
5500 return Tokens[Idx];
5501 }
5502
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005504 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 }
5506
5507 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5508 // The third field is reserved and currently not used. Use it here
5509 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005510 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 }
5512};
5513
5514} // end anonymous namespace
5515
5516static CXChildVisitResult
5517MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5518 CXClientData client_data) {
5519 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5520 parent);
5521}
5522
5523namespace {
5524 struct clang_annotateTokens_Data {
5525 CXTranslationUnit TU;
5526 ASTUnit *CXXUnit;
5527 CXToken *Tokens;
5528 unsigned NumTokens;
5529 CXCursor *Cursors;
5530 };
5531}
5532
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005533/// \brief Used by \c annotatePreprocessorTokens.
5534/// \returns true if lexing was finished, false otherwise.
5535static bool lexNext(Lexer &Lex, Token &Tok,
5536 unsigned &NextIdx, unsigned NumTokens) {
5537 if (NextIdx >= NumTokens)
5538 return true;
5539
5540 ++NextIdx;
5541 Lex.LexFromRawLexer(Tok);
5542 if (Tok.is(tok::eof))
5543 return true;
5544
5545 return false;
5546}
5547
Guy Benyei11169dd2012-12-18 14:30:41 +00005548static void annotatePreprocessorTokens(CXTranslationUnit TU,
5549 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005550 CXCursor *Cursors,
5551 CXToken *Tokens,
5552 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005553 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005554
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005555 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5557 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005558 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005560 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005561
5562 if (BeginLocInfo.first != EndLocInfo.first)
5563 return;
5564
5565 StringRef Buffer;
5566 bool Invalid = false;
5567 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5568 if (Buffer.empty() || Invalid)
5569 return;
5570
5571 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5572 CXXUnit->getASTContext().getLangOpts(),
5573 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5574 Buffer.end());
5575 Lex.SetCommentRetentionState(true);
5576
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005577 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 // Lex tokens in raw mode until we hit the end of the range, to avoid
5579 // entering #includes or expanding macros.
5580 while (true) {
5581 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005582 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5583 break;
5584 unsigned TokIdx = NextIdx-1;
5585 assert(Tok.getLocation() ==
5586 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005587
5588 reprocess:
5589 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005590 // We have found a preprocessing directive. Annotate the tokens
5591 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 //
5593 // FIXME: Some simple tests here could identify macro definitions and
5594 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005595
5596 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005597 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5598 break;
5599
5600 MacroInfo *MI = 0;
5601 if (Tok.is(tok::raw_identifier) &&
5602 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5603 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5604 break;
5605
5606 if (Tok.is(tok::raw_identifier)) {
5607 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5608 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5609 SourceLocation MappedTokLoc =
5610 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5611 MI = getMacroInfo(II, MappedTokLoc, TU);
5612 }
5613 }
5614
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005615 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005617 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5618 finished = true;
5619 break;
5620 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005621 // If we are in a macro definition, check if the token was ever a
5622 // macro name and annotate it if that's the case.
5623 if (MI) {
5624 SourceLocation SaveLoc = Tok.getLocation();
5625 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5626 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5627 Tok.setLocation(SaveLoc);
5628 if (MacroDef)
5629 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5630 Tok.getLocation(), TU);
5631 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005632 } while (!Tok.isAtStartOfLine());
5633
5634 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5635 assert(TokIdx <= LastIdx);
5636 SourceLocation EndLoc =
5637 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5638 CXCursor Cursor =
5639 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5640
5641 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005642 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005643
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005644 if (finished)
5645 break;
5646 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 }
5649}
5650
5651// This gets run a separate thread to avoid stack blowout.
5652static void clang_annotateTokensImpl(void *UserData) {
5653 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5654 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5655 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5656 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5657 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5658
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005659 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5661 setThreadBackgroundPriority();
5662
5663 // Determine the region of interest, which contains all of the tokens.
5664 SourceRange RegionOfInterest;
5665 RegionOfInterest.setBegin(
5666 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5667 RegionOfInterest.setEnd(
5668 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5669 Tokens[NumTokens-1])));
5670
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 // Relex the tokens within the source range to look for preprocessing
5672 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005674
5675 // If begin location points inside a macro argument, set it to the expansion
5676 // location so we can have the full context when annotating semantically.
5677 {
5678 SourceManager &SM = CXXUnit->getSourceManager();
5679 SourceLocation Loc =
5680 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5681 if (Loc.isMacroID())
5682 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5683 }
5684
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5686 // Search and mark tokens that are macro argument expansions.
5687 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5688 Tokens, NumTokens);
5689 CursorVisitor MacroArgMarker(TU,
5690 MarkMacroArgTokensVisitorDelegate, &Visitor,
5691 /*VisitPreprocessorLast=*/true,
5692 /*VisitIncludedEntities=*/false,
5693 RegionOfInterest);
5694 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5695 }
5696
5697 // Annotate all of the source locations in the region of interest that map to
5698 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005700
5701 // FIXME: We use a ridiculous stack size here because the data-recursion
5702 // algorithm uses a large stack frame than the non-data recursive version,
5703 // and AnnotationTokensWorker currently transforms the data-recursion
5704 // algorithm back into a traditional recursion by explicitly calling
5705 // VisitChildren(). We will need to remove this explicit recursive call.
5706 W.AnnotateTokens();
5707
5708 // If we ran into any entities that involve context-sensitive keywords,
5709 // take another pass through the tokens to mark them as such.
5710 if (W.hasContextSensitiveKeywords()) {
5711 for (unsigned I = 0; I != NumTokens; ++I) {
5712 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5713 continue;
5714
5715 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5716 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005717 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5719 if (Property->getPropertyAttributesAsWritten() != 0 &&
5720 llvm::StringSwitch<bool>(II->getName())
5721 .Case("readonly", true)
5722 .Case("assign", true)
5723 .Case("unsafe_unretained", true)
5724 .Case("readwrite", true)
5725 .Case("retain", true)
5726 .Case("copy", true)
5727 .Case("nonatomic", true)
5728 .Case("atomic", true)
5729 .Case("getter", true)
5730 .Case("setter", true)
5731 .Case("strong", true)
5732 .Case("weak", true)
5733 .Default(false))
5734 Tokens[I].int_data[0] = CXToken_Keyword;
5735 }
5736 continue;
5737 }
5738
5739 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5740 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5741 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5742 if (llvm::StringSwitch<bool>(II->getName())
5743 .Case("in", true)
5744 .Case("out", true)
5745 .Case("inout", true)
5746 .Case("oneway", true)
5747 .Case("bycopy", true)
5748 .Case("byref", true)
5749 .Default(false))
5750 Tokens[I].int_data[0] = CXToken_Keyword;
5751 continue;
5752 }
5753
5754 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5755 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5756 Tokens[I].int_data[0] = CXToken_Keyword;
5757 continue;
5758 }
5759 }
5760 }
5761}
5762
5763extern "C" {
5764
5765void clang_annotateTokens(CXTranslationUnit TU,
5766 CXToken *Tokens, unsigned NumTokens,
5767 CXCursor *Cursors) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005768 if (isNotUseableTU(TU)) {
5769 LOG_BAD_TU(TU);
5770 return;
5771 }
5772 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005773 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005775 }
5776
5777 LOG_FUNC_SECTION {
5778 *Log << TU << ' ';
5779 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5780 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5781 *Log << clang_getRange(bloc, eloc);
5782 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005783
5784 // Any token we don't specifically annotate will have a NULL cursor.
5785 CXCursor C = clang_getNullCursor();
5786 for (unsigned I = 0; I != NumTokens; ++I)
5787 Cursors[I] = C;
5788
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005789 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005790 if (!CXXUnit)
5791 return;
5792
5793 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5794
5795 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5796 llvm::CrashRecoveryContext CRC;
5797 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5798 GetSafetyThreadStackSize() * 2)) {
5799 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5800 }
5801}
5802
5803} // end: extern "C"
5804
5805//===----------------------------------------------------------------------===//
5806// Operations for querying linkage of a cursor.
5807//===----------------------------------------------------------------------===//
5808
5809extern "C" {
5810CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5811 if (!clang_isDeclaration(cursor.kind))
5812 return CXLinkage_Invalid;
5813
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005814 const Decl *D = cxcursor::getCursorDecl(cursor);
5815 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005816 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005817 case NoLinkage:
5818 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 case InternalLinkage: return CXLinkage_Internal;
5820 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5821 case ExternalLinkage: return CXLinkage_External;
5822 };
5823
5824 return CXLinkage_Invalid;
5825}
5826} // end: extern "C"
5827
5828//===----------------------------------------------------------------------===//
5829// Operations for querying language of a cursor.
5830//===----------------------------------------------------------------------===//
5831
5832static CXLanguageKind getDeclLanguage(const Decl *D) {
5833 if (!D)
5834 return CXLanguage_C;
5835
5836 switch (D->getKind()) {
5837 default:
5838 break;
5839 case Decl::ImplicitParam:
5840 case Decl::ObjCAtDefsField:
5841 case Decl::ObjCCategory:
5842 case Decl::ObjCCategoryImpl:
5843 case Decl::ObjCCompatibleAlias:
5844 case Decl::ObjCImplementation:
5845 case Decl::ObjCInterface:
5846 case Decl::ObjCIvar:
5847 case Decl::ObjCMethod:
5848 case Decl::ObjCProperty:
5849 case Decl::ObjCPropertyImpl:
5850 case Decl::ObjCProtocol:
5851 return CXLanguage_ObjC;
5852 case Decl::CXXConstructor:
5853 case Decl::CXXConversion:
5854 case Decl::CXXDestructor:
5855 case Decl::CXXMethod:
5856 case Decl::CXXRecord:
5857 case Decl::ClassTemplate:
5858 case Decl::ClassTemplatePartialSpecialization:
5859 case Decl::ClassTemplateSpecialization:
5860 case Decl::Friend:
5861 case Decl::FriendTemplate:
5862 case Decl::FunctionTemplate:
5863 case Decl::LinkageSpec:
5864 case Decl::Namespace:
5865 case Decl::NamespaceAlias:
5866 case Decl::NonTypeTemplateParm:
5867 case Decl::StaticAssert:
5868 case Decl::TemplateTemplateParm:
5869 case Decl::TemplateTypeParm:
5870 case Decl::UnresolvedUsingTypename:
5871 case Decl::UnresolvedUsingValue:
5872 case Decl::Using:
5873 case Decl::UsingDirective:
5874 case Decl::UsingShadow:
5875 return CXLanguage_CPlusPlus;
5876 }
5877
5878 return CXLanguage_C;
5879}
5880
5881extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005882
5883static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5884 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5885 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005886
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005887 switch (D->getAvailability()) {
5888 case AR_Available:
5889 case AR_NotYetIntroduced:
5890 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005891 return getCursorAvailabilityForDecl(
5892 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005893 return CXAvailability_Available;
5894
5895 case AR_Deprecated:
5896 return CXAvailability_Deprecated;
5897
5898 case AR_Unavailable:
5899 return CXAvailability_NotAvailable;
5900 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005901
5902 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005903}
5904
Guy Benyei11169dd2012-12-18 14:30:41 +00005905enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5906 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005907 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5908 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005909
5910 return CXAvailability_Available;
5911}
5912
5913static CXVersion convertVersion(VersionTuple In) {
5914 CXVersion Out = { -1, -1, -1 };
5915 if (In.empty())
5916 return Out;
5917
5918 Out.Major = In.getMajor();
5919
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005920 Optional<unsigned> Minor = In.getMinor();
5921 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 Out.Minor = *Minor;
5923 else
5924 return Out;
5925
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005926 Optional<unsigned> Subminor = In.getSubminor();
5927 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005928 Out.Subminor = *Subminor;
5929
5930 return Out;
5931}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005932
5933static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5934 int *always_deprecated,
5935 CXString *deprecated_message,
5936 int *always_unavailable,
5937 CXString *unavailable_message,
5938 CXPlatformAvailability *availability,
5939 int availability_size) {
5940 bool HadAvailAttr = false;
5941 int N = 0;
5942 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5943 ++A) {
5944 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5945 HadAvailAttr = true;
5946 if (always_deprecated)
5947 *always_deprecated = 1;
5948 if (deprecated_message)
5949 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5950 continue;
5951 }
5952
5953 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5954 HadAvailAttr = true;
5955 if (always_unavailable)
5956 *always_unavailable = 1;
5957 if (unavailable_message) {
5958 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5959 }
5960 continue;
5961 }
5962
5963 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5964 HadAvailAttr = true;
5965 if (N < availability_size) {
5966 availability[N].Platform
5967 = cxstring::createDup(Avail->getPlatform()->getName());
5968 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5969 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5970 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5971 availability[N].Unavailable = Avail->getUnavailable();
5972 availability[N].Message = cxstring::createDup(Avail->getMessage());
5973 }
5974 ++N;
5975 }
5976 }
5977
5978 if (!HadAvailAttr)
5979 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5980 return getCursorPlatformAvailabilityForDecl(
5981 cast<Decl>(EnumConst->getDeclContext()),
5982 always_deprecated,
5983 deprecated_message,
5984 always_unavailable,
5985 unavailable_message,
5986 availability,
5987 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005988
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005989 return N;
5990}
5991
Guy Benyei11169dd2012-12-18 14:30:41 +00005992int clang_getCursorPlatformAvailability(CXCursor cursor,
5993 int *always_deprecated,
5994 CXString *deprecated_message,
5995 int *always_unavailable,
5996 CXString *unavailable_message,
5997 CXPlatformAvailability *availability,
5998 int availability_size) {
5999 if (always_deprecated)
6000 *always_deprecated = 0;
6001 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006002 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 if (always_unavailable)
6004 *always_unavailable = 0;
6005 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006006 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006007
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 if (!clang_isDeclaration(cursor.kind))
6009 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006010
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006011 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 if (!D)
6013 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006014
6015 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6016 deprecated_message,
6017 always_unavailable,
6018 unavailable_message,
6019 availability,
6020 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006021}
6022
6023void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6024 clang_disposeString(availability->Platform);
6025 clang_disposeString(availability->Message);
6026}
6027
6028CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6029 if (clang_isDeclaration(cursor.kind))
6030 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6031
6032 return CXLanguage_Invalid;
6033}
6034
6035 /// \brief If the given cursor is the "templated" declaration
6036 /// descibing a class or function template, return the class or
6037 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006038static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006039 if (!D)
6040 return 0;
6041
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006042 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6044 return FunTmpl;
6045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006046 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6048 return ClassTmpl;
6049
6050 return D;
6051}
6052
6053CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6054 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006055 if (const Decl *D = getCursorDecl(cursor)) {
6056 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006057 if (!DC)
6058 return clang_getNullCursor();
6059
6060 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6061 getCursorTU(cursor));
6062 }
6063 }
6064
6065 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006066 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006067 return MakeCXCursor(D, getCursorTU(cursor));
6068 }
6069
6070 return clang_getNullCursor();
6071}
6072
6073CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6074 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006075 if (const Decl *D = getCursorDecl(cursor)) {
6076 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 if (!DC)
6078 return clang_getNullCursor();
6079
6080 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6081 getCursorTU(cursor));
6082 }
6083 }
6084
6085 // FIXME: Note that we can't easily compute the lexical context of a
6086 // statement or expression, so we return nothing.
6087 return clang_getNullCursor();
6088}
6089
6090CXFile clang_getIncludedFile(CXCursor cursor) {
6091 if (cursor.kind != CXCursor_InclusionDirective)
6092 return 0;
6093
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006094 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006095 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006096}
6097
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006098unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6099 if (C.kind != CXCursor_ObjCPropertyDecl)
6100 return CXObjCPropertyAttr_noattr;
6101
6102 unsigned Result = CXObjCPropertyAttr_noattr;
6103 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6104 ObjCPropertyDecl::PropertyAttributeKind Attr =
6105 PD->getPropertyAttributesAsWritten();
6106
6107#define SET_CXOBJCPROP_ATTR(A) \
6108 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6109 Result |= CXObjCPropertyAttr_##A
6110 SET_CXOBJCPROP_ATTR(readonly);
6111 SET_CXOBJCPROP_ATTR(getter);
6112 SET_CXOBJCPROP_ATTR(assign);
6113 SET_CXOBJCPROP_ATTR(readwrite);
6114 SET_CXOBJCPROP_ATTR(retain);
6115 SET_CXOBJCPROP_ATTR(copy);
6116 SET_CXOBJCPROP_ATTR(nonatomic);
6117 SET_CXOBJCPROP_ATTR(setter);
6118 SET_CXOBJCPROP_ATTR(atomic);
6119 SET_CXOBJCPROP_ATTR(weak);
6120 SET_CXOBJCPROP_ATTR(strong);
6121 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6122#undef SET_CXOBJCPROP_ATTR
6123
6124 return Result;
6125}
6126
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006127unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6128 if (!clang_isDeclaration(C.kind))
6129 return CXObjCDeclQualifier_None;
6130
6131 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6132 const Decl *D = getCursorDecl(C);
6133 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6134 QT = MD->getObjCDeclQualifier();
6135 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6136 QT = PD->getObjCDeclQualifier();
6137 if (QT == Decl::OBJC_TQ_None)
6138 return CXObjCDeclQualifier_None;
6139
6140 unsigned Result = CXObjCDeclQualifier_None;
6141 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6142 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6143 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6144 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6145 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6146 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6147
6148 return Result;
6149}
6150
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006151unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6152 if (!clang_isDeclaration(C.kind))
6153 return 0;
6154
6155 const Decl *D = getCursorDecl(C);
6156 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6157 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6158 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6159 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6160
6161 return 0;
6162}
6163
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006164unsigned clang_Cursor_isVariadic(CXCursor C) {
6165 if (!clang_isDeclaration(C.kind))
6166 return 0;
6167
6168 const Decl *D = getCursorDecl(C);
6169 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6170 return FD->isVariadic();
6171 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6172 return MD->isVariadic();
6173
6174 return 0;
6175}
6176
Guy Benyei11169dd2012-12-18 14:30:41 +00006177CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6178 if (!clang_isDeclaration(C.kind))
6179 return clang_getNullRange();
6180
6181 const Decl *D = getCursorDecl(C);
6182 ASTContext &Context = getCursorContext(C);
6183 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6184 if (!RC)
6185 return clang_getNullRange();
6186
6187 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6188}
6189
6190CXString clang_Cursor_getRawCommentText(CXCursor C) {
6191 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006192 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006193
6194 const Decl *D = getCursorDecl(C);
6195 ASTContext &Context = getCursorContext(C);
6196 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6197 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6198 StringRef();
6199
6200 // Don't duplicate the string because RawText points directly into source
6201 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006202 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006203}
6204
6205CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6206 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006207 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006208
6209 const Decl *D = getCursorDecl(C);
6210 const ASTContext &Context = getCursorContext(C);
6211 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6212
6213 if (RC) {
6214 StringRef BriefText = RC->getBriefText(Context);
6215
6216 // Don't duplicate the string because RawComment ensures that this memory
6217 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006218 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006219 }
6220
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006221 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006222}
6223
6224CXComment clang_Cursor_getParsedComment(CXCursor C) {
6225 if (!clang_isDeclaration(C.kind))
6226 return cxcomment::createCXComment(NULL, NULL);
6227
6228 const Decl *D = getCursorDecl(C);
6229 const ASTContext &Context = getCursorContext(C);
6230 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6231
6232 return cxcomment::createCXComment(FC, getCursorTU(C));
6233}
6234
6235CXModule clang_Cursor_getModule(CXCursor C) {
6236 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006237 if (const ImportDecl *ImportD =
6238 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 return ImportD->getImportedModule();
6240 }
6241
6242 return 0;
6243}
6244
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006245CXFile clang_Module_getASTFile(CXModule CXMod) {
6246 if (!CXMod)
6247 return 0;
6248 Module *Mod = static_cast<Module*>(CXMod);
6249 return const_cast<FileEntry *>(Mod->getASTFile());
6250}
6251
Guy Benyei11169dd2012-12-18 14:30:41 +00006252CXModule clang_Module_getParent(CXModule CXMod) {
6253 if (!CXMod)
6254 return 0;
6255 Module *Mod = static_cast<Module*>(CXMod);
6256 return Mod->Parent;
6257}
6258
6259CXString clang_Module_getName(CXModule CXMod) {
6260 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006261 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006262 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006263 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006264}
6265
6266CXString clang_Module_getFullName(CXModule CXMod) {
6267 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006268 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006269 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006270 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006271}
6272
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006273unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6274 CXModule CXMod) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006275 if (isNotUseableTU(TU)) {
6276 LOG_BAD_TU(TU);
6277 return 0;
6278 }
6279 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 return 0;
6281 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006282 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6283 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6284 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006285}
6286
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006287CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6288 CXModule CXMod, unsigned Index) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006289 if (isNotUseableTU(TU)) {
6290 LOG_BAD_TU(TU);
6291 return 0;
6292 }
6293 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 return 0;
6295 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006296 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006297
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006298 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6299 if (Index < TopHeaders.size())
6300 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301
6302 return 0;
6303}
6304
6305} // end: extern "C"
6306
6307//===----------------------------------------------------------------------===//
6308// C++ AST instrospection.
6309//===----------------------------------------------------------------------===//
6310
6311extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006312unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6313 if (!clang_isDeclaration(C.kind))
6314 return 0;
6315
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006316 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006317 const CXXMethodDecl *Method =
6318 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006319 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6320}
6321
Guy Benyei11169dd2012-12-18 14:30:41 +00006322unsigned clang_CXXMethod_isStatic(CXCursor C) {
6323 if (!clang_isDeclaration(C.kind))
6324 return 0;
6325
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006326 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006327 const CXXMethodDecl *Method =
6328 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006329 return (Method && Method->isStatic()) ? 1 : 0;
6330}
6331
6332unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6333 if (!clang_isDeclaration(C.kind))
6334 return 0;
6335
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006336 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006337 const CXXMethodDecl *Method =
6338 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 return (Method && Method->isVirtual()) ? 1 : 0;
6340}
6341} // end: extern "C"
6342
6343//===----------------------------------------------------------------------===//
6344// Attribute introspection.
6345//===----------------------------------------------------------------------===//
6346
6347extern "C" {
6348CXType clang_getIBOutletCollectionType(CXCursor C) {
6349 if (C.kind != CXCursor_IBOutletCollectionAttr)
6350 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6351
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006352 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006353 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6354
6355 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6356}
6357} // end: extern "C"
6358
6359//===----------------------------------------------------------------------===//
6360// Inspecting memory usage.
6361//===----------------------------------------------------------------------===//
6362
6363typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6364
6365static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6366 enum CXTUResourceUsageKind k,
6367 unsigned long amount) {
6368 CXTUResourceUsageEntry entry = { k, amount };
6369 entries.push_back(entry);
6370}
6371
6372extern "C" {
6373
6374const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6375 const char *str = "";
6376 switch (kind) {
6377 case CXTUResourceUsage_AST:
6378 str = "ASTContext: expressions, declarations, and types";
6379 break;
6380 case CXTUResourceUsage_Identifiers:
6381 str = "ASTContext: identifiers";
6382 break;
6383 case CXTUResourceUsage_Selectors:
6384 str = "ASTContext: selectors";
6385 break;
6386 case CXTUResourceUsage_GlobalCompletionResults:
6387 str = "Code completion: cached global results";
6388 break;
6389 case CXTUResourceUsage_SourceManagerContentCache:
6390 str = "SourceManager: content cache allocator";
6391 break;
6392 case CXTUResourceUsage_AST_SideTables:
6393 str = "ASTContext: side tables";
6394 break;
6395 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6396 str = "SourceManager: malloc'ed memory buffers";
6397 break;
6398 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6399 str = "SourceManager: mmap'ed memory buffers";
6400 break;
6401 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6402 str = "ExternalASTSource: malloc'ed memory buffers";
6403 break;
6404 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6405 str = "ExternalASTSource: mmap'ed memory buffers";
6406 break;
6407 case CXTUResourceUsage_Preprocessor:
6408 str = "Preprocessor: malloc'ed memory";
6409 break;
6410 case CXTUResourceUsage_PreprocessingRecord:
6411 str = "Preprocessor: PreprocessingRecord";
6412 break;
6413 case CXTUResourceUsage_SourceManager_DataStructures:
6414 str = "SourceManager: data structures and tables";
6415 break;
6416 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6417 str = "Preprocessor: header search tables";
6418 break;
6419 }
6420 return str;
6421}
6422
6423CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006424 if (isNotUseableTU(TU)) {
6425 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6427 return usage;
6428 }
6429
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006430 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6432 ASTContext &astContext = astUnit->getASTContext();
6433
6434 // How much memory is used by AST nodes and types?
6435 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6436 (unsigned long) astContext.getASTAllocatedMemory());
6437
6438 // How much memory is used by identifiers?
6439 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6440 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6441
6442 // How much memory is used for selectors?
6443 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6444 (unsigned long) astContext.Selectors.getTotalMemory());
6445
6446 // How much memory is used by ASTContext's side tables?
6447 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6448 (unsigned long) astContext.getSideTableAllocatedMemory());
6449
6450 // How much memory is used for caching global code completion results?
6451 unsigned long completionBytes = 0;
6452 if (GlobalCodeCompletionAllocator *completionAllocator =
6453 astUnit->getCachedCompletionAllocator().getPtr()) {
6454 completionBytes = completionAllocator->getTotalMemory();
6455 }
6456 createCXTUResourceUsageEntry(*entries,
6457 CXTUResourceUsage_GlobalCompletionResults,
6458 completionBytes);
6459
6460 // How much memory is being used by SourceManager's content cache?
6461 createCXTUResourceUsageEntry(*entries,
6462 CXTUResourceUsage_SourceManagerContentCache,
6463 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6464
6465 // How much memory is being used by the MemoryBuffer's in SourceManager?
6466 const SourceManager::MemoryBufferSizes &srcBufs =
6467 astUnit->getSourceManager().getMemoryBufferSizes();
6468
6469 createCXTUResourceUsageEntry(*entries,
6470 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6471 (unsigned long) srcBufs.malloc_bytes);
6472 createCXTUResourceUsageEntry(*entries,
6473 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6474 (unsigned long) srcBufs.mmap_bytes);
6475 createCXTUResourceUsageEntry(*entries,
6476 CXTUResourceUsage_SourceManager_DataStructures,
6477 (unsigned long) astContext.getSourceManager()
6478 .getDataStructureSizes());
6479
6480 // How much memory is being used by the ExternalASTSource?
6481 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6482 const ExternalASTSource::MemoryBufferSizes &sizes =
6483 esrc->getMemoryBufferSizes();
6484
6485 createCXTUResourceUsageEntry(*entries,
6486 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6487 (unsigned long) sizes.malloc_bytes);
6488 createCXTUResourceUsageEntry(*entries,
6489 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6490 (unsigned long) sizes.mmap_bytes);
6491 }
6492
6493 // How much memory is being used by the Preprocessor?
6494 Preprocessor &pp = astUnit->getPreprocessor();
6495 createCXTUResourceUsageEntry(*entries,
6496 CXTUResourceUsage_Preprocessor,
6497 pp.getTotalMemory());
6498
6499 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6500 createCXTUResourceUsageEntry(*entries,
6501 CXTUResourceUsage_PreprocessingRecord,
6502 pRec->getTotalMemory());
6503 }
6504
6505 createCXTUResourceUsageEntry(*entries,
6506 CXTUResourceUsage_Preprocessor_HeaderSearch,
6507 pp.getHeaderSearchInfo().getTotalMemory());
6508
6509 CXTUResourceUsage usage = { (void*) entries.get(),
6510 (unsigned) entries->size(),
6511 entries->size() ? &(*entries)[0] : 0 };
6512 entries.take();
6513 return usage;
6514}
6515
6516void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6517 if (usage.data)
6518 delete (MemUsageEntries*) usage.data;
6519}
6520
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006521CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6522 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006523 skipped->count = 0;
6524 skipped->ranges = 0;
6525
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006526 if (isNotUseableTU(TU)) {
6527 LOG_BAD_TU(TU);
6528 return skipped;
6529 }
6530
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006531 if (!file)
6532 return skipped;
6533
6534 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6535 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6536 if (!ppRec)
6537 return skipped;
6538
6539 ASTContext &Ctx = astUnit->getASTContext();
6540 SourceManager &sm = Ctx.getSourceManager();
6541 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6542 FileID wantedFileID = sm.translateFile(fileEntry);
6543
6544 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6545 std::vector<SourceRange> wantedRanges;
6546 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6547 i != ei; ++i) {
6548 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6549 wantedRanges.push_back(*i);
6550 }
6551
6552 skipped->count = wantedRanges.size();
6553 skipped->ranges = new CXSourceRange[skipped->count];
6554 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6555 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6556
6557 return skipped;
6558}
6559
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006560void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6561 if (ranges) {
6562 delete[] ranges->ranges;
6563 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006564 }
6565}
6566
Guy Benyei11169dd2012-12-18 14:30:41 +00006567} // end extern "C"
6568
6569void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6570 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6571 for (unsigned I = 0; I != Usage.numEntries; ++I)
6572 fprintf(stderr, " %s: %lu\n",
6573 clang_getTUResourceUsageName(Usage.entries[I].kind),
6574 Usage.entries[I].amount);
6575
6576 clang_disposeCXTUResourceUsage(Usage);
6577}
6578
6579//===----------------------------------------------------------------------===//
6580// Misc. utility functions.
6581//===----------------------------------------------------------------------===//
6582
6583/// Default to using an 8 MB stack size on "safety" threads.
6584static unsigned SafetyStackThreadSize = 8 << 20;
6585
6586namespace clang {
6587
6588bool RunSafely(llvm::CrashRecoveryContext &CRC,
6589 void (*Fn)(void*), void *UserData,
6590 unsigned Size) {
6591 if (!Size)
6592 Size = GetSafetyThreadStackSize();
6593 if (Size)
6594 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6595 return CRC.RunSafely(Fn, UserData);
6596}
6597
6598unsigned GetSafetyThreadStackSize() {
6599 return SafetyStackThreadSize;
6600}
6601
6602void SetSafetyThreadStackSize(unsigned Value) {
6603 SafetyStackThreadSize = Value;
6604}
6605
6606}
6607
6608void clang::setThreadBackgroundPriority() {
6609 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6610 return;
6611
6612 // FIXME: Move to llvm/Support and make it cross-platform.
6613#ifdef __APPLE__
6614 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6615#endif
6616}
6617
6618void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6619 if (!Unit)
6620 return;
6621
6622 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6623 DEnd = Unit->stored_diag_end();
6624 D != DEnd; ++D) {
6625 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6626 CXString Msg = clang_formatDiagnostic(&Diag,
6627 clang_defaultDiagnosticDisplayOptions());
6628 fprintf(stderr, "%s\n", clang_getCString(Msg));
6629 clang_disposeString(Msg);
6630 }
6631#ifdef LLVM_ON_WIN32
6632 // On Windows, force a flush, since there may be multiple copies of
6633 // stderr and stdout in the file system, all with different buffers
6634 // but writing to the same device.
6635 fflush(stderr);
6636#endif
6637}
6638
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006639MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6640 SourceLocation MacroDefLoc,
6641 CXTranslationUnit TU){
6642 if (MacroDefLoc.isInvalid() || !TU)
6643 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006644 if (!II.hadMacroDefinition())
6645 return 0;
6646
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006647 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006648 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006649 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006650 if (MD) {
6651 for (MacroDirective::DefInfo
6652 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6653 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6654 return Def.getMacroInfo();
6655 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006656 }
6657
6658 return 0;
6659}
6660
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006661const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6662 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006663 if (!MacroDef || !TU)
6664 return 0;
6665 const IdentifierInfo *II = MacroDef->getName();
6666 if (!II)
6667 return 0;
6668
6669 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6670}
6671
6672MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6673 const Token &Tok,
6674 CXTranslationUnit TU) {
6675 if (!MI || !TU)
6676 return 0;
6677 if (Tok.isNot(tok::raw_identifier))
6678 return 0;
6679
6680 if (MI->getNumTokens() == 0)
6681 return 0;
6682 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6683 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006684 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006685
6686 // Check that the token is inside the definition and not its argument list.
6687 SourceManager &SM = Unit->getSourceManager();
6688 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6689 return 0;
6690 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6691 return 0;
6692
6693 Preprocessor &PP = Unit->getPreprocessor();
6694 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6695 if (!PPRec)
6696 return 0;
6697
6698 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6699 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6700 if (!II.hadMacroDefinition())
6701 return 0;
6702
6703 // Check that the identifier is not one of the macro arguments.
6704 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6705 return 0;
6706
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006707 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6708 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006709 return 0;
6710
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006711 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006712}
6713
6714MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6715 SourceLocation Loc,
6716 CXTranslationUnit TU) {
6717 if (Loc.isInvalid() || !MI || !TU)
6718 return 0;
6719
6720 if (MI->getNumTokens() == 0)
6721 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006722 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006723 Preprocessor &PP = Unit->getPreprocessor();
6724 if (!PP.getPreprocessingRecord())
6725 return 0;
6726 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6727 Token Tok;
6728 if (PP.getRawToken(Loc, Tok))
6729 return 0;
6730
6731 return checkForMacroInMacroDefinition(MI, Tok, TU);
6732}
6733
Guy Benyei11169dd2012-12-18 14:30:41 +00006734extern "C" {
6735
6736CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006737 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006738}
6739
6740} // end: extern "C"
6741
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006742Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6743 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006744 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006745 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006746 if (Unit->isMainFileAST())
6747 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006748 return *this;
6749 }
6750 }
6751
6752 LogOS << "<NULL TU>";
6753 return *this;
6754}
6755
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006756Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6757 *this << FE->getName();
6758 return *this;
6759}
6760
6761Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6762 CXString cursorName = clang_getCursorDisplayName(cursor);
6763 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6764 clang_disposeString(cursorName);
6765 return *this;
6766}
6767
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006768Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6769 CXFile File;
6770 unsigned Line, Column;
6771 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6772 CXString FileName = clang_getFileName(File);
6773 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6774 clang_disposeString(FileName);
6775 return *this;
6776}
6777
6778Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6779 CXSourceLocation BLoc = clang_getRangeStart(range);
6780 CXSourceLocation ELoc = clang_getRangeEnd(range);
6781
6782 CXFile BFile;
6783 unsigned BLine, BColumn;
6784 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6785
6786 CXFile EFile;
6787 unsigned ELine, EColumn;
6788 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6789
6790 CXString BFileName = clang_getFileName(BFile);
6791 if (BFile == EFile) {
6792 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6793 BLine, BColumn, ELine, EColumn);
6794 } else {
6795 CXString EFileName = clang_getFileName(EFile);
6796 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6797 BLine, BColumn)
6798 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6799 ELine, EColumn);
6800 clang_disposeString(EFileName);
6801 }
6802 clang_disposeString(BFileName);
6803 return *this;
6804}
6805
6806Logger &cxindex::Logger::operator<<(CXString Str) {
6807 *this << clang_getCString(Str);
6808 return *this;
6809}
6810
6811Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6812 LogOS << Fmt;
6813 return *this;
6814}
6815
6816cxindex::Logger::~Logger() {
6817 LogOS.flush();
6818
6819 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6820
6821 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6822
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006823 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006824 OS << "[libclang:" << Name << ':';
6825
6826 // FIXME: Portability.
6827#if HAVE_PTHREAD_H && __APPLE__
6828 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6829 OS << tid << ':';
6830#endif
6831
6832 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6833 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6834 OS << Msg.str() << '\n';
6835
6836 if (Trace) {
6837 llvm::sys::PrintStackTrace(stderr);
6838 OS << "--------------------------------------------------\n";
6839 }
6840}