blob: f3ab7360b53097e6bac8f80738cc8efd462d4560 [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
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 if (!TU)
2849 return CXSaveError_InvalidTU;
2850
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002851 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2853 if (!CXXUnit->hasSema())
2854 return CXSaveError_InvalidTU;
2855
2856 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2857
2858 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2859 getenv("LIBCLANG_NOTHREADS")) {
2860 clang_saveTranslationUnit_Impl(&STUI);
2861
2862 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2863 PrintLibclangResourceUsage(TU);
2864
2865 return STUI.result;
2866 }
2867
2868 // We have an AST that has invalid nodes due to compiler errors.
2869 // Use a crash recovery thread for protection.
2870
2871 llvm::CrashRecoveryContext CRC;
2872
2873 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2874 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2875 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2876 fprintf(stderr, " 'options' : %d,\n", options);
2877 fprintf(stderr, "}\n");
2878
2879 return CXSaveError_Unknown;
2880
2881 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2882 PrintLibclangResourceUsage(TU);
2883 }
2884
2885 return STUI.result;
2886}
2887
2888void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2889 if (CTUnit) {
2890 // If the translation unit has been marked as unsafe to free, just discard
2891 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002892 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002893 return;
2894
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002895 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002896 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2898 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002899 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 delete CTUnit;
2901 }
2902}
2903
2904unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2905 return CXReparse_None;
2906}
2907
2908struct ReparseTranslationUnitInfo {
2909 CXTranslationUnit TU;
2910 unsigned num_unsaved_files;
2911 struct CXUnsavedFile *unsaved_files;
2912 unsigned options;
2913 int result;
2914};
2915
2916static void clang_reparseTranslationUnit_Impl(void *UserData) {
2917 ReparseTranslationUnitInfo *RTUI =
2918 static_cast<ReparseTranslationUnitInfo*>(UserData);
2919 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002920 if (!TU)
2921 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002922
2923 // Reset the associated diagnostics.
2924 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2925 TU->Diagnostics = 0;
2926
2927 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2928 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2929 unsigned options = RTUI->options;
2930 (void) options;
2931 RTUI->result = 1;
2932
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002933 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002934 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2935 setThreadBackgroundPriority();
2936
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002937 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002938 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2939
2940 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2941 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2942
2943 // Recover resources if we crash before exiting this function.
2944 llvm::CrashRecoveryContextCleanupRegistrar<
2945 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2946
2947 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2948 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2949 const llvm::MemoryBuffer *Buffer
2950 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2951 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2952 Buffer));
2953 }
2954
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002955 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 RTUI->result = 0;
2957}
2958
2959int clang_reparseTranslationUnit(CXTranslationUnit TU,
2960 unsigned num_unsaved_files,
2961 struct CXUnsavedFile *unsaved_files,
2962 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002963 LOG_FUNC_SECTION {
2964 *Log << TU;
2965 }
2966
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2968 options, 0 };
2969
2970 if (getenv("LIBCLANG_NOTHREADS")) {
2971 clang_reparseTranslationUnit_Impl(&RTUI);
2972 return RTUI.result;
2973 }
2974
2975 llvm::CrashRecoveryContext CRC;
2976
2977 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2978 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002979 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002980 return 1;
2981 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2982 PrintLibclangResourceUsage(TU);
2983
2984 return RTUI.result;
2985}
2986
2987
2988CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2989 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002990 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00002991
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002992 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00002993 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00002994}
2995
2996CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00002997 if (!TU)
2998 return clang_getNullCursor();
2999
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003000 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3002}
3003
3004} // end: extern "C"
3005
3006//===----------------------------------------------------------------------===//
3007// CXFile Operations.
3008//===----------------------------------------------------------------------===//
3009
3010extern "C" {
3011CXString clang_getFileName(CXFile SFile) {
3012 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003013 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003014
3015 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003016 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003017}
3018
3019time_t clang_getFileTime(CXFile SFile) {
3020 if (!SFile)
3021 return 0;
3022
3023 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3024 return FEnt->getModificationTime();
3025}
3026
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003027CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3028 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 return 0;
3030
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003031 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003032
3033 FileManager &FMgr = CXXUnit->getFileManager();
3034 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3035}
3036
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003037unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3038 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003039 return 0;
3040
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003041 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 FileEntry *FEnt = static_cast<FileEntry *>(file);
3043 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3044 .isFileMultipleIncludeGuarded(FEnt);
3045}
3046
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003047int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3048 if (!file || !outID)
3049 return 1;
3050
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003051 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003052 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3053 outID->data[0] = ID.getDevice();
3054 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003055 outID->data[2] = FEnt->getModificationTime();
3056 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003057}
3058
Guy Benyei11169dd2012-12-18 14:30:41 +00003059} // end: extern "C"
3060
3061//===----------------------------------------------------------------------===//
3062// CXCursor Operations.
3063//===----------------------------------------------------------------------===//
3064
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003065static const Decl *getDeclFromExpr(const Stmt *E) {
3066 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 return getDeclFromExpr(CE->getSubExpr());
3068
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003069 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003071 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003073 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003075 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 if (PRE->isExplicitProperty())
3077 return PRE->getExplicitProperty();
3078 // It could be messaging both getter and setter as in:
3079 // ++myobj.myprop;
3080 // in which case prefer to associate the setter since it is less obvious
3081 // from inspecting the source that the setter is going to get called.
3082 if (PRE->isMessagingSetter())
3083 return PRE->getImplicitPropertySetter();
3084 return PRE->getImplicitPropertyGetter();
3085 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003086 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003087 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003088 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 if (Expr *Src = OVE->getSourceExpr())
3090 return getDeclFromExpr(Src);
3091
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003092 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003094 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 if (!CE->isElidable())
3096 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003097 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 return OME->getMethodDecl();
3099
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003100 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003102 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3104 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003105 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3107 isa<ParmVarDecl>(SizeOfPack->getPack()))
3108 return SizeOfPack->getPack();
3109
3110 return 0;
3111}
3112
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003113static SourceLocation getLocationFromExpr(const Expr *E) {
3114 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 return getLocationFromExpr(CE->getSubExpr());
3116
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003117 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003119 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003121 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003123 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003125 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003127 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return PropRef->getLocation();
3129
3130 return E->getLocStart();
3131}
3132
3133extern "C" {
3134
3135unsigned clang_visitChildren(CXCursor parent,
3136 CXCursorVisitor visitor,
3137 CXClientData client_data) {
3138 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3139 /*VisitPreprocessorLast=*/false);
3140 return CursorVis.VisitChildren(parent);
3141}
3142
3143#ifndef __has_feature
3144#define __has_feature(x) 0
3145#endif
3146#if __has_feature(blocks)
3147typedef enum CXChildVisitResult
3148 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3149
3150static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3151 CXClientData client_data) {
3152 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3153 return block(cursor, parent);
3154}
3155#else
3156// If we are compiled with a compiler that doesn't have native blocks support,
3157// define and call the block manually, so the
3158typedef struct _CXChildVisitResult
3159{
3160 void *isa;
3161 int flags;
3162 int reserved;
3163 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3164 CXCursor);
3165} *CXCursorVisitorBlock;
3166
3167static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3168 CXClientData client_data) {
3169 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3170 return block->invoke(block, cursor, parent);
3171}
3172#endif
3173
3174
3175unsigned clang_visitChildrenWithBlock(CXCursor parent,
3176 CXCursorVisitorBlock block) {
3177 return clang_visitChildren(parent, visitWithBlock, block);
3178}
3179
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003180static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003182 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const ObjCPropertyImplDecl *PropImpl =
3187 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003189 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003190
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003193 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003194
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003195 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 }
3197
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003198 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003199 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003200
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3203 // and returns different names. NamedDecl returns the class name and
3204 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003205 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003206
3207 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003208 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003209
3210 SmallString<1024> S;
3211 llvm::raw_svector_ostream os(S);
3212 ND->printName(os);
3213
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003214 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003215}
3216
3217CXString clang_getCursorSpelling(CXCursor C) {
3218 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003219 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003220
3221 if (clang_isReference(C.kind)) {
3222 switch (C.kind) {
3223 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003224 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003225 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003226 }
3227 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003228 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003229 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 }
3231 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003232 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003234 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 }
3236 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003237 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003238 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 }
3240 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003241 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 assert(Type && "Missing type decl");
3243
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003244 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 getAsString());
3246 }
3247 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003248 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 assert(Template && "Missing template decl");
3250
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003251 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 }
3253
3254 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003255 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 assert(NS && "Missing namespace decl");
3257
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003258 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 }
3260
3261 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003262 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 assert(Field && "Missing member decl");
3264
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003265 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 }
3267
3268 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003269 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 assert(Label && "Missing label");
3271
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003272 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 }
3274
3275 case CXCursor_OverloadedDeclRef: {
3276 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3278 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003279 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003280 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003283 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 OverloadedTemplateStorage *Ovl
3285 = Storage.get<OverloadedTemplateStorage*>();
3286 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003287 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003288 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 }
3290
3291 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003292 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 assert(Var && "Missing variable decl");
3294
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003295 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 }
3297
3298 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003299 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 }
3301 }
3302
3303 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003304 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 if (D)
3306 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003307 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 }
3309
3310 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003311 const Stmt *S = getCursorStmt(C);
3312 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003313 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003315 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
3317
3318 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003319 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 ->getNameStart());
3321
3322 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003323 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 ->getNameStart());
3325
3326 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003327 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
3329 if (clang_isDeclaration(C.kind))
3330 return getDeclSpelling(getCursorDecl(C));
3331
3332 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003333 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003334 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 }
3336
3337 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003338 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003339 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 }
3341
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003342 if (C.kind == CXCursor_PackedAttr) {
3343 return cxstring::createRef("packed");
3344 }
3345
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003346 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003347}
3348
3349CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3350 unsigned pieceIndex,
3351 unsigned options) {
3352 if (clang_Cursor_isNull(C))
3353 return clang_getNullRange();
3354
3355 ASTContext &Ctx = getCursorContext(C);
3356
3357 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003358 const Stmt *S = getCursorStmt(C);
3359 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 if (pieceIndex > 0)
3361 return clang_getNullRange();
3362 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3363 }
3364
3365 return clang_getNullRange();
3366 }
3367
3368 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003369 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3371 if (pieceIndex >= ME->getNumSelectorLocs())
3372 return clang_getNullRange();
3373 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3374 }
3375 }
3376
3377 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3378 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3381 if (pieceIndex >= MD->getNumSelectorLocs())
3382 return clang_getNullRange();
3383 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3384 }
3385 }
3386
3387 if (C.kind == CXCursor_ObjCCategoryDecl ||
3388 C.kind == CXCursor_ObjCCategoryImplDecl) {
3389 if (pieceIndex > 0)
3390 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003391 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3393 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003394 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3396 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3397 }
3398
3399 if (C.kind == CXCursor_ModuleImportDecl) {
3400 if (pieceIndex > 0)
3401 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003402 if (const ImportDecl *ImportD =
3403 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3405 if (!Locs.empty())
3406 return cxloc::translateSourceRange(Ctx,
3407 SourceRange(Locs.front(), Locs.back()));
3408 }
3409 return clang_getNullRange();
3410 }
3411
3412 // FIXME: A CXCursor_InclusionDirective should give the location of the
3413 // filename, but we don't keep track of this.
3414
3415 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3416 // but we don't keep track of this.
3417
3418 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3419 // but we don't keep track of this.
3420
3421 // Default handling, give the location of the cursor.
3422
3423 if (pieceIndex > 0)
3424 return clang_getNullRange();
3425
3426 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3427 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3428 return cxloc::translateSourceRange(Ctx, Loc);
3429}
3430
3431CXString clang_getCursorDisplayName(CXCursor C) {
3432 if (!clang_isDeclaration(C.kind))
3433 return clang_getCursorSpelling(C);
3434
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003437 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003438
3439 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 D = FunTmpl->getTemplatedDecl();
3442
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003443 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 SmallString<64> Str;
3445 llvm::raw_svector_ostream OS(Str);
3446 OS << *Function;
3447 if (Function->getPrimaryTemplate())
3448 OS << "<>";
3449 OS << "(";
3450 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3451 if (I)
3452 OS << ", ";
3453 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3454 }
3455
3456 if (Function->isVariadic()) {
3457 if (Function->getNumParams())
3458 OS << ", ";
3459 OS << "...";
3460 }
3461 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003462 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 }
3464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 SmallString<64> Str;
3467 llvm::raw_svector_ostream OS(Str);
3468 OS << *ClassTemplate;
3469 OS << "<";
3470 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3471 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3472 if (I)
3473 OS << ", ";
3474
3475 NamedDecl *Param = Params->getParam(I);
3476 if (Param->getIdentifier()) {
3477 OS << Param->getIdentifier()->getName();
3478 continue;
3479 }
3480
3481 // There is no parameter name, which makes this tricky. Try to come up
3482 // with something useful that isn't too long.
3483 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3484 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3485 else if (NonTypeTemplateParmDecl *NTTP
3486 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3487 OS << NTTP->getType().getAsString(Policy);
3488 else
3489 OS << "template<...> class";
3490 }
3491
3492 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003493 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 }
3495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3498 // If the type was explicitly written, use that.
3499 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003500 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003501
Benjamin Kramer9170e912013-02-22 15:46:01 +00003502 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 llvm::raw_svector_ostream OS(Str);
3504 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003505 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 ClassSpec->getTemplateArgs().data(),
3507 ClassSpec->getTemplateArgs().size(),
3508 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003509 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 }
3511
3512 return clang_getCursorSpelling(C);
3513}
3514
3515CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3516 switch (Kind) {
3517 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003518 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003520 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003522 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003524 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003528 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003530 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003536 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003540 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003546 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003564 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003568 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003572 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003576 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003580 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003586 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003588 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003592 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003596 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003598 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003600 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003604 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003606 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003608 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003645 case CXCursor_ObjCSelfExpr:
3646 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003763 case CXCursor_PackedAttr:
3764 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003813 case CXCursor_OMPParallelDirective:
3814 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 }
3816
3817 llvm_unreachable("Unhandled CXCursorKind");
3818}
3819
3820struct GetCursorData {
3821 SourceLocation TokenBeginLoc;
3822 bool PointsAtMacroArgExpansion;
3823 bool VisitedObjCPropertyImplDecl;
3824 SourceLocation VisitedDeclaratorDeclStartLoc;
3825 CXCursor &BestCursor;
3826
3827 GetCursorData(SourceManager &SM,
3828 SourceLocation tokenBegin, CXCursor &outputCursor)
3829 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3830 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3831 VisitedObjCPropertyImplDecl = false;
3832 }
3833};
3834
3835static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3836 CXCursor parent,
3837 CXClientData client_data) {
3838 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3839 CXCursor *BestCursor = &Data->BestCursor;
3840
3841 // If we point inside a macro argument we should provide info of what the
3842 // token is so use the actual cursor, don't replace it with a macro expansion
3843 // cursor.
3844 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3845 return CXChildVisit_Recurse;
3846
3847 if (clang_isDeclaration(cursor.kind)) {
3848 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003849 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3851 if (MD->isImplicit())
3852 return CXChildVisit_Break;
3853
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003854 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3856 // Check that when we have multiple @class references in the same line,
3857 // that later ones do not override the previous ones.
3858 // If we have:
3859 // @class Foo, Bar;
3860 // source ranges for both start at '@', so 'Bar' will end up overriding
3861 // 'Foo' even though the cursor location was at 'Foo'.
3862 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3863 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003864 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3866 if (PrevID != ID &&
3867 !PrevID->isThisDeclarationADefinition() &&
3868 !ID->isThisDeclarationADefinition())
3869 return CXChildVisit_Break;
3870 }
3871
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003872 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3874 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3875 // Check that when we have multiple declarators in the same line,
3876 // that later ones do not override the previous ones.
3877 // If we have:
3878 // int Foo, Bar;
3879 // source ranges for both start at 'int', so 'Bar' will end up overriding
3880 // 'Foo' even though the cursor location was at 'Foo'.
3881 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3882 return CXChildVisit_Break;
3883 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3884
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003885 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3887 (void)PropImp;
3888 // Check that when we have multiple @synthesize in the same line,
3889 // that later ones do not override the previous ones.
3890 // If we have:
3891 // @synthesize Foo, Bar;
3892 // source ranges for both start at '@', so 'Bar' will end up overriding
3893 // 'Foo' even though the cursor location was at 'Foo'.
3894 if (Data->VisitedObjCPropertyImplDecl)
3895 return CXChildVisit_Break;
3896 Data->VisitedObjCPropertyImplDecl = true;
3897 }
3898 }
3899
3900 if (clang_isExpression(cursor.kind) &&
3901 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 // Avoid having the cursor of an expression replace the declaration cursor
3904 // when the expression source range overlaps the declaration range.
3905 // This can happen for C++ constructor expressions whose range generally
3906 // include the variable declaration, e.g.:
3907 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3908 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3909 D->getLocation() == Data->TokenBeginLoc)
3910 return CXChildVisit_Break;
3911 }
3912 }
3913
3914 // If our current best cursor is the construction of a temporary object,
3915 // don't replace that cursor with a type reference, because we want
3916 // clang_getCursor() to point at the constructor.
3917 if (clang_isExpression(BestCursor->kind) &&
3918 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3919 cursor.kind == CXCursor_TypeRef) {
3920 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3921 // as having the actual point on the type reference.
3922 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3923 return CXChildVisit_Recurse;
3924 }
3925
3926 *BestCursor = cursor;
3927 return CXChildVisit_Recurse;
3928}
3929
3930CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3931 if (!TU)
3932 return clang_getNullCursor();
3933
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003934 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3936
3937 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3938 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3939
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003940 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 CXFile SearchFile;
3942 unsigned SearchLine, SearchColumn;
3943 CXFile ResultFile;
3944 unsigned ResultLine, ResultColumn;
3945 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3946 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3947 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3948
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003949 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3950 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 &ResultColumn, 0);
3952 SearchFileName = clang_getFileName(SearchFile);
3953 ResultFileName = clang_getFileName(ResultFile);
3954 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3955 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003956 *Log << llvm::format("(%s:%d:%d) = %s",
3957 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3958 clang_getCString(KindSpelling))
3959 << llvm::format("(%s:%d:%d):%s%s",
3960 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3961 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 clang_disposeString(SearchFileName);
3963 clang_disposeString(ResultFileName);
3964 clang_disposeString(KindSpelling);
3965 clang_disposeString(USR);
3966
3967 CXCursor Definition = clang_getCursorDefinition(Result);
3968 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3969 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3970 CXString DefinitionKindSpelling
3971 = clang_getCursorKindSpelling(Definition.kind);
3972 CXFile DefinitionFile;
3973 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003974 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 &DefinitionLine, &DefinitionColumn, 0);
3976 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003977 *Log << llvm::format(" -> %s(%s:%d:%d)",
3978 clang_getCString(DefinitionKindSpelling),
3979 clang_getCString(DefinitionFileName),
3980 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 clang_disposeString(DefinitionFileName);
3982 clang_disposeString(DefinitionKindSpelling);
3983 }
3984 }
3985
3986 return Result;
3987}
3988
3989CXCursor clang_getNullCursor(void) {
3990 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3991}
3992
3993unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00003994 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3995 // can't set consistently. For example, when visiting a DeclStmt we will set
3996 // it but we don't set it on the result of clang_getCursorDefinition for
3997 // a reference of the same declaration.
3998 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3999 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4000 // to provide that kind of info.
4001 if (clang_isDeclaration(X.kind))
4002 X.data[1] = 0;
4003 if (clang_isDeclaration(Y.kind))
4004 Y.data[1] = 0;
4005
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 return X == Y;
4007}
4008
4009unsigned clang_hashCursor(CXCursor C) {
4010 unsigned Index = 0;
4011 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4012 Index = 1;
4013
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004014 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 std::make_pair(C.kind, C.data[Index]));
4016}
4017
4018unsigned clang_isInvalid(enum CXCursorKind K) {
4019 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4020}
4021
4022unsigned clang_isDeclaration(enum CXCursorKind K) {
4023 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4024 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4025}
4026
4027unsigned clang_isReference(enum CXCursorKind K) {
4028 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4029}
4030
4031unsigned clang_isExpression(enum CXCursorKind K) {
4032 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4033}
4034
4035unsigned clang_isStatement(enum CXCursorKind K) {
4036 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4037}
4038
4039unsigned clang_isAttribute(enum CXCursorKind K) {
4040 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4041}
4042
4043unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4044 return K == CXCursor_TranslationUnit;
4045}
4046
4047unsigned clang_isPreprocessing(enum CXCursorKind K) {
4048 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4049}
4050
4051unsigned clang_isUnexposed(enum CXCursorKind K) {
4052 switch (K) {
4053 case CXCursor_UnexposedDecl:
4054 case CXCursor_UnexposedExpr:
4055 case CXCursor_UnexposedStmt:
4056 case CXCursor_UnexposedAttr:
4057 return true;
4058 default:
4059 return false;
4060 }
4061}
4062
4063CXCursorKind clang_getCursorKind(CXCursor C) {
4064 return C.kind;
4065}
4066
4067CXSourceLocation clang_getCursorLocation(CXCursor C) {
4068 if (clang_isReference(C.kind)) {
4069 switch (C.kind) {
4070 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004071 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 = getCursorObjCSuperClassRef(C);
4073 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4074 }
4075
4076 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004077 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 = getCursorObjCProtocolRef(C);
4079 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4080 }
4081
4082 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004083 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 = getCursorObjCClassRef(C);
4085 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4086 }
4087
4088 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004089 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4091 }
4092
4093 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004094 std::pair<const TemplateDecl *, SourceLocation> P =
4095 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4097 }
4098
4099 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004100 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4102 }
4103
4104 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004105 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4107 }
4108
4109 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004110 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4112 }
4113
4114 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004115 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 if (!BaseSpec)
4117 return clang_getNullLocation();
4118
4119 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4120 return cxloc::translateSourceLocation(getCursorContext(C),
4121 TSInfo->getTypeLoc().getBeginLoc());
4122
4123 return cxloc::translateSourceLocation(getCursorContext(C),
4124 BaseSpec->getLocStart());
4125 }
4126
4127 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004128 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4130 }
4131
4132 case CXCursor_OverloadedDeclRef:
4133 return cxloc::translateSourceLocation(getCursorContext(C),
4134 getCursorOverloadedDeclRef(C).second);
4135
4136 default:
4137 // FIXME: Need a way to enumerate all non-reference cases.
4138 llvm_unreachable("Missed a reference kind");
4139 }
4140 }
4141
4142 if (clang_isExpression(C.kind))
4143 return cxloc::translateSourceLocation(getCursorContext(C),
4144 getLocationFromExpr(getCursorExpr(C)));
4145
4146 if (clang_isStatement(C.kind))
4147 return cxloc::translateSourceLocation(getCursorContext(C),
4148 getCursorStmt(C)->getLocStart());
4149
4150 if (C.kind == CXCursor_PreprocessingDirective) {
4151 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4152 return cxloc::translateSourceLocation(getCursorContext(C), L);
4153 }
4154
4155 if (C.kind == CXCursor_MacroExpansion) {
4156 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004157 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 return cxloc::translateSourceLocation(getCursorContext(C), L);
4159 }
4160
4161 if (C.kind == CXCursor_MacroDefinition) {
4162 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4163 return cxloc::translateSourceLocation(getCursorContext(C), L);
4164 }
4165
4166 if (C.kind == CXCursor_InclusionDirective) {
4167 SourceLocation L
4168 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4169 return cxloc::translateSourceLocation(getCursorContext(C), L);
4170 }
4171
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004172 if (clang_isAttribute(C.kind)) {
4173 SourceLocation L
4174 = cxcursor::getCursorAttr(C)->getLocation();
4175 return cxloc::translateSourceLocation(getCursorContext(C), L);
4176 }
4177
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 if (!clang_isDeclaration(C.kind))
4179 return clang_getNullLocation();
4180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004181 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 if (!D)
4183 return clang_getNullLocation();
4184
4185 SourceLocation Loc = D->getLocation();
4186 // FIXME: Multiple variables declared in a single declaration
4187 // currently lack the information needed to correctly determine their
4188 // ranges when accounting for the type-specifier. We use context
4189 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4190 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004191 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 if (!cxcursor::isFirstInDeclGroup(C))
4193 Loc = VD->getLocation();
4194 }
4195
4196 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004197 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 Loc = MD->getSelectorStartLoc();
4199
4200 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4201}
4202
4203} // end extern "C"
4204
4205CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4206 assert(TU);
4207
4208 // Guard against an invalid SourceLocation, or we may assert in one
4209 // of the following calls.
4210 if (SLoc.isInvalid())
4211 return clang_getNullCursor();
4212
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004213 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004214
4215 // Translate the given source location to make it point at the beginning of
4216 // the token under the cursor.
4217 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4218 CXXUnit->getASTContext().getLangOpts());
4219
4220 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4221 if (SLoc.isValid()) {
4222 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4223 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4224 /*VisitPreprocessorLast=*/true,
4225 /*VisitIncludedEntities=*/false,
4226 SourceLocation(SLoc));
4227 CursorVis.visitFileRegion();
4228 }
4229
4230 return Result;
4231}
4232
4233static SourceRange getRawCursorExtent(CXCursor C) {
4234 if (clang_isReference(C.kind)) {
4235 switch (C.kind) {
4236 case CXCursor_ObjCSuperClassRef:
4237 return getCursorObjCSuperClassRef(C).second;
4238
4239 case CXCursor_ObjCProtocolRef:
4240 return getCursorObjCProtocolRef(C).second;
4241
4242 case CXCursor_ObjCClassRef:
4243 return getCursorObjCClassRef(C).second;
4244
4245 case CXCursor_TypeRef:
4246 return getCursorTypeRef(C).second;
4247
4248 case CXCursor_TemplateRef:
4249 return getCursorTemplateRef(C).second;
4250
4251 case CXCursor_NamespaceRef:
4252 return getCursorNamespaceRef(C).second;
4253
4254 case CXCursor_MemberRef:
4255 return getCursorMemberRef(C).second;
4256
4257 case CXCursor_CXXBaseSpecifier:
4258 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4259
4260 case CXCursor_LabelRef:
4261 return getCursorLabelRef(C).second;
4262
4263 case CXCursor_OverloadedDeclRef:
4264 return getCursorOverloadedDeclRef(C).second;
4265
4266 case CXCursor_VariableRef:
4267 return getCursorVariableRef(C).second;
4268
4269 default:
4270 // FIXME: Need a way to enumerate all non-reference cases.
4271 llvm_unreachable("Missed a reference kind");
4272 }
4273 }
4274
4275 if (clang_isExpression(C.kind))
4276 return getCursorExpr(C)->getSourceRange();
4277
4278 if (clang_isStatement(C.kind))
4279 return getCursorStmt(C)->getSourceRange();
4280
4281 if (clang_isAttribute(C.kind))
4282 return getCursorAttr(C)->getRange();
4283
4284 if (C.kind == CXCursor_PreprocessingDirective)
4285 return cxcursor::getCursorPreprocessingDirective(C);
4286
4287 if (C.kind == CXCursor_MacroExpansion) {
4288 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004289 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 return TU->mapRangeFromPreamble(Range);
4291 }
4292
4293 if (C.kind == CXCursor_MacroDefinition) {
4294 ASTUnit *TU = getCursorASTUnit(C);
4295 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4296 return TU->mapRangeFromPreamble(Range);
4297 }
4298
4299 if (C.kind == CXCursor_InclusionDirective) {
4300 ASTUnit *TU = getCursorASTUnit(C);
4301 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4302 return TU->mapRangeFromPreamble(Range);
4303 }
4304
4305 if (C.kind == CXCursor_TranslationUnit) {
4306 ASTUnit *TU = getCursorASTUnit(C);
4307 FileID MainID = TU->getSourceManager().getMainFileID();
4308 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4309 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4310 return SourceRange(Start, End);
4311 }
4312
4313 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 if (!D)
4316 return SourceRange();
4317
4318 SourceRange R = D->getSourceRange();
4319 // FIXME: Multiple variables declared in a single declaration
4320 // currently lack the information needed to correctly determine their
4321 // ranges when accounting for the type-specifier. We use context
4322 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4323 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004324 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 if (!cxcursor::isFirstInDeclGroup(C))
4326 R.setBegin(VD->getLocation());
4327 }
4328 return R;
4329 }
4330 return SourceRange();
4331}
4332
4333/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4334/// the decl-specifier-seq for declarations.
4335static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4336 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004337 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 if (!D)
4339 return SourceRange();
4340
4341 SourceRange R = D->getSourceRange();
4342
4343 // Adjust the start of the location for declarations preceded by
4344 // declaration specifiers.
4345 SourceLocation StartLoc;
4346 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4347 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4348 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004349 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4351 StartLoc = TI->getTypeLoc().getLocStart();
4352 }
4353
4354 if (StartLoc.isValid() && R.getBegin().isValid() &&
4355 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4356 R.setBegin(StartLoc);
4357
4358 // FIXME: Multiple variables declared in a single declaration
4359 // currently lack the information needed to correctly determine their
4360 // ranges when accounting for the type-specifier. We use context
4361 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4362 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004363 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 if (!cxcursor::isFirstInDeclGroup(C))
4365 R.setBegin(VD->getLocation());
4366 }
4367
4368 return R;
4369 }
4370
4371 return getRawCursorExtent(C);
4372}
4373
4374extern "C" {
4375
4376CXSourceRange clang_getCursorExtent(CXCursor C) {
4377 SourceRange R = getRawCursorExtent(C);
4378 if (R.isInvalid())
4379 return clang_getNullRange();
4380
4381 return cxloc::translateSourceRange(getCursorContext(C), R);
4382}
4383
4384CXCursor clang_getCursorReferenced(CXCursor C) {
4385 if (clang_isInvalid(C.kind))
4386 return clang_getNullCursor();
4387
4388 CXTranslationUnit tu = getCursorTU(C);
4389 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004390 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 if (!D)
4392 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004393 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004395 if (const ObjCPropertyImplDecl *PropImpl =
4396 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4398 return MakeCXCursor(Property, tu);
4399
4400 return C;
4401 }
4402
4403 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004404 const Expr *E = getCursorExpr(C);
4405 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 if (D) {
4407 CXCursor declCursor = MakeCXCursor(D, tu);
4408 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4409 declCursor);
4410 return declCursor;
4411 }
4412
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004413 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 return MakeCursorOverloadedDeclRef(Ovl, tu);
4415
4416 return clang_getNullCursor();
4417 }
4418
4419 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004420 const Stmt *S = getCursorStmt(C);
4421 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 if (LabelDecl *label = Goto->getLabel())
4423 if (LabelStmt *labelS = label->getStmt())
4424 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4425
4426 return clang_getNullCursor();
4427 }
4428
4429 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004430 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 return MakeMacroDefinitionCursor(Def, tu);
4432 }
4433
4434 if (!clang_isReference(C.kind))
4435 return clang_getNullCursor();
4436
4437 switch (C.kind) {
4438 case CXCursor_ObjCSuperClassRef:
4439 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4440
4441 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004442 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4443 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 return MakeCXCursor(Def, tu);
4445
4446 return MakeCXCursor(Prot, tu);
4447 }
4448
4449 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004450 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4451 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 return MakeCXCursor(Def, tu);
4453
4454 return MakeCXCursor(Class, tu);
4455 }
4456
4457 case CXCursor_TypeRef:
4458 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4459
4460 case CXCursor_TemplateRef:
4461 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4462
4463 case CXCursor_NamespaceRef:
4464 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4465
4466 case CXCursor_MemberRef:
4467 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4468
4469 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004470 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4472 tu ));
4473 }
4474
4475 case CXCursor_LabelRef:
4476 // FIXME: We end up faking the "parent" declaration here because we
4477 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004478 return MakeCXCursor(getCursorLabelRef(C).first,
4479 cxtu::getASTUnit(tu)->getASTContext()
4480 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 tu);
4482
4483 case CXCursor_OverloadedDeclRef:
4484 return C;
4485
4486 case CXCursor_VariableRef:
4487 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4488
4489 default:
4490 // We would prefer to enumerate all non-reference cursor kinds here.
4491 llvm_unreachable("Unhandled reference cursor kind");
4492 }
4493}
4494
4495CXCursor clang_getCursorDefinition(CXCursor C) {
4496 if (clang_isInvalid(C.kind))
4497 return clang_getNullCursor();
4498
4499 CXTranslationUnit TU = getCursorTU(C);
4500
4501 bool WasReference = false;
4502 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4503 C = clang_getCursorReferenced(C);
4504 WasReference = true;
4505 }
4506
4507 if (C.kind == CXCursor_MacroExpansion)
4508 return clang_getCursorReferenced(C);
4509
4510 if (!clang_isDeclaration(C.kind))
4511 return clang_getNullCursor();
4512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 if (!D)
4515 return clang_getNullCursor();
4516
4517 switch (D->getKind()) {
4518 // Declaration kinds that don't really separate the notions of
4519 // declaration and definition.
4520 case Decl::Namespace:
4521 case Decl::Typedef:
4522 case Decl::TypeAlias:
4523 case Decl::TypeAliasTemplate:
4524 case Decl::TemplateTypeParm:
4525 case Decl::EnumConstant:
4526 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004527 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 case Decl::IndirectField:
4529 case Decl::ObjCIvar:
4530 case Decl::ObjCAtDefsField:
4531 case Decl::ImplicitParam:
4532 case Decl::ParmVar:
4533 case Decl::NonTypeTemplateParm:
4534 case Decl::TemplateTemplateParm:
4535 case Decl::ObjCCategoryImpl:
4536 case Decl::ObjCImplementation:
4537 case Decl::AccessSpec:
4538 case Decl::LinkageSpec:
4539 case Decl::ObjCPropertyImpl:
4540 case Decl::FileScopeAsm:
4541 case Decl::StaticAssert:
4542 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004543 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 case Decl::Label: // FIXME: Is this right??
4545 case Decl::ClassScopeFunctionSpecialization:
4546 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004547 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 return C;
4549
4550 // Declaration kinds that don't make any sense here, but are
4551 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004552 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case Decl::TranslationUnit:
4554 break;
4555
4556 // Declaration kinds for which the definition is not resolvable.
4557 case Decl::UnresolvedUsingTypename:
4558 case Decl::UnresolvedUsingValue:
4559 break;
4560
4561 case Decl::UsingDirective:
4562 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4563 TU);
4564
4565 case Decl::NamespaceAlias:
4566 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4567
4568 case Decl::Enum:
4569 case Decl::Record:
4570 case Decl::CXXRecord:
4571 case Decl::ClassTemplateSpecialization:
4572 case Decl::ClassTemplatePartialSpecialization:
4573 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4574 return MakeCXCursor(Def, TU);
4575 return clang_getNullCursor();
4576
4577 case Decl::Function:
4578 case Decl::CXXMethod:
4579 case Decl::CXXConstructor:
4580 case Decl::CXXDestructor:
4581 case Decl::CXXConversion: {
4582 const FunctionDecl *Def = 0;
4583 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004584 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 return clang_getNullCursor();
4586 }
4587
Larisse Voufo39a1e502013-08-06 01:03:05 +00004588 case Decl::Var:
4589 case Decl::VarTemplateSpecialization:
4590 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004592 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 return MakeCXCursor(Def, TU);
4594 return clang_getNullCursor();
4595 }
4596
4597 case Decl::FunctionTemplate: {
4598 const FunctionDecl *Def = 0;
4599 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4600 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4601 return clang_getNullCursor();
4602 }
4603
4604 case Decl::ClassTemplate: {
4605 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4606 ->getDefinition())
4607 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4608 TU);
4609 return clang_getNullCursor();
4610 }
4611
Larisse Voufo39a1e502013-08-06 01:03:05 +00004612 case Decl::VarTemplate: {
4613 if (VarDecl *Def =
4614 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4615 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4616 return clang_getNullCursor();
4617 }
4618
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case Decl::Using:
4620 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4621 D->getLocation(), TU);
4622
4623 case Decl::UsingShadow:
4624 return clang_getCursorDefinition(
4625 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4626 TU));
4627
4628 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004629 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 if (Method->isThisDeclarationADefinition())
4631 return C;
4632
4633 // Dig out the method definition in the associated
4634 // @implementation, if we have it.
4635 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004636 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4638 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4639 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4640 Method->isInstanceMethod()))
4641 if (Def->isThisDeclarationADefinition())
4642 return MakeCXCursor(Def, TU);
4643
4644 return clang_getNullCursor();
4645 }
4646
4647 case Decl::ObjCCategory:
4648 if (ObjCCategoryImplDecl *Impl
4649 = cast<ObjCCategoryDecl>(D)->getImplementation())
4650 return MakeCXCursor(Impl, TU);
4651 return clang_getNullCursor();
4652
4653 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004654 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 return MakeCXCursor(Def, TU);
4656 return clang_getNullCursor();
4657
4658 case Decl::ObjCInterface: {
4659 // There are two notions of a "definition" for an Objective-C
4660 // class: the interface and its implementation. When we resolved a
4661 // reference to an Objective-C class, produce the @interface as
4662 // the definition; when we were provided with the interface,
4663 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004664 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004666 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 return MakeCXCursor(Def, TU);
4668 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4669 return MakeCXCursor(Impl, TU);
4670 return clang_getNullCursor();
4671 }
4672
4673 case Decl::ObjCProperty:
4674 // FIXME: We don't really know where to find the
4675 // ObjCPropertyImplDecls that implement this property.
4676 return clang_getNullCursor();
4677
4678 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004679 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004681 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 return MakeCXCursor(Def, TU);
4683
4684 return clang_getNullCursor();
4685
4686 case Decl::Friend:
4687 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4688 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4689 return clang_getNullCursor();
4690
4691 case Decl::FriendTemplate:
4692 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4693 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4694 return clang_getNullCursor();
4695 }
4696
4697 return clang_getNullCursor();
4698}
4699
4700unsigned clang_isCursorDefinition(CXCursor C) {
4701 if (!clang_isDeclaration(C.kind))
4702 return 0;
4703
4704 return clang_getCursorDefinition(C) == C;
4705}
4706
4707CXCursor clang_getCanonicalCursor(CXCursor C) {
4708 if (!clang_isDeclaration(C.kind))
4709 return C;
4710
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004711 if (const Decl *D = getCursorDecl(C)) {
4712 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4714 return MakeCXCursor(CatD, getCursorTU(C));
4715
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004716 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4717 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 return MakeCXCursor(IFD, getCursorTU(C));
4719
4720 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4721 }
4722
4723 return C;
4724}
4725
4726int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4727 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4728}
4729
4730unsigned clang_getNumOverloadedDecls(CXCursor C) {
4731 if (C.kind != CXCursor_OverloadedDeclRef)
4732 return 0;
4733
4734 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 return E->getNumDecls();
4737
4738 if (OverloadedTemplateStorage *S
4739 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4740 return S->size();
4741
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004742 const Decl *D = Storage.get<const Decl *>();
4743 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 return Using->shadow_size();
4745
4746 return 0;
4747}
4748
4749CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4750 if (cursor.kind != CXCursor_OverloadedDeclRef)
4751 return clang_getNullCursor();
4752
4753 if (index >= clang_getNumOverloadedDecls(cursor))
4754 return clang_getNullCursor();
4755
4756 CXTranslationUnit TU = getCursorTU(cursor);
4757 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004758 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 return MakeCXCursor(E->decls_begin()[index], TU);
4760
4761 if (OverloadedTemplateStorage *S
4762 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4763 return MakeCXCursor(S->begin()[index], TU);
4764
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004765 const Decl *D = Storage.get<const Decl *>();
4766 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 // FIXME: This is, unfortunately, linear time.
4768 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4769 std::advance(Pos, index);
4770 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4771 }
4772
4773 return clang_getNullCursor();
4774}
4775
4776void clang_getDefinitionSpellingAndExtent(CXCursor C,
4777 const char **startBuf,
4778 const char **endBuf,
4779 unsigned *startLine,
4780 unsigned *startColumn,
4781 unsigned *endLine,
4782 unsigned *endColumn) {
4783 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004784 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4786
4787 SourceManager &SM = FD->getASTContext().getSourceManager();
4788 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4789 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4790 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4791 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4792 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4793 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4794}
4795
4796
4797CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4798 unsigned PieceIndex) {
4799 RefNamePieces Pieces;
4800
4801 switch (C.kind) {
4802 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004803 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4805 E->getQualifierLoc().getSourceRange());
4806 break;
4807
4808 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004809 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4811 E->getQualifierLoc().getSourceRange(),
4812 E->getOptionalExplicitTemplateArgs());
4813 break;
4814
4815 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004816 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004818 const Expr *Callee = OCE->getCallee();
4819 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 Callee = ICE->getSubExpr();
4821
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004822 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4824 DRE->getQualifierLoc().getSourceRange());
4825 }
4826 break;
4827
4828 default:
4829 break;
4830 }
4831
4832 if (Pieces.empty()) {
4833 if (PieceIndex == 0)
4834 return clang_getCursorExtent(C);
4835 } else if (PieceIndex < Pieces.size()) {
4836 SourceRange R = Pieces[PieceIndex];
4837 if (R.isValid())
4838 return cxloc::translateSourceRange(getCursorContext(C), R);
4839 }
4840
4841 return clang_getNullRange();
4842}
4843
4844void clang_enableStackTraces(void) {
4845 llvm::sys::PrintStackTraceOnErrorSignal();
4846}
4847
4848void clang_executeOnThread(void (*fn)(void*), void *user_data,
4849 unsigned stack_size) {
4850 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4851}
4852
4853} // end: extern "C"
4854
4855//===----------------------------------------------------------------------===//
4856// Token-based Operations.
4857//===----------------------------------------------------------------------===//
4858
4859/* CXToken layout:
4860 * int_data[0]: a CXTokenKind
4861 * int_data[1]: starting token location
4862 * int_data[2]: token length
4863 * int_data[3]: reserved
4864 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4865 * otherwise unused.
4866 */
4867extern "C" {
4868
4869CXTokenKind clang_getTokenKind(CXToken CXTok) {
4870 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4871}
4872
4873CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4874 switch (clang_getTokenKind(CXTok)) {
4875 case CXToken_Identifier:
4876 case CXToken_Keyword:
4877 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004878 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 ->getNameStart());
4880
4881 case CXToken_Literal: {
4882 // We have stashed the starting pointer in the ptr_data field. Use it.
4883 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004884 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 }
4886
4887 case CXToken_Punctuation:
4888 case CXToken_Comment:
4889 break;
4890 }
4891
4892 // We have to find the starting buffer pointer the hard way, by
4893 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004894 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004896 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004897
4898 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4899 std::pair<FileID, unsigned> LocInfo
4900 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4901 bool Invalid = false;
4902 StringRef Buffer
4903 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4904 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004905 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004906
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004907 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004908}
4909
4910CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004911 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 if (!CXXUnit)
4913 return clang_getNullLocation();
4914
4915 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4916 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4917}
4918
4919CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004920 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 if (!CXXUnit)
4922 return clang_getNullRange();
4923
4924 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4925 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4926}
4927
4928static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4929 SmallVectorImpl<CXToken> &CXTokens) {
4930 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4931 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004932 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004933 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004934 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004935
4936 // Cannot tokenize across files.
4937 if (BeginLocInfo.first != EndLocInfo.first)
4938 return;
4939
4940 // Create a lexer
4941 bool Invalid = false;
4942 StringRef Buffer
4943 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4944 if (Invalid)
4945 return;
4946
4947 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4948 CXXUnit->getASTContext().getLangOpts(),
4949 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4950 Lex.SetCommentRetentionState(true);
4951
4952 // Lex tokens until we hit the end of the range.
4953 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4954 Token Tok;
4955 bool previousWasAt = false;
4956 do {
4957 // Lex the next token
4958 Lex.LexFromRawLexer(Tok);
4959 if (Tok.is(tok::eof))
4960 break;
4961
4962 // Initialize the CXToken.
4963 CXToken CXTok;
4964
4965 // - Common fields
4966 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4967 CXTok.int_data[2] = Tok.getLength();
4968 CXTok.int_data[3] = 0;
4969
4970 // - Kind-specific fields
4971 if (Tok.isLiteral()) {
4972 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004973 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 } else if (Tok.is(tok::raw_identifier)) {
4975 // Lookup the identifier to determine whether we have a keyword.
4976 IdentifierInfo *II
4977 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4978
4979 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4980 CXTok.int_data[0] = CXToken_Keyword;
4981 }
4982 else {
4983 CXTok.int_data[0] = Tok.is(tok::identifier)
4984 ? CXToken_Identifier
4985 : CXToken_Keyword;
4986 }
4987 CXTok.ptr_data = II;
4988 } else if (Tok.is(tok::comment)) {
4989 CXTok.int_data[0] = CXToken_Comment;
4990 CXTok.ptr_data = 0;
4991 } else {
4992 CXTok.int_data[0] = CXToken_Punctuation;
4993 CXTok.ptr_data = 0;
4994 }
4995 CXTokens.push_back(CXTok);
4996 previousWasAt = Tok.is(tok::at);
4997 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4998}
4999
5000void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5001 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005002 LOG_FUNC_SECTION {
5003 *Log << TU << ' ' << Range;
5004 }
5005
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 if (Tokens)
5007 *Tokens = 0;
5008 if (NumTokens)
5009 *NumTokens = 0;
5010
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005011 if (!TU)
5012 return;
5013
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 if (!CXXUnit || !Tokens || !NumTokens)
5016 return;
5017
5018 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5019
5020 SourceRange R = cxloc::translateCXSourceRange(Range);
5021 if (R.isInvalid())
5022 return;
5023
5024 SmallVector<CXToken, 32> CXTokens;
5025 getTokens(CXXUnit, R, CXTokens);
5026
5027 if (CXTokens.empty())
5028 return;
5029
5030 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5031 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5032 *NumTokens = CXTokens.size();
5033}
5034
5035void clang_disposeTokens(CXTranslationUnit TU,
5036 CXToken *Tokens, unsigned NumTokens) {
5037 free(Tokens);
5038}
5039
5040} // end: extern "C"
5041
5042//===----------------------------------------------------------------------===//
5043// Token annotation APIs.
5044//===----------------------------------------------------------------------===//
5045
Guy Benyei11169dd2012-12-18 14:30:41 +00005046static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5047 CXCursor parent,
5048 CXClientData client_data);
5049static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5050 CXClientData client_data);
5051
5052namespace {
5053class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 CXToken *Tokens;
5055 CXCursor *Cursors;
5056 unsigned NumTokens;
5057 unsigned TokIdx;
5058 unsigned PreprocessingTokIdx;
5059 CursorVisitor AnnotateVis;
5060 SourceManager &SrcMgr;
5061 bool HasContextSensitiveKeywords;
5062
5063 struct PostChildrenInfo {
5064 CXCursor Cursor;
5065 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005066 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 unsigned BeforeChildrenTokenIdx;
5068 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005069 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005070
5071 CXToken &getTok(unsigned Idx) {
5072 assert(Idx < NumTokens);
5073 return Tokens[Idx];
5074 }
5075 const CXToken &getTok(unsigned Idx) const {
5076 assert(Idx < NumTokens);
5077 return Tokens[Idx];
5078 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 bool MoreTokens() const { return TokIdx < NumTokens; }
5080 unsigned NextToken() const { return TokIdx; }
5081 void AdvanceToken() { ++TokIdx; }
5082 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005083 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 }
5085 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005086 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 }
5088 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005089 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 }
5091
5092 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005093 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 SourceRange);
5095
5096public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005097 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005098 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005099 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005101 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 AnnotateTokensVisitor, this,
5103 /*VisitPreprocessorLast=*/true,
5104 /*VisitIncludedEntities=*/false,
5105 RegionOfInterest,
5106 /*VisitDeclsOnly=*/false,
5107 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005108 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 HasContextSensitiveKeywords(false) { }
5110
5111 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5112 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5113 bool postVisitChildren(CXCursor cursor);
5114 void AnnotateTokens();
5115
5116 /// \brief Determine whether the annotator saw any cursors that have
5117 /// context-sensitive keywords.
5118 bool hasContextSensitiveKeywords() const {
5119 return HasContextSensitiveKeywords;
5120 }
5121
5122 ~AnnotateTokensWorker() {
5123 assert(PostChildrenInfos.empty());
5124 }
5125};
5126}
5127
5128void AnnotateTokensWorker::AnnotateTokens() {
5129 // Walk the AST within the region of interest, annotating tokens
5130 // along the way.
5131 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005132}
Guy Benyei11169dd2012-12-18 14:30:41 +00005133
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005134static inline void updateCursorAnnotation(CXCursor &Cursor,
5135 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005136 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005138 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005139}
5140
5141/// \brief It annotates and advances tokens with a cursor until the comparison
5142//// between the cursor location and the source range is the same as
5143/// \arg compResult.
5144///
5145/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5146/// Pass RangeOverlap to annotate tokens inside a range.
5147void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5148 RangeComparisonResult compResult,
5149 SourceRange range) {
5150 while (MoreTokens()) {
5151 const unsigned I = NextToken();
5152 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005153 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5154 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005155
5156 SourceLocation TokLoc = GetTokenLoc(I);
5157 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005158 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 AdvanceToken();
5160 continue;
5161 }
5162 break;
5163 }
5164}
5165
5166/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005167/// \returns true if it advanced beyond all macro tokens, false otherwise.
5168bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 CXCursor updateC,
5170 RangeComparisonResult compResult,
5171 SourceRange range) {
5172 assert(MoreTokens());
5173 assert(isFunctionMacroToken(NextToken()) &&
5174 "Should be called only for macro arg tokens");
5175
5176 // This works differently than annotateAndAdvanceTokens; because expanded
5177 // macro arguments can have arbitrary translation-unit source order, we do not
5178 // advance the token index one by one until a token fails the range test.
5179 // We only advance once past all of the macro arg tokens if all of them
5180 // pass the range test. If one of them fails we keep the token index pointing
5181 // at the start of the macro arg tokens so that the failing token will be
5182 // annotated by a subsequent annotation try.
5183
5184 bool atLeastOneCompFail = false;
5185
5186 unsigned I = NextToken();
5187 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5188 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5189 if (TokLoc.isFileID())
5190 continue; // not macro arg token, it's parens or comma.
5191 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5192 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5193 Cursors[I] = updateC;
5194 } else
5195 atLeastOneCompFail = true;
5196 }
5197
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005198 if (atLeastOneCompFail)
5199 return false;
5200
5201 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5202 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005203}
5204
5205enum CXChildVisitResult
5206AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 SourceRange cursorRange = getRawCursorExtent(cursor);
5208 if (cursorRange.isInvalid())
5209 return CXChildVisit_Recurse;
5210
5211 if (!HasContextSensitiveKeywords) {
5212 // Objective-C properties can have context-sensitive keywords.
5213 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005214 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5216 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5217 }
5218 // Objective-C methods can have context-sensitive keywords.
5219 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5220 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005221 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5223 if (Method->getObjCDeclQualifier())
5224 HasContextSensitiveKeywords = true;
5225 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005226 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5227 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 P != PEnd; ++P) {
5229 if ((*P)->getObjCDeclQualifier()) {
5230 HasContextSensitiveKeywords = true;
5231 break;
5232 }
5233 }
5234 }
5235 }
5236 }
5237 // C++ methods can have context-sensitive keywords.
5238 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005239 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5241 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5242 HasContextSensitiveKeywords = true;
5243 }
5244 }
5245 // C++ classes can have context-sensitive keywords.
5246 else if (cursor.kind == CXCursor_StructDecl ||
5247 cursor.kind == CXCursor_ClassDecl ||
5248 cursor.kind == CXCursor_ClassTemplate ||
5249 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005250 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005251 if (D->hasAttr<FinalAttr>())
5252 HasContextSensitiveKeywords = true;
5253 }
5254 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005255
5256 // Don't override a property annotation with its getter/setter method.
5257 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5258 parent.kind == CXCursor_ObjCPropertyDecl)
5259 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005260
5261 if (clang_isPreprocessing(cursor.kind)) {
5262 // Items in the preprocessing record are kept separate from items in
5263 // declarations, so we keep a separate token index.
5264 unsigned SavedTokIdx = TokIdx;
5265 TokIdx = PreprocessingTokIdx;
5266
5267 // Skip tokens up until we catch up to the beginning of the preprocessing
5268 // entry.
5269 while (MoreTokens()) {
5270 const unsigned I = NextToken();
5271 SourceLocation TokLoc = GetTokenLoc(I);
5272 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5273 case RangeBefore:
5274 AdvanceToken();
5275 continue;
5276 case RangeAfter:
5277 case RangeOverlap:
5278 break;
5279 }
5280 break;
5281 }
5282
5283 // Look at all of the tokens within this range.
5284 while (MoreTokens()) {
5285 const unsigned I = NextToken();
5286 SourceLocation TokLoc = GetTokenLoc(I);
5287 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5288 case RangeBefore:
5289 llvm_unreachable("Infeasible");
5290 case RangeAfter:
5291 break;
5292 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005293 // For macro expansions, just note where the beginning of the macro
5294 // expansion occurs.
5295 if (cursor.kind == CXCursor_MacroExpansion) {
5296 if (TokLoc == cursorRange.getBegin())
5297 Cursors[I] = cursor;
5298 AdvanceToken();
5299 break;
5300 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005301 // We may have already annotated macro names inside macro definitions.
5302 if (Cursors[I].kind != CXCursor_MacroExpansion)
5303 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 continue;
5306 }
5307 break;
5308 }
5309
5310 // Save the preprocessing token index; restore the non-preprocessing
5311 // token index.
5312 PreprocessingTokIdx = TokIdx;
5313 TokIdx = SavedTokIdx;
5314 return CXChildVisit_Recurse;
5315 }
5316
5317 if (cursorRange.isInvalid())
5318 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005319
5320 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 const enum CXCursorKind K = clang_getCursorKind(parent);
5323 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005324 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5325 // Attributes are annotated out-of-order, skip tokens until we reach it.
5326 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 ? clang_getNullCursor() : parent;
5328
5329 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5330
5331 // Avoid having the cursor of an expression "overwrite" the annotation of the
5332 // variable declaration that it belongs to.
5333 // This can happen for C++ constructor expressions whose range generally
5334 // include the variable declaration, e.g.:
5335 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005336 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005337 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005338 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 const unsigned I = NextToken();
5340 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5341 E->getLocStart() == D->getLocation() &&
5342 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005343 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 AdvanceToken();
5345 }
5346 }
5347 }
5348
5349 // Before recursing into the children keep some state that we are going
5350 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5351 // extra work after the child nodes are visited.
5352 // Note that we don't call VisitChildren here to avoid traversing statements
5353 // code-recursively which can blow the stack.
5354
5355 PostChildrenInfo Info;
5356 Info.Cursor = cursor;
5357 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005358 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 Info.BeforeChildrenTokenIdx = NextToken();
5360 PostChildrenInfos.push_back(Info);
5361
5362 return CXChildVisit_Recurse;
5363}
5364
5365bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5366 if (PostChildrenInfos.empty())
5367 return false;
5368 const PostChildrenInfo &Info = PostChildrenInfos.back();
5369 if (!clang_equalCursors(Info.Cursor, cursor))
5370 return false;
5371
5372 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5373 const unsigned AfterChildren = NextToken();
5374 SourceRange cursorRange = Info.CursorRange;
5375
5376 // Scan the tokens that are at the end of the cursor, but are not captured
5377 // but the child cursors.
5378 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5379
5380 // Scan the tokens that are at the beginning of the cursor, but are not
5381 // capture by the child cursors.
5382 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5383 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5384 break;
5385
5386 Cursors[I] = cursor;
5387 }
5388
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005389 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5390 // encountered the attribute cursor.
5391 if (clang_isAttribute(cursor.kind))
5392 TokIdx = Info.BeforeReachingCursorIdx;
5393
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 PostChildrenInfos.pop_back();
5395 return false;
5396}
5397
5398static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5399 CXCursor parent,
5400 CXClientData client_data) {
5401 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5402}
5403
5404static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5405 CXClientData client_data) {
5406 return static_cast<AnnotateTokensWorker*>(client_data)->
5407 postVisitChildren(cursor);
5408}
5409
5410namespace {
5411
5412/// \brief Uses the macro expansions in the preprocessing record to find
5413/// and mark tokens that are macro arguments. This info is used by the
5414/// AnnotateTokensWorker.
5415class MarkMacroArgTokensVisitor {
5416 SourceManager &SM;
5417 CXToken *Tokens;
5418 unsigned NumTokens;
5419 unsigned CurIdx;
5420
5421public:
5422 MarkMacroArgTokensVisitor(SourceManager &SM,
5423 CXToken *tokens, unsigned numTokens)
5424 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5425
5426 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5427 if (cursor.kind != CXCursor_MacroExpansion)
5428 return CXChildVisit_Continue;
5429
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005430 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 if (macroRange.getBegin() == macroRange.getEnd())
5432 return CXChildVisit_Continue; // it's not a function macro.
5433
5434 for (; CurIdx < NumTokens; ++CurIdx) {
5435 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5436 macroRange.getBegin()))
5437 break;
5438 }
5439
5440 if (CurIdx == NumTokens)
5441 return CXChildVisit_Break;
5442
5443 for (; CurIdx < NumTokens; ++CurIdx) {
5444 SourceLocation tokLoc = getTokenLoc(CurIdx);
5445 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5446 break;
5447
5448 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5449 }
5450
5451 if (CurIdx == NumTokens)
5452 return CXChildVisit_Break;
5453
5454 return CXChildVisit_Continue;
5455 }
5456
5457private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005458 CXToken &getTok(unsigned Idx) {
5459 assert(Idx < NumTokens);
5460 return Tokens[Idx];
5461 }
5462 const CXToken &getTok(unsigned Idx) const {
5463 assert(Idx < NumTokens);
5464 return Tokens[Idx];
5465 }
5466
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005468 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 }
5470
5471 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5472 // The third field is reserved and currently not used. Use it here
5473 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005474 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 }
5476};
5477
5478} // end anonymous namespace
5479
5480static CXChildVisitResult
5481MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5482 CXClientData client_data) {
5483 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5484 parent);
5485}
5486
5487namespace {
5488 struct clang_annotateTokens_Data {
5489 CXTranslationUnit TU;
5490 ASTUnit *CXXUnit;
5491 CXToken *Tokens;
5492 unsigned NumTokens;
5493 CXCursor *Cursors;
5494 };
5495}
5496
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005497/// \brief Used by \c annotatePreprocessorTokens.
5498/// \returns true if lexing was finished, false otherwise.
5499static bool lexNext(Lexer &Lex, Token &Tok,
5500 unsigned &NextIdx, unsigned NumTokens) {
5501 if (NextIdx >= NumTokens)
5502 return true;
5503
5504 ++NextIdx;
5505 Lex.LexFromRawLexer(Tok);
5506 if (Tok.is(tok::eof))
5507 return true;
5508
5509 return false;
5510}
5511
Guy Benyei11169dd2012-12-18 14:30:41 +00005512static void annotatePreprocessorTokens(CXTranslationUnit TU,
5513 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005514 CXCursor *Cursors,
5515 CXToken *Tokens,
5516 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005517 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005518
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005519 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5521 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005522 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005524 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005525
5526 if (BeginLocInfo.first != EndLocInfo.first)
5527 return;
5528
5529 StringRef Buffer;
5530 bool Invalid = false;
5531 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5532 if (Buffer.empty() || Invalid)
5533 return;
5534
5535 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5536 CXXUnit->getASTContext().getLangOpts(),
5537 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5538 Buffer.end());
5539 Lex.SetCommentRetentionState(true);
5540
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005541 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 // Lex tokens in raw mode until we hit the end of the range, to avoid
5543 // entering #includes or expanding macros.
5544 while (true) {
5545 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005546 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5547 break;
5548 unsigned TokIdx = NextIdx-1;
5549 assert(Tok.getLocation() ==
5550 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005551
5552 reprocess:
5553 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005554 // We have found a preprocessing directive. Annotate the tokens
5555 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 //
5557 // FIXME: Some simple tests here could identify macro definitions and
5558 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005559
5560 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005561 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5562 break;
5563
5564 MacroInfo *MI = 0;
5565 if (Tok.is(tok::raw_identifier) &&
5566 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5567 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5568 break;
5569
5570 if (Tok.is(tok::raw_identifier)) {
5571 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5572 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5573 SourceLocation MappedTokLoc =
5574 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5575 MI = getMacroInfo(II, MappedTokLoc, TU);
5576 }
5577 }
5578
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005579 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005581 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5582 finished = true;
5583 break;
5584 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005585 // If we are in a macro definition, check if the token was ever a
5586 // macro name and annotate it if that's the case.
5587 if (MI) {
5588 SourceLocation SaveLoc = Tok.getLocation();
5589 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5590 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5591 Tok.setLocation(SaveLoc);
5592 if (MacroDef)
5593 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5594 Tok.getLocation(), TU);
5595 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005596 } while (!Tok.isAtStartOfLine());
5597
5598 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5599 assert(TokIdx <= LastIdx);
5600 SourceLocation EndLoc =
5601 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5602 CXCursor Cursor =
5603 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5604
5605 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005606 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005607
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005608 if (finished)
5609 break;
5610 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005612 }
5613}
5614
5615// This gets run a separate thread to avoid stack blowout.
5616static void clang_annotateTokensImpl(void *UserData) {
5617 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5618 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5619 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5620 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5621 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5622
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005623 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5625 setThreadBackgroundPriority();
5626
5627 // Determine the region of interest, which contains all of the tokens.
5628 SourceRange RegionOfInterest;
5629 RegionOfInterest.setBegin(
5630 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5631 RegionOfInterest.setEnd(
5632 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5633 Tokens[NumTokens-1])));
5634
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 // Relex the tokens within the source range to look for preprocessing
5636 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005637 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005638
5639 // If begin location points inside a macro argument, set it to the expansion
5640 // location so we can have the full context when annotating semantically.
5641 {
5642 SourceManager &SM = CXXUnit->getSourceManager();
5643 SourceLocation Loc =
5644 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5645 if (Loc.isMacroID())
5646 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5647 }
5648
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5650 // Search and mark tokens that are macro argument expansions.
5651 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5652 Tokens, NumTokens);
5653 CursorVisitor MacroArgMarker(TU,
5654 MarkMacroArgTokensVisitorDelegate, &Visitor,
5655 /*VisitPreprocessorLast=*/true,
5656 /*VisitIncludedEntities=*/false,
5657 RegionOfInterest);
5658 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5659 }
5660
5661 // Annotate all of the source locations in the region of interest that map to
5662 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005663 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005664
5665 // FIXME: We use a ridiculous stack size here because the data-recursion
5666 // algorithm uses a large stack frame than the non-data recursive version,
5667 // and AnnotationTokensWorker currently transforms the data-recursion
5668 // algorithm back into a traditional recursion by explicitly calling
5669 // VisitChildren(). We will need to remove this explicit recursive call.
5670 W.AnnotateTokens();
5671
5672 // If we ran into any entities that involve context-sensitive keywords,
5673 // take another pass through the tokens to mark them as such.
5674 if (W.hasContextSensitiveKeywords()) {
5675 for (unsigned I = 0; I != NumTokens; ++I) {
5676 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5677 continue;
5678
5679 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5680 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005681 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5683 if (Property->getPropertyAttributesAsWritten() != 0 &&
5684 llvm::StringSwitch<bool>(II->getName())
5685 .Case("readonly", true)
5686 .Case("assign", true)
5687 .Case("unsafe_unretained", true)
5688 .Case("readwrite", true)
5689 .Case("retain", true)
5690 .Case("copy", true)
5691 .Case("nonatomic", true)
5692 .Case("atomic", true)
5693 .Case("getter", true)
5694 .Case("setter", true)
5695 .Case("strong", true)
5696 .Case("weak", true)
5697 .Default(false))
5698 Tokens[I].int_data[0] = CXToken_Keyword;
5699 }
5700 continue;
5701 }
5702
5703 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5704 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5705 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5706 if (llvm::StringSwitch<bool>(II->getName())
5707 .Case("in", true)
5708 .Case("out", true)
5709 .Case("inout", true)
5710 .Case("oneway", true)
5711 .Case("bycopy", true)
5712 .Case("byref", true)
5713 .Default(false))
5714 Tokens[I].int_data[0] = CXToken_Keyword;
5715 continue;
5716 }
5717
5718 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5719 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5720 Tokens[I].int_data[0] = CXToken_Keyword;
5721 continue;
5722 }
5723 }
5724 }
5725}
5726
5727extern "C" {
5728
5729void clang_annotateTokens(CXTranslationUnit TU,
5730 CXToken *Tokens, unsigned NumTokens,
5731 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005732 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005733 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005735 }
5736
5737 LOG_FUNC_SECTION {
5738 *Log << TU << ' ';
5739 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5740 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5741 *Log << clang_getRange(bloc, eloc);
5742 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005743
5744 // Any token we don't specifically annotate will have a NULL cursor.
5745 CXCursor C = clang_getNullCursor();
5746 for (unsigned I = 0; I != NumTokens; ++I)
5747 Cursors[I] = C;
5748
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005749 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 if (!CXXUnit)
5751 return;
5752
5753 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5754
5755 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5756 llvm::CrashRecoveryContext CRC;
5757 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5758 GetSafetyThreadStackSize() * 2)) {
5759 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5760 }
5761}
5762
5763} // end: extern "C"
5764
5765//===----------------------------------------------------------------------===//
5766// Operations for querying linkage of a cursor.
5767//===----------------------------------------------------------------------===//
5768
5769extern "C" {
5770CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5771 if (!clang_isDeclaration(cursor.kind))
5772 return CXLinkage_Invalid;
5773
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005774 const Decl *D = cxcursor::getCursorDecl(cursor);
5775 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005776 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005777 case NoLinkage:
5778 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 case InternalLinkage: return CXLinkage_Internal;
5780 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5781 case ExternalLinkage: return CXLinkage_External;
5782 };
5783
5784 return CXLinkage_Invalid;
5785}
5786} // end: extern "C"
5787
5788//===----------------------------------------------------------------------===//
5789// Operations for querying language of a cursor.
5790//===----------------------------------------------------------------------===//
5791
5792static CXLanguageKind getDeclLanguage(const Decl *D) {
5793 if (!D)
5794 return CXLanguage_C;
5795
5796 switch (D->getKind()) {
5797 default:
5798 break;
5799 case Decl::ImplicitParam:
5800 case Decl::ObjCAtDefsField:
5801 case Decl::ObjCCategory:
5802 case Decl::ObjCCategoryImpl:
5803 case Decl::ObjCCompatibleAlias:
5804 case Decl::ObjCImplementation:
5805 case Decl::ObjCInterface:
5806 case Decl::ObjCIvar:
5807 case Decl::ObjCMethod:
5808 case Decl::ObjCProperty:
5809 case Decl::ObjCPropertyImpl:
5810 case Decl::ObjCProtocol:
5811 return CXLanguage_ObjC;
5812 case Decl::CXXConstructor:
5813 case Decl::CXXConversion:
5814 case Decl::CXXDestructor:
5815 case Decl::CXXMethod:
5816 case Decl::CXXRecord:
5817 case Decl::ClassTemplate:
5818 case Decl::ClassTemplatePartialSpecialization:
5819 case Decl::ClassTemplateSpecialization:
5820 case Decl::Friend:
5821 case Decl::FriendTemplate:
5822 case Decl::FunctionTemplate:
5823 case Decl::LinkageSpec:
5824 case Decl::Namespace:
5825 case Decl::NamespaceAlias:
5826 case Decl::NonTypeTemplateParm:
5827 case Decl::StaticAssert:
5828 case Decl::TemplateTemplateParm:
5829 case Decl::TemplateTypeParm:
5830 case Decl::UnresolvedUsingTypename:
5831 case Decl::UnresolvedUsingValue:
5832 case Decl::Using:
5833 case Decl::UsingDirective:
5834 case Decl::UsingShadow:
5835 return CXLanguage_CPlusPlus;
5836 }
5837
5838 return CXLanguage_C;
5839}
5840
5841extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005842
5843static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5844 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5845 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005846
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005847 switch (D->getAvailability()) {
5848 case AR_Available:
5849 case AR_NotYetIntroduced:
5850 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005851 return getCursorAvailabilityForDecl(
5852 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005853 return CXAvailability_Available;
5854
5855 case AR_Deprecated:
5856 return CXAvailability_Deprecated;
5857
5858 case AR_Unavailable:
5859 return CXAvailability_NotAvailable;
5860 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005861
5862 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005863}
5864
Guy Benyei11169dd2012-12-18 14:30:41 +00005865enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5866 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005867 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5868 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005869
5870 return CXAvailability_Available;
5871}
5872
5873static CXVersion convertVersion(VersionTuple In) {
5874 CXVersion Out = { -1, -1, -1 };
5875 if (In.empty())
5876 return Out;
5877
5878 Out.Major = In.getMajor();
5879
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005880 Optional<unsigned> Minor = In.getMinor();
5881 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 Out.Minor = *Minor;
5883 else
5884 return Out;
5885
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005886 Optional<unsigned> Subminor = In.getSubminor();
5887 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 Out.Subminor = *Subminor;
5889
5890 return Out;
5891}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005892
5893static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5894 int *always_deprecated,
5895 CXString *deprecated_message,
5896 int *always_unavailable,
5897 CXString *unavailable_message,
5898 CXPlatformAvailability *availability,
5899 int availability_size) {
5900 bool HadAvailAttr = false;
5901 int N = 0;
5902 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5903 ++A) {
5904 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5905 HadAvailAttr = true;
5906 if (always_deprecated)
5907 *always_deprecated = 1;
5908 if (deprecated_message)
5909 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5910 continue;
5911 }
5912
5913 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5914 HadAvailAttr = true;
5915 if (always_unavailable)
5916 *always_unavailable = 1;
5917 if (unavailable_message) {
5918 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5919 }
5920 continue;
5921 }
5922
5923 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5924 HadAvailAttr = true;
5925 if (N < availability_size) {
5926 availability[N].Platform
5927 = cxstring::createDup(Avail->getPlatform()->getName());
5928 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5929 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5930 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5931 availability[N].Unavailable = Avail->getUnavailable();
5932 availability[N].Message = cxstring::createDup(Avail->getMessage());
5933 }
5934 ++N;
5935 }
5936 }
5937
5938 if (!HadAvailAttr)
5939 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5940 return getCursorPlatformAvailabilityForDecl(
5941 cast<Decl>(EnumConst->getDeclContext()),
5942 always_deprecated,
5943 deprecated_message,
5944 always_unavailable,
5945 unavailable_message,
5946 availability,
5947 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005948
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005949 return N;
5950}
5951
Guy Benyei11169dd2012-12-18 14:30:41 +00005952int clang_getCursorPlatformAvailability(CXCursor cursor,
5953 int *always_deprecated,
5954 CXString *deprecated_message,
5955 int *always_unavailable,
5956 CXString *unavailable_message,
5957 CXPlatformAvailability *availability,
5958 int availability_size) {
5959 if (always_deprecated)
5960 *always_deprecated = 0;
5961 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005962 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 if (always_unavailable)
5964 *always_unavailable = 0;
5965 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005966 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005967
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 if (!clang_isDeclaration(cursor.kind))
5969 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005970
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005971 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 if (!D)
5973 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005974
5975 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5976 deprecated_message,
5977 always_unavailable,
5978 unavailable_message,
5979 availability,
5980 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005981}
5982
5983void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5984 clang_disposeString(availability->Platform);
5985 clang_disposeString(availability->Message);
5986}
5987
5988CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5989 if (clang_isDeclaration(cursor.kind))
5990 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5991
5992 return CXLanguage_Invalid;
5993}
5994
5995 /// \brief If the given cursor is the "templated" declaration
5996 /// descibing a class or function template, return the class or
5997 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005998static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005999 if (!D)
6000 return 0;
6001
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006002 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6004 return FunTmpl;
6005
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006006 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6008 return ClassTmpl;
6009
6010 return D;
6011}
6012
6013CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6014 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006015 if (const Decl *D = getCursorDecl(cursor)) {
6016 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 if (!DC)
6018 return clang_getNullCursor();
6019
6020 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6021 getCursorTU(cursor));
6022 }
6023 }
6024
6025 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006026 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006027 return MakeCXCursor(D, getCursorTU(cursor));
6028 }
6029
6030 return clang_getNullCursor();
6031}
6032
6033CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6034 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006035 if (const Decl *D = getCursorDecl(cursor)) {
6036 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006037 if (!DC)
6038 return clang_getNullCursor();
6039
6040 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6041 getCursorTU(cursor));
6042 }
6043 }
6044
6045 // FIXME: Note that we can't easily compute the lexical context of a
6046 // statement or expression, so we return nothing.
6047 return clang_getNullCursor();
6048}
6049
6050CXFile clang_getIncludedFile(CXCursor cursor) {
6051 if (cursor.kind != CXCursor_InclusionDirective)
6052 return 0;
6053
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006054 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006055 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006056}
6057
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006058unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6059 if (C.kind != CXCursor_ObjCPropertyDecl)
6060 return CXObjCPropertyAttr_noattr;
6061
6062 unsigned Result = CXObjCPropertyAttr_noattr;
6063 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6064 ObjCPropertyDecl::PropertyAttributeKind Attr =
6065 PD->getPropertyAttributesAsWritten();
6066
6067#define SET_CXOBJCPROP_ATTR(A) \
6068 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6069 Result |= CXObjCPropertyAttr_##A
6070 SET_CXOBJCPROP_ATTR(readonly);
6071 SET_CXOBJCPROP_ATTR(getter);
6072 SET_CXOBJCPROP_ATTR(assign);
6073 SET_CXOBJCPROP_ATTR(readwrite);
6074 SET_CXOBJCPROP_ATTR(retain);
6075 SET_CXOBJCPROP_ATTR(copy);
6076 SET_CXOBJCPROP_ATTR(nonatomic);
6077 SET_CXOBJCPROP_ATTR(setter);
6078 SET_CXOBJCPROP_ATTR(atomic);
6079 SET_CXOBJCPROP_ATTR(weak);
6080 SET_CXOBJCPROP_ATTR(strong);
6081 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6082#undef SET_CXOBJCPROP_ATTR
6083
6084 return Result;
6085}
6086
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006087unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6088 if (!clang_isDeclaration(C.kind))
6089 return CXObjCDeclQualifier_None;
6090
6091 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6092 const Decl *D = getCursorDecl(C);
6093 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6094 QT = MD->getObjCDeclQualifier();
6095 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6096 QT = PD->getObjCDeclQualifier();
6097 if (QT == Decl::OBJC_TQ_None)
6098 return CXObjCDeclQualifier_None;
6099
6100 unsigned Result = CXObjCDeclQualifier_None;
6101 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6102 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6103 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6104 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6105 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6106 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6107
6108 return Result;
6109}
6110
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006111unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6112 if (!clang_isDeclaration(C.kind))
6113 return 0;
6114
6115 const Decl *D = getCursorDecl(C);
6116 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6117 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6118 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6119 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6120
6121 return 0;
6122}
6123
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006124unsigned clang_Cursor_isVariadic(CXCursor C) {
6125 if (!clang_isDeclaration(C.kind))
6126 return 0;
6127
6128 const Decl *D = getCursorDecl(C);
6129 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6130 return FD->isVariadic();
6131 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6132 return MD->isVariadic();
6133
6134 return 0;
6135}
6136
Guy Benyei11169dd2012-12-18 14:30:41 +00006137CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6138 if (!clang_isDeclaration(C.kind))
6139 return clang_getNullRange();
6140
6141 const Decl *D = getCursorDecl(C);
6142 ASTContext &Context = getCursorContext(C);
6143 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6144 if (!RC)
6145 return clang_getNullRange();
6146
6147 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6148}
6149
6150CXString clang_Cursor_getRawCommentText(CXCursor C) {
6151 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006152 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153
6154 const Decl *D = getCursorDecl(C);
6155 ASTContext &Context = getCursorContext(C);
6156 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6157 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6158 StringRef();
6159
6160 // Don't duplicate the string because RawText points directly into source
6161 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006162 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006163}
6164
6165CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6166 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006167 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006168
6169 const Decl *D = getCursorDecl(C);
6170 const ASTContext &Context = getCursorContext(C);
6171 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6172
6173 if (RC) {
6174 StringRef BriefText = RC->getBriefText(Context);
6175
6176 // Don't duplicate the string because RawComment ensures that this memory
6177 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006178 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 }
6180
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006181 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006182}
6183
6184CXComment clang_Cursor_getParsedComment(CXCursor C) {
6185 if (!clang_isDeclaration(C.kind))
6186 return cxcomment::createCXComment(NULL, NULL);
6187
6188 const Decl *D = getCursorDecl(C);
6189 const ASTContext &Context = getCursorContext(C);
6190 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6191
6192 return cxcomment::createCXComment(FC, getCursorTU(C));
6193}
6194
6195CXModule clang_Cursor_getModule(CXCursor C) {
6196 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006197 if (const ImportDecl *ImportD =
6198 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 return ImportD->getImportedModule();
6200 }
6201
6202 return 0;
6203}
6204
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006205CXFile clang_Module_getASTFile(CXModule CXMod) {
6206 if (!CXMod)
6207 return 0;
6208 Module *Mod = static_cast<Module*>(CXMod);
6209 return const_cast<FileEntry *>(Mod->getASTFile());
6210}
6211
Guy Benyei11169dd2012-12-18 14:30:41 +00006212CXModule clang_Module_getParent(CXModule CXMod) {
6213 if (!CXMod)
6214 return 0;
6215 Module *Mod = static_cast<Module*>(CXMod);
6216 return Mod->Parent;
6217}
6218
6219CXString clang_Module_getName(CXModule CXMod) {
6220 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006221 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006223 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006224}
6225
6226CXString clang_Module_getFullName(CXModule CXMod) {
6227 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006228 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006229 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006230 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006231}
6232
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006233unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6234 CXModule CXMod) {
6235 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006236 return 0;
6237 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006238 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6239 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6240 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006241}
6242
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006243CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6244 CXModule CXMod, unsigned Index) {
6245 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 return 0;
6247 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006248 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006249
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006250 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6251 if (Index < TopHeaders.size())
6252 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006253
6254 return 0;
6255}
6256
6257} // end: extern "C"
6258
6259//===----------------------------------------------------------------------===//
6260// C++ AST instrospection.
6261//===----------------------------------------------------------------------===//
6262
6263extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006264unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6265 if (!clang_isDeclaration(C.kind))
6266 return 0;
6267
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006268 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006269 const CXXMethodDecl *Method =
6270 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006271 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6272}
6273
Guy Benyei11169dd2012-12-18 14:30:41 +00006274unsigned clang_CXXMethod_isStatic(CXCursor C) {
6275 if (!clang_isDeclaration(C.kind))
6276 return 0;
6277
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006278 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006279 const CXXMethodDecl *Method =
6280 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006281 return (Method && Method->isStatic()) ? 1 : 0;
6282}
6283
6284unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6285 if (!clang_isDeclaration(C.kind))
6286 return 0;
6287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006288 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006289 const CXXMethodDecl *Method =
6290 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 return (Method && Method->isVirtual()) ? 1 : 0;
6292}
6293} // end: extern "C"
6294
6295//===----------------------------------------------------------------------===//
6296// Attribute introspection.
6297//===----------------------------------------------------------------------===//
6298
6299extern "C" {
6300CXType clang_getIBOutletCollectionType(CXCursor C) {
6301 if (C.kind != CXCursor_IBOutletCollectionAttr)
6302 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6303
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006304 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006305 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6306
6307 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6308}
6309} // end: extern "C"
6310
6311//===----------------------------------------------------------------------===//
6312// Inspecting memory usage.
6313//===----------------------------------------------------------------------===//
6314
6315typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6316
6317static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6318 enum CXTUResourceUsageKind k,
6319 unsigned long amount) {
6320 CXTUResourceUsageEntry entry = { k, amount };
6321 entries.push_back(entry);
6322}
6323
6324extern "C" {
6325
6326const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6327 const char *str = "";
6328 switch (kind) {
6329 case CXTUResourceUsage_AST:
6330 str = "ASTContext: expressions, declarations, and types";
6331 break;
6332 case CXTUResourceUsage_Identifiers:
6333 str = "ASTContext: identifiers";
6334 break;
6335 case CXTUResourceUsage_Selectors:
6336 str = "ASTContext: selectors";
6337 break;
6338 case CXTUResourceUsage_GlobalCompletionResults:
6339 str = "Code completion: cached global results";
6340 break;
6341 case CXTUResourceUsage_SourceManagerContentCache:
6342 str = "SourceManager: content cache allocator";
6343 break;
6344 case CXTUResourceUsage_AST_SideTables:
6345 str = "ASTContext: side tables";
6346 break;
6347 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6348 str = "SourceManager: malloc'ed memory buffers";
6349 break;
6350 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6351 str = "SourceManager: mmap'ed memory buffers";
6352 break;
6353 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6354 str = "ExternalASTSource: malloc'ed memory buffers";
6355 break;
6356 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6357 str = "ExternalASTSource: mmap'ed memory buffers";
6358 break;
6359 case CXTUResourceUsage_Preprocessor:
6360 str = "Preprocessor: malloc'ed memory";
6361 break;
6362 case CXTUResourceUsage_PreprocessingRecord:
6363 str = "Preprocessor: PreprocessingRecord";
6364 break;
6365 case CXTUResourceUsage_SourceManager_DataStructures:
6366 str = "SourceManager: data structures and tables";
6367 break;
6368 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6369 str = "Preprocessor: header search tables";
6370 break;
6371 }
6372 return str;
6373}
6374
6375CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6376 if (!TU) {
6377 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6378 return usage;
6379 }
6380
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006381 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6383 ASTContext &astContext = astUnit->getASTContext();
6384
6385 // How much memory is used by AST nodes and types?
6386 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6387 (unsigned long) astContext.getASTAllocatedMemory());
6388
6389 // How much memory is used by identifiers?
6390 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6391 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6392
6393 // How much memory is used for selectors?
6394 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6395 (unsigned long) astContext.Selectors.getTotalMemory());
6396
6397 // How much memory is used by ASTContext's side tables?
6398 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6399 (unsigned long) astContext.getSideTableAllocatedMemory());
6400
6401 // How much memory is used for caching global code completion results?
6402 unsigned long completionBytes = 0;
6403 if (GlobalCodeCompletionAllocator *completionAllocator =
6404 astUnit->getCachedCompletionAllocator().getPtr()) {
6405 completionBytes = completionAllocator->getTotalMemory();
6406 }
6407 createCXTUResourceUsageEntry(*entries,
6408 CXTUResourceUsage_GlobalCompletionResults,
6409 completionBytes);
6410
6411 // How much memory is being used by SourceManager's content cache?
6412 createCXTUResourceUsageEntry(*entries,
6413 CXTUResourceUsage_SourceManagerContentCache,
6414 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6415
6416 // How much memory is being used by the MemoryBuffer's in SourceManager?
6417 const SourceManager::MemoryBufferSizes &srcBufs =
6418 astUnit->getSourceManager().getMemoryBufferSizes();
6419
6420 createCXTUResourceUsageEntry(*entries,
6421 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6422 (unsigned long) srcBufs.malloc_bytes);
6423 createCXTUResourceUsageEntry(*entries,
6424 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6425 (unsigned long) srcBufs.mmap_bytes);
6426 createCXTUResourceUsageEntry(*entries,
6427 CXTUResourceUsage_SourceManager_DataStructures,
6428 (unsigned long) astContext.getSourceManager()
6429 .getDataStructureSizes());
6430
6431 // How much memory is being used by the ExternalASTSource?
6432 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6433 const ExternalASTSource::MemoryBufferSizes &sizes =
6434 esrc->getMemoryBufferSizes();
6435
6436 createCXTUResourceUsageEntry(*entries,
6437 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6438 (unsigned long) sizes.malloc_bytes);
6439 createCXTUResourceUsageEntry(*entries,
6440 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6441 (unsigned long) sizes.mmap_bytes);
6442 }
6443
6444 // How much memory is being used by the Preprocessor?
6445 Preprocessor &pp = astUnit->getPreprocessor();
6446 createCXTUResourceUsageEntry(*entries,
6447 CXTUResourceUsage_Preprocessor,
6448 pp.getTotalMemory());
6449
6450 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6451 createCXTUResourceUsageEntry(*entries,
6452 CXTUResourceUsage_PreprocessingRecord,
6453 pRec->getTotalMemory());
6454 }
6455
6456 createCXTUResourceUsageEntry(*entries,
6457 CXTUResourceUsage_Preprocessor_HeaderSearch,
6458 pp.getHeaderSearchInfo().getTotalMemory());
6459
6460 CXTUResourceUsage usage = { (void*) entries.get(),
6461 (unsigned) entries->size(),
6462 entries->size() ? &(*entries)[0] : 0 };
6463 entries.take();
6464 return usage;
6465}
6466
6467void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6468 if (usage.data)
6469 delete (MemUsageEntries*) usage.data;
6470}
6471
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006472CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6473 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006474 skipped->count = 0;
6475 skipped->ranges = 0;
6476
6477 if (!file)
6478 return skipped;
6479
6480 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6481 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6482 if (!ppRec)
6483 return skipped;
6484
6485 ASTContext &Ctx = astUnit->getASTContext();
6486 SourceManager &sm = Ctx.getSourceManager();
6487 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6488 FileID wantedFileID = sm.translateFile(fileEntry);
6489
6490 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6491 std::vector<SourceRange> wantedRanges;
6492 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6493 i != ei; ++i) {
6494 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6495 wantedRanges.push_back(*i);
6496 }
6497
6498 skipped->count = wantedRanges.size();
6499 skipped->ranges = new CXSourceRange[skipped->count];
6500 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6501 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6502
6503 return skipped;
6504}
6505
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006506void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6507 if (ranges) {
6508 delete[] ranges->ranges;
6509 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006510 }
6511}
6512
Guy Benyei11169dd2012-12-18 14:30:41 +00006513} // end extern "C"
6514
6515void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6516 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6517 for (unsigned I = 0; I != Usage.numEntries; ++I)
6518 fprintf(stderr, " %s: %lu\n",
6519 clang_getTUResourceUsageName(Usage.entries[I].kind),
6520 Usage.entries[I].amount);
6521
6522 clang_disposeCXTUResourceUsage(Usage);
6523}
6524
6525//===----------------------------------------------------------------------===//
6526// Misc. utility functions.
6527//===----------------------------------------------------------------------===//
6528
6529/// Default to using an 8 MB stack size on "safety" threads.
6530static unsigned SafetyStackThreadSize = 8 << 20;
6531
6532namespace clang {
6533
6534bool RunSafely(llvm::CrashRecoveryContext &CRC,
6535 void (*Fn)(void*), void *UserData,
6536 unsigned Size) {
6537 if (!Size)
6538 Size = GetSafetyThreadStackSize();
6539 if (Size)
6540 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6541 return CRC.RunSafely(Fn, UserData);
6542}
6543
6544unsigned GetSafetyThreadStackSize() {
6545 return SafetyStackThreadSize;
6546}
6547
6548void SetSafetyThreadStackSize(unsigned Value) {
6549 SafetyStackThreadSize = Value;
6550}
6551
6552}
6553
6554void clang::setThreadBackgroundPriority() {
6555 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6556 return;
6557
6558 // FIXME: Move to llvm/Support and make it cross-platform.
6559#ifdef __APPLE__
6560 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6561#endif
6562}
6563
6564void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6565 if (!Unit)
6566 return;
6567
6568 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6569 DEnd = Unit->stored_diag_end();
6570 D != DEnd; ++D) {
6571 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6572 CXString Msg = clang_formatDiagnostic(&Diag,
6573 clang_defaultDiagnosticDisplayOptions());
6574 fprintf(stderr, "%s\n", clang_getCString(Msg));
6575 clang_disposeString(Msg);
6576 }
6577#ifdef LLVM_ON_WIN32
6578 // On Windows, force a flush, since there may be multiple copies of
6579 // stderr and stdout in the file system, all with different buffers
6580 // but writing to the same device.
6581 fflush(stderr);
6582#endif
6583}
6584
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006585MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6586 SourceLocation MacroDefLoc,
6587 CXTranslationUnit TU){
6588 if (MacroDefLoc.isInvalid() || !TU)
6589 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006590 if (!II.hadMacroDefinition())
6591 return 0;
6592
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006593 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006594 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006595 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006596 if (MD) {
6597 for (MacroDirective::DefInfo
6598 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6599 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6600 return Def.getMacroInfo();
6601 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006602 }
6603
6604 return 0;
6605}
6606
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006607const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6608 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006609 if (!MacroDef || !TU)
6610 return 0;
6611 const IdentifierInfo *II = MacroDef->getName();
6612 if (!II)
6613 return 0;
6614
6615 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6616}
6617
6618MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6619 const Token &Tok,
6620 CXTranslationUnit TU) {
6621 if (!MI || !TU)
6622 return 0;
6623 if (Tok.isNot(tok::raw_identifier))
6624 return 0;
6625
6626 if (MI->getNumTokens() == 0)
6627 return 0;
6628 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6629 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006630 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006631
6632 // Check that the token is inside the definition and not its argument list.
6633 SourceManager &SM = Unit->getSourceManager();
6634 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6635 return 0;
6636 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6637 return 0;
6638
6639 Preprocessor &PP = Unit->getPreprocessor();
6640 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6641 if (!PPRec)
6642 return 0;
6643
6644 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6645 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6646 if (!II.hadMacroDefinition())
6647 return 0;
6648
6649 // Check that the identifier is not one of the macro arguments.
6650 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6651 return 0;
6652
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006653 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6654 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006655 return 0;
6656
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006657 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006658}
6659
6660MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6661 SourceLocation Loc,
6662 CXTranslationUnit TU) {
6663 if (Loc.isInvalid() || !MI || !TU)
6664 return 0;
6665
6666 if (MI->getNumTokens() == 0)
6667 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006668 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006669 Preprocessor &PP = Unit->getPreprocessor();
6670 if (!PP.getPreprocessingRecord())
6671 return 0;
6672 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6673 Token Tok;
6674 if (PP.getRawToken(Loc, Tok))
6675 return 0;
6676
6677 return checkForMacroInMacroDefinition(MI, Tok, TU);
6678}
6679
Guy Benyei11169dd2012-12-18 14:30:41 +00006680extern "C" {
6681
6682CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006683 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006684}
6685
6686} // end: extern "C"
6687
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006688Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6689 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006690 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006691 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006692 if (Unit->isMainFileAST())
6693 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006694 return *this;
6695 }
6696 }
6697
6698 LogOS << "<NULL TU>";
6699 return *this;
6700}
6701
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006702Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6703 *this << FE->getName();
6704 return *this;
6705}
6706
6707Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6708 CXString cursorName = clang_getCursorDisplayName(cursor);
6709 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6710 clang_disposeString(cursorName);
6711 return *this;
6712}
6713
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006714Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6715 CXFile File;
6716 unsigned Line, Column;
6717 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6718 CXString FileName = clang_getFileName(File);
6719 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6720 clang_disposeString(FileName);
6721 return *this;
6722}
6723
6724Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6725 CXSourceLocation BLoc = clang_getRangeStart(range);
6726 CXSourceLocation ELoc = clang_getRangeEnd(range);
6727
6728 CXFile BFile;
6729 unsigned BLine, BColumn;
6730 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6731
6732 CXFile EFile;
6733 unsigned ELine, EColumn;
6734 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6735
6736 CXString BFileName = clang_getFileName(BFile);
6737 if (BFile == EFile) {
6738 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6739 BLine, BColumn, ELine, EColumn);
6740 } else {
6741 CXString EFileName = clang_getFileName(EFile);
6742 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6743 BLine, BColumn)
6744 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6745 ELine, EColumn);
6746 clang_disposeString(EFileName);
6747 }
6748 clang_disposeString(BFileName);
6749 return *this;
6750}
6751
6752Logger &cxindex::Logger::operator<<(CXString Str) {
6753 *this << clang_getCString(Str);
6754 return *this;
6755}
6756
6757Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6758 LogOS << Fmt;
6759 return *this;
6760}
6761
6762cxindex::Logger::~Logger() {
6763 LogOS.flush();
6764
6765 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6766
6767 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6768
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006769 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006770 OS << "[libclang:" << Name << ':';
6771
6772 // FIXME: Portability.
6773#if HAVE_PTHREAD_H && __APPLE__
6774 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6775 OS << tid << ':';
6776#endif
6777
6778 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6779 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6780 OS << Msg.str() << '\n';
6781
6782 if (Trace) {
6783 llvm::sys::PrintStackTrace(stderr);
6784 OS << "--------------------------------------------------\n";
6785 }
6786}