blob: 1af4e55e093825b7a2faba266b576903fd07526a [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.
782 if (VisitDeclarationNameInfo(ND->getNameInfo()))
783 return true;
784
785 // FIXME: Visit explicitly-specified template arguments!
786
787 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000788 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 return true;
790
Bill Wendling44426052012-12-20 19:22:21 +0000791 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000792 }
793
794 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
795 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
796 // Find the initializers that were written in the source.
797 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
798 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
799 IEnd = Constructor->init_end();
800 I != IEnd; ++I) {
801 if (!(*I)->isWritten())
802 continue;
803
804 WrittenInits.push_back(*I);
805 }
806
807 // Sort the initializers in source order
808 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
809 &CompareCXXCtorInitializers);
810
811 // Visit the initializers in source order
812 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
813 CXXCtorInitializer *Init = WrittenInits[I];
814 if (Init->isAnyMemberInitializer()) {
815 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
816 Init->getMemberLocation(), TU)))
817 return true;
818 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
819 if (Visit(TInfo->getTypeLoc()))
820 return true;
821 }
822
823 // Visit the initializer value.
824 if (Expr *Initializer = Init->getInit())
825 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
826 return true;
827 }
828 }
829
830 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
831 return true;
832 }
833
834 return false;
835}
836
837bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
838 if (VisitDeclaratorDecl(D))
839 return true;
840
841 if (Expr *BitWidth = D->getBitWidth())
842 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
843
844 return false;
845}
846
847bool CursorVisitor::VisitVarDecl(VarDecl *D) {
848 if (VisitDeclaratorDecl(D))
849 return true;
850
851 if (Expr *Init = D->getInit())
852 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
853
854 return false;
855}
856
857bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
858 if (VisitDeclaratorDecl(D))
859 return true;
860
861 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
862 if (Expr *DefArg = D->getDefaultArgument())
863 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
864
865 return false;
866}
867
868bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
869 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
870 // before visiting these template parameters.
871 if (VisitTemplateParameters(D->getTemplateParameters()))
872 return true;
873
874 return VisitFunctionDecl(D->getTemplatedDecl());
875}
876
877bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
878 // FIXME: Visit the "outer" template parameter lists on the TagDecl
879 // before visiting these template parameters.
880 if (VisitTemplateParameters(D->getTemplateParameters()))
881 return true;
882
883 return VisitCXXRecordDecl(D->getTemplatedDecl());
884}
885
886bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
887 if (VisitTemplateParameters(D->getTemplateParameters()))
888 return true;
889
890 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
891 VisitTemplateArgumentLoc(D->getDefaultArgument()))
892 return true;
893
894 return false;
895}
896
897bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000898 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000899 if (Visit(TSInfo->getTypeLoc()))
900 return true;
901
902 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
903 PEnd = ND->param_end();
904 P != PEnd; ++P) {
905 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
906 return true;
907 }
908
909 if (ND->isThisDeclarationADefinition() &&
910 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
911 return true;
912
913 return false;
914}
915
916template <typename DeclIt>
917static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
918 SourceManager &SM, SourceLocation EndLoc,
919 SmallVectorImpl<Decl *> &Decls) {
920 DeclIt next = *DI_current;
921 while (++next != DE_current) {
922 Decl *D_next = *next;
923 if (!D_next)
924 break;
925 SourceLocation L = D_next->getLocStart();
926 if (!L.isValid())
927 break;
928 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
929 *DI_current = next;
930 Decls.push_back(D_next);
931 continue;
932 }
933 break;
934 }
935}
936
937namespace {
938 struct ContainerDeclsSort {
939 SourceManager &SM;
940 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
941 bool operator()(Decl *A, Decl *B) {
942 SourceLocation L_A = A->getLocStart();
943 SourceLocation L_B = B->getLocStart();
944 assert(L_A.isValid() && L_B.isValid());
945 return SM.isBeforeInTranslationUnit(L_A, L_B);
946 }
947 };
948}
949
950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
981 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
982 I!=E; ++I) {
983 Decl *subDecl = *I;
984 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
985 subDecl->getLocStart().isInvalid())
986 continue;
987 DeclsInContainer.push_back(subDecl);
988 }
989
990 // Now sort the Decls so that they appear in lexical order.
991 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
992 ContainerDeclsSort(SM));
993
994 // Now visit the decls.
995 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
996 E = DeclsInContainer.end(); I != E; ++I) {
997 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +0000998 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000999 if (!V.hasValue())
1000 continue;
1001 if (!V.getValue())
1002 return false;
1003 if (Visit(Cursor, true))
1004 return true;
1005 }
1006 return false;
1007}
1008
1009bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1010 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1011 TU)))
1012 return true;
1013
1014 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1015 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1016 E = ND->protocol_end(); I != E; ++I, ++PL)
1017 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1018 return true;
1019
1020 return VisitObjCContainerDecl(ND);
1021}
1022
1023bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1024 if (!PID->isThisDeclarationADefinition())
1025 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1026
1027 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1028 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1029 E = PID->protocol_end(); I != E; ++I, ++PL)
1030 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1031 return true;
1032
1033 return VisitObjCContainerDecl(PID);
1034}
1035
1036bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1037 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1038 return true;
1039
1040 // FIXME: This implements a workaround with @property declarations also being
1041 // installed in the DeclContext for the @interface. Eventually this code
1042 // should be removed.
1043 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1044 if (!CDecl || !CDecl->IsClassExtension())
1045 return false;
1046
1047 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1048 if (!ID)
1049 return false;
1050
1051 IdentifierInfo *PropertyId = PD->getIdentifier();
1052 ObjCPropertyDecl *prevDecl =
1053 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1054
1055 if (!prevDecl)
1056 return false;
1057
1058 // Visit synthesized methods since they will be skipped when visiting
1059 // the @interface.
1060 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1061 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1062 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1063 return true;
1064
1065 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1066 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1067 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1068 return true;
1069
1070 return false;
1071}
1072
1073bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1074 if (!D->isThisDeclarationADefinition()) {
1075 // Forward declaration is treated like a reference.
1076 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1077 }
1078
1079 // Issue callbacks for super class.
1080 if (D->getSuperClass() &&
1081 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1082 D->getSuperClassLoc(),
1083 TU)))
1084 return true;
1085
1086 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1087 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1088 E = D->protocol_end(); I != E; ++I, ++PL)
1089 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1090 return true;
1091
1092 return VisitObjCContainerDecl(D);
1093}
1094
1095bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1096 return VisitObjCContainerDecl(D);
1097}
1098
1099bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1100 // 'ID' could be null when dealing with invalid code.
1101 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1102 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1103 return true;
1104
1105 return VisitObjCImplDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1109#if 0
1110 // Issue callbacks for super class.
1111 // FIXME: No source location information!
1112 if (D->getSuperClass() &&
1113 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1114 D->getSuperClassLoc(),
1115 TU)))
1116 return true;
1117#endif
1118
1119 return VisitObjCImplDecl(D);
1120}
1121
1122bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1123 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1124 if (PD->isIvarNameSpecified())
1125 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1126
1127 return false;
1128}
1129
1130bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1131 return VisitDeclContext(D);
1132}
1133
1134bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1135 // Visit nested-name-specifier.
1136 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1137 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1138 return true;
1139
1140 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1141 D->getTargetNameLoc(), TU));
1142}
1143
1144bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149 }
1150
1151 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1152 return true;
1153
1154 return VisitDeclarationNameInfo(D->getNameInfo());
1155}
1156
1157bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1158 // Visit nested-name-specifier.
1159 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1160 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1161 return true;
1162
1163 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1164 D->getIdentLocation(), TU));
1165}
1166
1167bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172 }
1173
1174 return VisitDeclarationNameInfo(D->getNameInfo());
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1178 UnresolvedUsingTypenameDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183
1184 return false;
1185}
1186
1187bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1188 switch (Name.getName().getNameKind()) {
1189 case clang::DeclarationName::Identifier:
1190 case clang::DeclarationName::CXXLiteralOperatorName:
1191 case clang::DeclarationName::CXXOperatorName:
1192 case clang::DeclarationName::CXXUsingDirective:
1193 return false;
1194
1195 case clang::DeclarationName::CXXConstructorName:
1196 case clang::DeclarationName::CXXDestructorName:
1197 case clang::DeclarationName::CXXConversionFunctionName:
1198 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1199 return Visit(TSInfo->getTypeLoc());
1200 return false;
1201
1202 case clang::DeclarationName::ObjCZeroArgSelector:
1203 case clang::DeclarationName::ObjCOneArgSelector:
1204 case clang::DeclarationName::ObjCMultiArgSelector:
1205 // FIXME: Per-identifier location info?
1206 return false;
1207 }
1208
1209 llvm_unreachable("Invalid DeclarationName::Kind!");
1210}
1211
1212bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1213 SourceRange Range) {
1214 // FIXME: This whole routine is a hack to work around the lack of proper
1215 // source information in nested-name-specifiers (PR5791). Since we do have
1216 // a beginning source location, we can visit the first component of the
1217 // nested-name-specifier, if it's a single-token component.
1218 if (!NNS)
1219 return false;
1220
1221 // Get the first component in the nested-name-specifier.
1222 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1223 NNS = Prefix;
1224
1225 switch (NNS->getKind()) {
1226 case NestedNameSpecifier::Namespace:
1227 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1228 TU));
1229
1230 case NestedNameSpecifier::NamespaceAlias:
1231 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1232 Range.getBegin(), TU));
1233
1234 case NestedNameSpecifier::TypeSpec: {
1235 // If the type has a form where we know that the beginning of the source
1236 // range matches up with a reference cursor. Visit the appropriate reference
1237 // cursor.
1238 const Type *T = NNS->getAsType();
1239 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1240 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1241 if (const TagType *Tag = dyn_cast<TagType>(T))
1242 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1243 if (const TemplateSpecializationType *TST
1244 = dyn_cast<TemplateSpecializationType>(T))
1245 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1246 break;
1247 }
1248
1249 case NestedNameSpecifier::TypeSpecWithTemplate:
1250 case NestedNameSpecifier::Global:
1251 case NestedNameSpecifier::Identifier:
1252 break;
1253 }
1254
1255 return false;
1256}
1257
1258bool
1259CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1260 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1261 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1262 Qualifiers.push_back(Qualifier);
1263
1264 while (!Qualifiers.empty()) {
1265 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1266 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1267 switch (NNS->getKind()) {
1268 case NestedNameSpecifier::Namespace:
1269 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1270 Q.getLocalBeginLoc(),
1271 TU)))
1272 return true;
1273
1274 break;
1275
1276 case NestedNameSpecifier::NamespaceAlias:
1277 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1278 Q.getLocalBeginLoc(),
1279 TU)))
1280 return true;
1281
1282 break;
1283
1284 case NestedNameSpecifier::TypeSpec:
1285 case NestedNameSpecifier::TypeSpecWithTemplate:
1286 if (Visit(Q.getTypeLoc()))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::Global:
1292 case NestedNameSpecifier::Identifier:
1293 break;
1294 }
1295 }
1296
1297 return false;
1298}
1299
1300bool CursorVisitor::VisitTemplateParameters(
1301 const TemplateParameterList *Params) {
1302 if (!Params)
1303 return false;
1304
1305 for (TemplateParameterList::const_iterator P = Params->begin(),
1306 PEnd = Params->end();
1307 P != PEnd; ++P) {
1308 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1309 return true;
1310 }
1311
1312 return false;
1313}
1314
1315bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1316 switch (Name.getKind()) {
1317 case TemplateName::Template:
1318 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1319
1320 case TemplateName::OverloadedTemplate:
1321 // Visit the overloaded template set.
1322 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1323 return true;
1324
1325 return false;
1326
1327 case TemplateName::DependentTemplate:
1328 // FIXME: Visit nested-name-specifier.
1329 return false;
1330
1331 case TemplateName::QualifiedTemplate:
1332 // FIXME: Visit nested-name-specifier.
1333 return Visit(MakeCursorTemplateRef(
1334 Name.getAsQualifiedTemplateName()->getDecl(),
1335 Loc, TU));
1336
1337 case TemplateName::SubstTemplateTemplateParm:
1338 return Visit(MakeCursorTemplateRef(
1339 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1340 Loc, TU));
1341
1342 case TemplateName::SubstTemplateTemplateParmPack:
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1345 Loc, TU));
1346 }
1347
1348 llvm_unreachable("Invalid TemplateName::Kind!");
1349}
1350
1351bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1352 switch (TAL.getArgument().getKind()) {
1353 case TemplateArgument::Null:
1354 case TemplateArgument::Integral:
1355 case TemplateArgument::Pack:
1356 return false;
1357
1358 case TemplateArgument::Type:
1359 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1360 return Visit(TSInfo->getTypeLoc());
1361 return false;
1362
1363 case TemplateArgument::Declaration:
1364 if (Expr *E = TAL.getSourceDeclExpression())
1365 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1366 return false;
1367
1368 case TemplateArgument::NullPtr:
1369 if (Expr *E = TAL.getSourceNullPtrExpression())
1370 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1371 return false;
1372
1373 case TemplateArgument::Expression:
1374 if (Expr *E = TAL.getSourceExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::Template:
1379 case TemplateArgument::TemplateExpansion:
1380 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1381 return true;
1382
1383 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1384 TAL.getTemplateNameLoc());
1385 }
1386
1387 llvm_unreachable("Invalid TemplateArgument::Kind!");
1388}
1389
1390bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1391 return VisitDeclContext(D);
1392}
1393
1394bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1395 return Visit(TL.getUnqualifiedLoc());
1396}
1397
1398bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1399 ASTContext &Context = AU->getASTContext();
1400
1401 // Some builtin types (such as Objective-C's "id", "sel", and
1402 // "Class") have associated declarations. Create cursors for those.
1403 QualType VisitType;
1404 switch (TL.getTypePtr()->getKind()) {
1405
1406 case BuiltinType::Void:
1407 case BuiltinType::NullPtr:
1408 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001409 case BuiltinType::OCLImage1d:
1410 case BuiltinType::OCLImage1dArray:
1411 case BuiltinType::OCLImage1dBuffer:
1412 case BuiltinType::OCLImage2d:
1413 case BuiltinType::OCLImage2dArray:
1414 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001415 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001416 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001417#define BUILTIN_TYPE(Id, SingletonId)
1418#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1419#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1420#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#include "clang/AST/BuiltinTypes.def"
1423 break;
1424
1425 case BuiltinType::ObjCId:
1426 VisitType = Context.getObjCIdType();
1427 break;
1428
1429 case BuiltinType::ObjCClass:
1430 VisitType = Context.getObjCClassType();
1431 break;
1432
1433 case BuiltinType::ObjCSel:
1434 VisitType = Context.getObjCSelType();
1435 break;
1436 }
1437
1438 if (!VisitType.isNull()) {
1439 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1440 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1441 TU));
1442 }
1443
1444 return false;
1445}
1446
1447bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1448 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1449}
1450
1451bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1452 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1453}
1454
1455bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1456 if (TL.isDefinition())
1457 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1458
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1467 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1468 return true;
1469
1470 return false;
1471}
1472
1473bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1474 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1475 return true;
1476
1477 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1478 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1479 TU)))
1480 return true;
1481 }
1482
1483 return false;
1484}
1485
1486bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1487 return Visit(TL.getPointeeLoc());
1488}
1489
1490bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1491 return Visit(TL.getInnerLoc());
1492}
1493
1494bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1495 return Visit(TL.getPointeeLoc());
1496}
1497
1498bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1503 return Visit(TL.getPointeeLoc());
1504}
1505
1506bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1515 return Visit(TL.getModifiedLoc());
1516}
1517
1518bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1519 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001520 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001521 return true;
1522
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001523 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1524 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001525 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1526 return true;
1527
1528 return false;
1529}
1530
1531bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1532 if (Visit(TL.getElementLoc()))
1533 return true;
1534
1535 if (Expr *Size = TL.getSizeExpr())
1536 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1537
1538 return false;
1539}
1540
Reid Kleckner8a365022013-06-24 17:51:48 +00001541bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1542 return Visit(TL.getOriginalLoc());
1543}
1544
Reid Kleckner0503a872013-12-05 01:23:43 +00001545bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1546 return Visit(TL.getOriginalLoc());
1547}
1548
Guy Benyei11169dd2012-12-18 14:30:41 +00001549bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1550 TemplateSpecializationTypeLoc TL) {
1551 // Visit the template name.
1552 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1553 TL.getTemplateNameLoc()))
1554 return true;
1555
1556 // Visit the template arguments.
1557 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1558 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1559 return true;
1560
1561 return false;
1562}
1563
1564bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1565 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1566}
1567
1568bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1569 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1570 return Visit(TSInfo->getTypeLoc());
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1583 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1584 return true;
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1590 DependentTemplateSpecializationTypeLoc TL) {
1591 // Visit the nested-name-specifier, if there is one.
1592 if (TL.getQualifierLoc() &&
1593 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1594 return true;
1595
1596 // Visit the template arguments.
1597 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1598 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1599 return true;
1600
1601 return false;
1602}
1603
1604bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1605 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 return Visit(TL.getNamedTypeLoc());
1609}
1610
1611bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1612 return Visit(TL.getPatternLoc());
1613}
1614
1615bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1616 if (Expr *E = TL.getUnderlyingExpr())
1617 return Visit(MakeCXCursor(E, StmtParent, TU));
1618
1619 return false;
1620}
1621
1622bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1623 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1624}
1625
1626bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1627 return Visit(TL.getValueLoc());
1628}
1629
1630#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1631bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1632 return Visit##PARENT##Loc(TL); \
1633}
1634
1635DEFAULT_TYPELOC_IMPL(Complex, Type)
1636DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1638DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1641DEFAULT_TYPELOC_IMPL(Vector, Type)
1642DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1643DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1644DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1645DEFAULT_TYPELOC_IMPL(Record, TagType)
1646DEFAULT_TYPELOC_IMPL(Enum, TagType)
1647DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1648DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1649DEFAULT_TYPELOC_IMPL(Auto, Type)
1650
1651bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1652 // Visit the nested-name-specifier, if present.
1653 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1654 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1655 return true;
1656
1657 if (D->isCompleteDefinition()) {
1658 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1659 E = D->bases_end(); I != E; ++I) {
1660 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1661 return true;
1662 }
1663 }
1664
1665 return VisitTagDecl(D);
1666}
1667
1668bool CursorVisitor::VisitAttributes(Decl *D) {
1669 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1670 i != e; ++i)
1671 if (Visit(MakeCXCursor(*i, D, TU)))
1672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001706 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001801 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 VisitorWorkList &WL;
1803 CXCursor Parent;
1804public:
1805 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1806 : WL(wl), Parent(parent) {}
1807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1809 void VisitBlockExpr(const BlockExpr *B);
1810 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1811 void VisitCompoundStmt(const CompoundStmt *S);
1812 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1813 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1814 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1815 void VisitCXXNewExpr(const CXXNewExpr *E);
1816 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1817 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1818 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1819 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1820 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1821 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1822 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1823 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1824 void VisitDeclRefExpr(const DeclRefExpr *D);
1825 void VisitDeclStmt(const DeclStmt *S);
1826 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1827 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1828 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1829 void VisitForStmt(const ForStmt *FS);
1830 void VisitGotoStmt(const GotoStmt *GS);
1831 void VisitIfStmt(const IfStmt *If);
1832 void VisitInitListExpr(const InitListExpr *IE);
1833 void VisitMemberExpr(const MemberExpr *M);
1834 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1835 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1836 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1837 void VisitOverloadExpr(const OverloadExpr *E);
1838 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1839 void VisitStmt(const Stmt *S);
1840 void VisitSwitchStmt(const SwitchStmt *S);
1841 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853
Guy Benyei11169dd2012-12-18 14:30:41 +00001854private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001856 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1857 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1859 void AddStmt(const Stmt *S);
1860 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001863 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001864};
1865} // end anonyous namespace
1866
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001868 // 'S' should always be non-null, since it comes from the
1869 // statement we are visiting.
1870 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1871}
1872
1873void
1874EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1875 if (Qualifier)
1876 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1877}
1878
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 if (S)
1881 WL.push_back(StmtVisit(S, Parent));
1882}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 if (D)
1885 WL.push_back(DeclVisit(D, Parent, isFirst));
1886}
1887void EnqueueVisitor::
1888 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1889 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001891}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001893 if (D)
1894 WL.push_back(MemberRefVisit(D, L, Parent));
1895}
1896void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1897 if (TI)
1898 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1899 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 AddStmt(*Child);
1904 }
1905 if (size == WL.size())
1906 return;
1907 // Now reverse the entries we just added. This will match the DFS
1908 // ordering performed by the worklist.
1909 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1910 std::reverse(I, E);
1911}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001912namespace {
1913class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1914 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001915 /// \brief Process clauses with list of variables.
1916 template <typename T>
1917 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918public:
1919 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1920#define OPENMP_CLAUSE(Name, Class) \
1921 void Visit##Class(const Class *C);
1922#include "clang/Basic/OpenMPKinds.def"
1923};
1924
1925void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001926
1927template<typename T>
1928void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1929 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1930 E = Node->varlist_end();
1931 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001933}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001934
1935void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001936 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001937}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001938void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1939 const OMPFirstprivateClause *C) {
1940 VisitOMPClauseList(C);
1941}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001942void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001943 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001944}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945}
Alexey Bataev756c1962013-09-24 03:17:45 +00001946
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1948 unsigned size = WL.size();
1949 OMPClauseEnqueue Visitor(this);
1950 Visitor.Visit(S);
1951 if (size == WL.size())
1952 return;
1953 // Now reverse the entries we just added. This will match the DFS
1954 // ordering performed by the worklist.
1955 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1956 std::reverse(I, E);
1957}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1960}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 AddDecl(B->getBlockDecl());
1963}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 EnqueueChildren(E);
1966 AddTypeLoc(E->getTypeSourceInfo());
1967}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1969 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 E = S->body_rend(); I != E; ++I) {
1971 AddStmt(*I);
1972 }
1973}
1974void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 AddStmt(S->getSubStmt());
1977 AddDeclarationNameInfo(S);
1978 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1979 AddNestedNameSpecifierLoc(QualifierLoc);
1980}
1981
1982void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1985 AddDeclarationNameInfo(E);
1986 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1987 AddNestedNameSpecifierLoc(QualifierLoc);
1988 if (!E->isImplicitAccess())
1989 AddStmt(E->getBase());
1990}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 // Enqueue the initializer , if any.
1993 AddStmt(E->getInitializer());
1994 // Enqueue the array size, if any.
1995 AddStmt(E->getArraySize());
1996 // Enqueue the allocated type.
1997 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1998 // Enqueue the placement arguments.
1999 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2000 AddStmt(E->getPlacementArg(I-1));
2001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2004 AddStmt(CE->getArg(I-1));
2005 AddStmt(CE->getCallee());
2006 AddStmt(CE->getArg(0));
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2009 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 // Visit the name of the type being destroyed.
2011 AddTypeLoc(E->getDestroyedTypeInfo());
2012 // Visit the scope type that looks disturbingly like the nested-name-specifier
2013 // but isn't.
2014 AddTypeLoc(E->getScopeTypeInfo());
2015 // Visit the nested-name-specifier.
2016 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2017 AddNestedNameSpecifierLoc(QualifierLoc);
2018 // Visit base expression.
2019 AddStmt(E->getBase());
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2022 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 AddTypeLoc(E->getTypeSourceInfo());
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2026 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 EnqueueChildren(E);
2028 AddTypeLoc(E->getTypeSourceInfo());
2029}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 EnqueueChildren(E);
2032 if (E->isTypeOperand())
2033 AddTypeLoc(E->getTypeOperandSourceInfo());
2034}
2035
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2037 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002038 EnqueueChildren(E);
2039 AddTypeLoc(E->getTypeSourceInfo());
2040}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 EnqueueChildren(E);
2043 if (E->isTypeOperand())
2044 AddTypeLoc(E->getTypeOperandSourceInfo());
2045}
2046
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(S);
2049 AddDecl(S->getExceptionDecl());
2050}
2051
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 if (DR->hasExplicitTemplateArgs()) {
2054 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2055 }
2056 WL.push_back(DeclRefExprParts(DR, Parent));
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2059 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2061 AddDeclarationNameInfo(E);
2062 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 unsigned size = WL.size();
2066 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 D != DEnd; ++D) {
2069 AddDecl(*D, isFirst);
2070 isFirst = false;
2071 }
2072 if (size == WL.size())
2073 return;
2074 // Now reverse the entries we just added. This will match the DFS
2075 // ordering performed by the worklist.
2076 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2077 std::reverse(I, E);
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 D = E->designators_rbegin(), DEnd = E->designators_rend();
2083 D != DEnd; ++D) {
2084 if (D->isFieldDesignator()) {
2085 if (FieldDecl *Field = D->getField())
2086 AddMemberRef(Field, D->getFieldLoc());
2087 continue;
2088 }
2089 if (D->isArrayDesignator()) {
2090 AddStmt(E->getArrayIndex(*D));
2091 continue;
2092 }
2093 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2094 AddStmt(E->getArrayRangeEnd(*D));
2095 AddStmt(E->getArrayRangeStart(*D));
2096 }
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 EnqueueChildren(E);
2100 AddTypeLoc(E->getTypeInfoAsWritten());
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 AddStmt(FS->getBody());
2104 AddStmt(FS->getInc());
2105 AddStmt(FS->getCond());
2106 AddDecl(FS->getConditionVariable());
2107 AddStmt(FS->getInit());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 AddStmt(If->getElse());
2114 AddStmt(If->getThen());
2115 AddStmt(If->getCond());
2116 AddDecl(If->getConditionVariable());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 // We care about the syntactic form of the initializer list, only.
2120 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2121 IE = Syntactic;
2122 EnqueueChildren(IE);
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 WL.push_back(MemberExprParts(M, Parent));
2126
2127 // If the base of the member access expression is an implicit 'this', don't
2128 // visit it.
2129 // FIXME: If we ever want to show these implicit accesses, this will be
2130 // unfortunate. However, clang_getCursor() relies on this behavior.
2131 if (!M->isImplicitAccess())
2132 AddStmt(M->getBase());
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 AddTypeLoc(E->getEncodedTypeSourceInfo());
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 EnqueueChildren(M);
2139 AddTypeLoc(M->getClassReceiverTypeInfo());
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 // Visit the components of the offsetof expression.
2143 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2144 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2145 const OffsetOfNode &Node = E->getComponent(I-1);
2146 switch (Node.getKind()) {
2147 case OffsetOfNode::Array:
2148 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2149 break;
2150 case OffsetOfNode::Field:
2151 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2152 break;
2153 case OffsetOfNode::Identifier:
2154 case OffsetOfNode::Base:
2155 continue;
2156 }
2157 }
2158 // Visit the type into which we're computing the offset.
2159 AddTypeLoc(E->getTypeSourceInfo());
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2163 WL.push_back(OverloadExprParts(E, Parent));
2164}
2165void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 EnqueueChildren(E);
2168 if (E->isArgumentType())
2169 AddTypeLoc(E->getArgumentTypeInfo());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(S);
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddStmt(S->getBody());
2176 AddStmt(S->getCond());
2177 AddDecl(S->getConditionVariable());
2178}
2179
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddStmt(W->getBody());
2182 AddStmt(W->getCond());
2183 AddDecl(W->getConditionVariable());
2184}
2185
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 for (unsigned I = E->getNumArgs(); I > 0; --I)
2188 AddTypeLoc(E->getArg(I-1));
2189}
2190
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddTypeLoc(E->getQueriedTypeSourceInfo());
2193}
2194
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 EnqueueChildren(E);
2197}
2198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 VisitOverloadExpr(U);
2201 if (!U->isImplicitAccess())
2202 AddStmt(U->getBase());
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddStmt(E->getSubExpr());
2206 AddTypeLoc(E->getWrittenTypeInfo());
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 WL.push_back(SizeOfPackExprParts(E, Parent));
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 // If the opaque value has a source expression, just transparently
2213 // visit that. This is useful for (e.g.) pseudo-object expressions.
2214 if (Expr *SourceExpr = E->getSourceExpr())
2215 return Visit(SourceExpr);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddStmt(E->getBody());
2219 WL.push_back(LambdaExprParts(E, Parent));
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 // Treat the expression like its syntactic form.
2223 Visit(E->getSyntacticForm());
2224}
2225
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002226void EnqueueVisitor::VisitOMPExecutableDirective(
2227 const OMPExecutableDirective *D) {
2228 EnqueueChildren(D);
2229 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2230 E = D->clauses().end();
2231 I != E; ++I)
2232 EnqueueChildren(*I);
2233}
2234
2235void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2236 VisitOMPExecutableDirective(D);
2237}
2238
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2241}
2242
2243bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2244 if (RegionOfInterest.isValid()) {
2245 SourceRange Range = getRawCursorExtent(C);
2246 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2247 return false;
2248 }
2249 return true;
2250}
2251
2252bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2253 while (!WL.empty()) {
2254 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002255 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002256
2257 // Set the Parent field, then back to its old value once we're done.
2258 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2259
2260 switch (LI.getKind()) {
2261 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 if (!D)
2264 continue;
2265
2266 // For now, perform default visitation for Decls.
2267 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2268 cast<DeclVisit>(&LI)->isFirst())))
2269 return true;
2270
2271 continue;
2272 }
2273 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2274 const ASTTemplateArgumentListInfo *ArgList =
2275 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2276 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2277 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2278 Arg != ArgEnd; ++Arg) {
2279 if (VisitTemplateArgumentLoc(*Arg))
2280 return true;
2281 }
2282 continue;
2283 }
2284 case VisitorJob::TypeLocVisitKind: {
2285 // Perform default visitation for TypeLocs.
2286 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2287 return true;
2288 continue;
2289 }
2290 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 if (LabelStmt *stmt = LS->getStmt()) {
2293 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2294 TU))) {
2295 return true;
2296 }
2297 }
2298 continue;
2299 }
2300
2301 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2302 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2303 if (VisitNestedNameSpecifierLoc(V->get()))
2304 return true;
2305 continue;
2306 }
2307
2308 case VisitorJob::DeclarationNameInfoVisitKind: {
2309 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2310 ->get()))
2311 return true;
2312 continue;
2313 }
2314 case VisitorJob::MemberRefVisitKind: {
2315 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2316 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2317 return true;
2318 continue;
2319 }
2320 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 if (!S)
2323 continue;
2324
2325 // Update the current cursor.
2326 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2327 if (!IsInRegionOfInterest(Cursor))
2328 continue;
2329 switch (Visitor(Cursor, Parent, ClientData)) {
2330 case CXChildVisit_Break: return true;
2331 case CXChildVisit_Continue: break;
2332 case CXChildVisit_Recurse:
2333 if (PostChildrenVisitor)
2334 WL.push_back(PostChildrenVisit(0, Cursor));
2335 EnqueueWorkList(WL, S);
2336 break;
2337 }
2338 continue;
2339 }
2340 case VisitorJob::MemberExprPartsKind: {
2341 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343
2344 // Visit the nested-name-specifier
2345 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2346 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2347 return true;
2348
2349 // Visit the declaration name.
2350 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2351 return true;
2352
2353 // Visit the explicitly-specified template arguments, if any.
2354 if (M->hasExplicitTemplateArgs()) {
2355 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2356 *ArgEnd = Arg + M->getNumTemplateArgs();
2357 Arg != ArgEnd; ++Arg) {
2358 if (VisitTemplateArgumentLoc(*Arg))
2359 return true;
2360 }
2361 }
2362 continue;
2363 }
2364 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002366 // Visit nested-name-specifier, if present.
2367 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2368 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2369 return true;
2370 // Visit declaration name.
2371 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2372 return true;
2373 continue;
2374 }
2375 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 // Visit the nested-name-specifier.
2378 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2379 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2380 return true;
2381 // Visit the declaration name.
2382 if (VisitDeclarationNameInfo(O->getNameInfo()))
2383 return true;
2384 // Visit the overloaded declaration reference.
2385 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2386 return true;
2387 continue;
2388 }
2389 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 NamedDecl *Pack = E->getPack();
2392 if (isa<TemplateTypeParmDecl>(Pack)) {
2393 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2394 E->getPackLoc(), TU)))
2395 return true;
2396
2397 continue;
2398 }
2399
2400 if (isa<TemplateTemplateParmDecl>(Pack)) {
2401 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2402 E->getPackLoc(), TU)))
2403 return true;
2404
2405 continue;
2406 }
2407
2408 // Non-type template parameter packs and function parameter packs are
2409 // treated like DeclRefExpr cursors.
2410 continue;
2411 }
2412
2413 case VisitorJob::LambdaExprPartsKind: {
2414 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2417 CEnd = E->explicit_capture_end();
2418 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002419 // FIXME: Lambda init-captures.
2420 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002422
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2424 C->getLocation(),
2425 TU)))
2426 return true;
2427 }
2428
2429 // Visit parameters and return type, if present.
2430 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2431 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2432 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2433 // Visit the whole type.
2434 if (Visit(TL))
2435 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002436 } else if (FunctionProtoTypeLoc Proto =
2437 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 if (E->hasExplicitParameters()) {
2439 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002440 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2441 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 return true;
2443 } else {
2444 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002445 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 return true;
2447 }
2448 }
2449 }
2450 break;
2451 }
2452
2453 case VisitorJob::PostChildrenVisitKind:
2454 if (PostChildrenVisitor(Parent, ClientData))
2455 return true;
2456 break;
2457 }
2458 }
2459 return false;
2460}
2461
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 VisitorWorkList *WL = 0;
2464 if (!WorkListFreeList.empty()) {
2465 WL = WorkListFreeList.back();
2466 WL->clear();
2467 WorkListFreeList.pop_back();
2468 }
2469 else {
2470 WL = new VisitorWorkList();
2471 WorkListCache.push_back(WL);
2472 }
2473 EnqueueWorkList(*WL, S);
2474 bool result = RunVisitorWorkList(*WL);
2475 WorkListFreeList.push_back(WL);
2476 return result;
2477}
2478
2479namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002480typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002481RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2482 const DeclarationNameInfo &NI,
2483 const SourceRange &QLoc,
2484 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2485 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2486 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2487 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2488
2489 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2490
2491 RefNamePieces Pieces;
2492
2493 if (WantQualifier && QLoc.isValid())
2494 Pieces.push_back(QLoc);
2495
2496 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2497 Pieces.push_back(NI.getLoc());
2498
2499 if (WantTemplateArgs && TemplateArgs)
2500 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2501 TemplateArgs->RAngleLoc));
2502
2503 if (Kind == DeclarationName::CXXOperatorName) {
2504 Pieces.push_back(SourceLocation::getFromRawEncoding(
2505 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2506 Pieces.push_back(SourceLocation::getFromRawEncoding(
2507 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2508 }
2509
2510 if (WantSinglePiece) {
2511 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2512 Pieces.clear();
2513 Pieces.push_back(R);
2514 }
2515
2516 return Pieces;
2517}
2518}
2519
2520//===----------------------------------------------------------------------===//
2521// Misc. API hooks.
2522//===----------------------------------------------------------------------===//
2523
2524static llvm::sys::Mutex EnableMultithreadingMutex;
2525static bool EnabledMultithreading;
2526
Chad Rosier05c71aa2013-03-27 18:28:23 +00002527static void fatal_error_handler(void *user_data, const std::string& reason,
2528 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 // Write the result out to stderr avoiding errs() because raw_ostreams can
2530 // call report_fatal_error.
2531 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2532 ::abort();
2533}
2534
2535extern "C" {
2536CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2537 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 // We use crash recovery to make some of our APIs more reliable, implicitly
2539 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002540 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2541 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002542
2543 // Enable support for multithreading in LLVM.
2544 {
2545 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2546 if (!EnabledMultithreading) {
2547 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2548 llvm::llvm_start_multithreaded();
2549 EnabledMultithreading = true;
2550 }
2551 }
2552
2553 CIndexer *CIdxr = new CIndexer();
2554 if (excludeDeclarationsFromPCH)
2555 CIdxr->setOnlyLocalDecls();
2556 if (displayDiagnostics)
2557 CIdxr->setDisplayDiagnostics();
2558
2559 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2560 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2561 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2562 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2563 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2564 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2565
2566 return CIdxr;
2567}
2568
2569void clang_disposeIndex(CXIndex CIdx) {
2570 if (CIdx)
2571 delete static_cast<CIndexer *>(CIdx);
2572}
2573
2574void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2575 if (CIdx)
2576 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2577}
2578
2579unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2580 if (CIdx)
2581 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2582 return 0;
2583}
2584
2585void clang_toggleCrashRecovery(unsigned isEnabled) {
2586 if (isEnabled)
2587 llvm::CrashRecoveryContext::Enable();
2588 else
2589 llvm::CrashRecoveryContext::Disable();
2590}
2591
2592CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2593 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002594 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 return 0;
2596
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002597 LOG_FUNC_SECTION {
2598 *Log << ast_filename;
2599 }
2600
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2602 FileSystemOptions FileSystemOpts;
2603
2604 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2605 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002606 CXXIdx->getOnlyLocalDecls(), None,
2607 /*CaptureDiagnostics=*/true,
2608 /*AllowPCHWithCompilerErrors=*/true,
2609 /*UserFilesAreVolatile=*/true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002610 return MakeCXTranslationUnit(CXXIdx, TU);
2611}
2612
2613unsigned clang_defaultEditingTranslationUnitOptions() {
2614 return CXTranslationUnit_PrecompiledPreamble |
2615 CXTranslationUnit_CacheCompletionResults;
2616}
2617
2618CXTranslationUnit
2619clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2620 const char *source_filename,
2621 int num_command_line_args,
2622 const char * const *command_line_args,
2623 unsigned num_unsaved_files,
2624 struct CXUnsavedFile *unsaved_files) {
2625 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2626 return clang_parseTranslationUnit(CIdx, source_filename,
2627 command_line_args, num_command_line_args,
2628 unsaved_files, num_unsaved_files,
2629 Options);
2630}
2631
2632struct ParseTranslationUnitInfo {
2633 CXIndex CIdx;
2634 const char *source_filename;
2635 const char *const *command_line_args;
2636 int num_command_line_args;
2637 struct CXUnsavedFile *unsaved_files;
2638 unsigned num_unsaved_files;
2639 unsigned options;
2640 CXTranslationUnit result;
2641};
2642static void clang_parseTranslationUnit_Impl(void *UserData) {
2643 ParseTranslationUnitInfo *PTUI =
2644 static_cast<ParseTranslationUnitInfo*>(UserData);
2645 CXIndex CIdx = PTUI->CIdx;
2646 const char *source_filename = PTUI->source_filename;
2647 const char * const *command_line_args = PTUI->command_line_args;
2648 int num_command_line_args = PTUI->num_command_line_args;
2649 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2650 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2651 unsigned options = PTUI->options;
2652 PTUI->result = 0;
2653
2654 if (!CIdx)
2655 return;
2656
2657 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2658
2659 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2660 setThreadBackgroundPriority();
2661
2662 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2663 // FIXME: Add a flag for modules.
2664 TranslationUnitKind TUKind
2665 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002666 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002667 = options & CXTranslationUnit_CacheCompletionResults;
2668 bool IncludeBriefCommentsInCodeCompletion
2669 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2670 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2671 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2672
2673 // Configure the diagnostics.
2674 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002675 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002676
2677 // Recover resources if we crash before exiting this function.
2678 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2679 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2680 DiagCleanup(Diags.getPtr());
2681
2682 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2683 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2684
2685 // Recover resources if we crash before exiting this function.
2686 llvm::CrashRecoveryContextCleanupRegistrar<
2687 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2688
2689 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2690 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2691 const llvm::MemoryBuffer *Buffer
2692 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2693 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2694 Buffer));
2695 }
2696
2697 OwningPtr<std::vector<const char *> >
2698 Args(new std::vector<const char*>());
2699
2700 // Recover resources if we crash before exiting this method.
2701 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2702 ArgsCleanup(Args.get());
2703
2704 // Since the Clang C library is primarily used by batch tools dealing with
2705 // (often very broken) source code, where spell-checking can have a
2706 // significant negative impact on performance (particularly when
2707 // precompiled headers are involved), we disable it by default.
2708 // Only do this if we haven't found a spell-checking-related argument.
2709 bool FoundSpellCheckingArgument = false;
2710 for (int I = 0; I != num_command_line_args; ++I) {
2711 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2712 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2713 FoundSpellCheckingArgument = true;
2714 break;
2715 }
2716 }
2717 if (!FoundSpellCheckingArgument)
2718 Args->push_back("-fno-spell-checking");
2719
2720 Args->insert(Args->end(), command_line_args,
2721 command_line_args + num_command_line_args);
2722
2723 // The 'source_filename' argument is optional. If the caller does not
2724 // specify it then it is assumed that the source file is specified
2725 // in the actual argument list.
2726 // Put the source file after command_line_args otherwise if '-x' flag is
2727 // present it will be unused.
2728 if (source_filename)
2729 Args->push_back(source_filename);
2730
2731 // Do we need the detailed preprocessing record?
2732 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2733 Args->push_back("-Xclang");
2734 Args->push_back("-detailed-preprocessing-record");
2735 }
2736
2737 unsigned NumErrors = Diags->getClient()->getNumErrors();
2738 OwningPtr<ASTUnit> ErrUnit;
2739 OwningPtr<ASTUnit> Unit(
2740 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2741 /* vector::data() not portable */,
2742 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2743 Diags,
2744 CXXIdx->getClangResourcesPath(),
2745 CXXIdx->getOnlyLocalDecls(),
2746 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002747 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 /*RemappedFilesKeepOriginalName=*/true,
2749 PrecompilePreamble,
2750 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002751 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002752 IncludeBriefCommentsInCodeCompletion,
2753 /*AllowPCHWithCompilerErrors=*/true,
2754 SkipFunctionBodies,
2755 /*UserFilesAreVolatile=*/true,
2756 ForSerialization,
2757 &ErrUnit));
2758
2759 if (NumErrors != Diags->getClient()->getNumErrors()) {
2760 // Make sure to check that 'Unit' is non-NULL.
2761 if (CXXIdx->getDisplayDiagnostics())
2762 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2763 }
2764
2765 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2766}
2767CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2768 const char *source_filename,
2769 const char * const *command_line_args,
2770 int num_command_line_args,
2771 struct CXUnsavedFile *unsaved_files,
2772 unsigned num_unsaved_files,
2773 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002774 LOG_FUNC_SECTION {
2775 *Log << source_filename << ": ";
2776 for (int i = 0; i != num_command_line_args; ++i)
2777 *Log << command_line_args[i] << " ";
2778 }
2779
Guy Benyei11169dd2012-12-18 14:30:41 +00002780 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2781 num_command_line_args, unsaved_files,
2782 num_unsaved_files, options, 0 };
2783 llvm::CrashRecoveryContext CRC;
2784
2785 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2786 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2787 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2788 fprintf(stderr, " 'command_line_args' : [");
2789 for (int i = 0; i != num_command_line_args; ++i) {
2790 if (i)
2791 fprintf(stderr, ", ");
2792 fprintf(stderr, "'%s'", command_line_args[i]);
2793 }
2794 fprintf(stderr, "],\n");
2795 fprintf(stderr, " 'unsaved_files' : [");
2796 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2797 if (i)
2798 fprintf(stderr, ", ");
2799 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2800 unsaved_files[i].Length);
2801 }
2802 fprintf(stderr, "],\n");
2803 fprintf(stderr, " 'options' : %d,\n", options);
2804 fprintf(stderr, "}\n");
2805
2806 return 0;
2807 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2808 PrintLibclangResourceUsage(PTUI.result);
2809 }
2810
2811 return PTUI.result;
2812}
2813
2814unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2815 return CXSaveTranslationUnit_None;
2816}
2817
2818namespace {
2819
2820struct SaveTranslationUnitInfo {
2821 CXTranslationUnit TU;
2822 const char *FileName;
2823 unsigned options;
2824 CXSaveError result;
2825};
2826
2827}
2828
2829static void clang_saveTranslationUnit_Impl(void *UserData) {
2830 SaveTranslationUnitInfo *STUI =
2831 static_cast<SaveTranslationUnitInfo*>(UserData);
2832
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002833 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002834 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2835 setThreadBackgroundPriority();
2836
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002837 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2839}
2840
2841int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2842 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002843 LOG_FUNC_SECTION {
2844 *Log << TU << ' ' << FileName;
2845 }
2846
Guy Benyei11169dd2012-12-18 14:30:41 +00002847 if (!TU)
2848 return CXSaveError_InvalidTU;
2849
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002850 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2852 if (!CXXUnit->hasSema())
2853 return CXSaveError_InvalidTU;
2854
2855 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2856
2857 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2858 getenv("LIBCLANG_NOTHREADS")) {
2859 clang_saveTranslationUnit_Impl(&STUI);
2860
2861 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2862 PrintLibclangResourceUsage(TU);
2863
2864 return STUI.result;
2865 }
2866
2867 // We have an AST that has invalid nodes due to compiler errors.
2868 // Use a crash recovery thread for protection.
2869
2870 llvm::CrashRecoveryContext CRC;
2871
2872 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2873 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2874 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2875 fprintf(stderr, " 'options' : %d,\n", options);
2876 fprintf(stderr, "}\n");
2877
2878 return CXSaveError_Unknown;
2879
2880 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2881 PrintLibclangResourceUsage(TU);
2882 }
2883
2884 return STUI.result;
2885}
2886
2887void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2888 if (CTUnit) {
2889 // If the translation unit has been marked as unsafe to free, just discard
2890 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002891 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002892 return;
2893
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002894 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002895 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002896 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2897 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002898 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 delete CTUnit;
2900 }
2901}
2902
2903unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2904 return CXReparse_None;
2905}
2906
2907struct ReparseTranslationUnitInfo {
2908 CXTranslationUnit TU;
2909 unsigned num_unsaved_files;
2910 struct CXUnsavedFile *unsaved_files;
2911 unsigned options;
2912 int result;
2913};
2914
2915static void clang_reparseTranslationUnit_Impl(void *UserData) {
2916 ReparseTranslationUnitInfo *RTUI =
2917 static_cast<ReparseTranslationUnitInfo*>(UserData);
2918 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002919 if (!TU)
2920 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002921
2922 // Reset the associated diagnostics.
2923 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2924 TU->Diagnostics = 0;
2925
2926 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2927 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2928 unsigned options = RTUI->options;
2929 (void) options;
2930 RTUI->result = 1;
2931
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002932 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2934 setThreadBackgroundPriority();
2935
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002936 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2938
2939 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2940 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2941
2942 // Recover resources if we crash before exiting this function.
2943 llvm::CrashRecoveryContextCleanupRegistrar<
2944 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2945
2946 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2947 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2948 const llvm::MemoryBuffer *Buffer
2949 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2950 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2951 Buffer));
2952 }
2953
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002954 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002955 RTUI->result = 0;
2956}
2957
2958int clang_reparseTranslationUnit(CXTranslationUnit TU,
2959 unsigned num_unsaved_files,
2960 struct CXUnsavedFile *unsaved_files,
2961 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002962 LOG_FUNC_SECTION {
2963 *Log << TU;
2964 }
2965
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2967 options, 0 };
2968
2969 if (getenv("LIBCLANG_NOTHREADS")) {
2970 clang_reparseTranslationUnit_Impl(&RTUI);
2971 return RTUI.result;
2972 }
2973
2974 llvm::CrashRecoveryContext CRC;
2975
2976 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2977 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002978 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002979 return 1;
2980 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2981 PrintLibclangResourceUsage(TU);
2982
2983 return RTUI.result;
2984}
2985
2986
2987CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2988 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002989 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00002990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002991 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00002992 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00002993}
2994
2995CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00002996 if (!TU)
2997 return clang_getNullCursor();
2998
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002999 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003000 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3001}
3002
3003} // end: extern "C"
3004
3005//===----------------------------------------------------------------------===//
3006// CXFile Operations.
3007//===----------------------------------------------------------------------===//
3008
3009extern "C" {
3010CXString clang_getFileName(CXFile SFile) {
3011 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003012 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003013
3014 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003015 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003016}
3017
3018time_t clang_getFileTime(CXFile SFile) {
3019 if (!SFile)
3020 return 0;
3021
3022 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3023 return FEnt->getModificationTime();
3024}
3025
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003026CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3027 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003028 return 0;
3029
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003030 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003031
3032 FileManager &FMgr = CXXUnit->getFileManager();
3033 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3034}
3035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003036unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3037 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 return 0;
3039
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 FileEntry *FEnt = static_cast<FileEntry *>(file);
3042 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3043 .isFileMultipleIncludeGuarded(FEnt);
3044}
3045
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003046int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3047 if (!file || !outID)
3048 return 1;
3049
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003050 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003051 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3052 outID->data[0] = ID.getDevice();
3053 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003054 outID->data[2] = FEnt->getModificationTime();
3055 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003056}
3057
Guy Benyei11169dd2012-12-18 14:30:41 +00003058} // end: extern "C"
3059
3060//===----------------------------------------------------------------------===//
3061// CXCursor Operations.
3062//===----------------------------------------------------------------------===//
3063
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003064static const Decl *getDeclFromExpr(const Stmt *E) {
3065 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 return getDeclFromExpr(CE->getSubExpr());
3067
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003068 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003070 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003071 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003072 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003073 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003074 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 if (PRE->isExplicitProperty())
3076 return PRE->getExplicitProperty();
3077 // It could be messaging both getter and setter as in:
3078 // ++myobj.myprop;
3079 // in which case prefer to associate the setter since it is less obvious
3080 // from inspecting the source that the setter is going to get called.
3081 if (PRE->isMessagingSetter())
3082 return PRE->getImplicitPropertySetter();
3083 return PRE->getImplicitPropertyGetter();
3084 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003085 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003087 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003088 if (Expr *Src = OVE->getSourceExpr())
3089 return getDeclFromExpr(Src);
3090
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003091 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003093 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003094 if (!CE->isElidable())
3095 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003096 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 return OME->getMethodDecl();
3098
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003099 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003101 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3103 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003104 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3106 isa<ParmVarDecl>(SizeOfPack->getPack()))
3107 return SizeOfPack->getPack();
3108
3109 return 0;
3110}
3111
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003112static SourceLocation getLocationFromExpr(const Expr *E) {
3113 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 return getLocationFromExpr(CE->getSubExpr());
3115
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003116 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003118 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003120 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003122 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003124 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003126 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 return PropRef->getLocation();
3128
3129 return E->getLocStart();
3130}
3131
3132extern "C" {
3133
3134unsigned clang_visitChildren(CXCursor parent,
3135 CXCursorVisitor visitor,
3136 CXClientData client_data) {
3137 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3138 /*VisitPreprocessorLast=*/false);
3139 return CursorVis.VisitChildren(parent);
3140}
3141
3142#ifndef __has_feature
3143#define __has_feature(x) 0
3144#endif
3145#if __has_feature(blocks)
3146typedef enum CXChildVisitResult
3147 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3148
3149static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3150 CXClientData client_data) {
3151 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3152 return block(cursor, parent);
3153}
3154#else
3155// If we are compiled with a compiler that doesn't have native blocks support,
3156// define and call the block manually, so the
3157typedef struct _CXChildVisitResult
3158{
3159 void *isa;
3160 int flags;
3161 int reserved;
3162 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3163 CXCursor);
3164} *CXCursorVisitorBlock;
3165
3166static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3167 CXClientData client_data) {
3168 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3169 return block->invoke(block, cursor, parent);
3170}
3171#endif
3172
3173
3174unsigned clang_visitChildrenWithBlock(CXCursor parent,
3175 CXCursorVisitorBlock block) {
3176 return clang_visitChildren(parent, visitWithBlock, block);
3177}
3178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003181 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003182
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const ObjCPropertyImplDecl *PropImpl =
3186 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003188 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003189
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003190 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003192 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003193
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003194 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 }
3196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003198 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003199
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3202 // and returns different names. NamedDecl returns the class name and
3203 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003204 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003205
3206 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003207 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
3209 SmallString<1024> S;
3210 llvm::raw_svector_ostream os(S);
3211 ND->printName(os);
3212
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003213 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003214}
3215
3216CXString clang_getCursorSpelling(CXCursor C) {
3217 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003218 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003219
3220 if (clang_isReference(C.kind)) {
3221 switch (C.kind) {
3222 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003223 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003224 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 }
3226 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003227 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003228 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 }
3230 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003231 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003233 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 }
3235 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003236 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003237 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 }
3239 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003240 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 assert(Type && "Missing type decl");
3242
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003243 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 getAsString());
3245 }
3246 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003247 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 assert(Template && "Missing template decl");
3249
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003250 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 }
3252
3253 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003254 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003255 assert(NS && "Missing namespace decl");
3256
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003257 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 }
3259
3260 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003261 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 assert(Field && "Missing member decl");
3263
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003264 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 }
3266
3267 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003268 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 assert(Label && "Missing label");
3270
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003271 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 }
3273
3274 case CXCursor_OverloadedDeclRef: {
3275 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3277 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003278 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003279 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003282 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 OverloadedTemplateStorage *Ovl
3284 = Storage.get<OverloadedTemplateStorage*>();
3285 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003286 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003287 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 }
3289
3290 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003291 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 assert(Var && "Missing variable decl");
3293
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003294 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 }
3296
3297 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003298 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 }
3300 }
3301
3302 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003303 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 if (D)
3305 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003306 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 }
3308
3309 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003310 const Stmt *S = getCursorStmt(C);
3311 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003312 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003313
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003314 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
3316
3317 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003318 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 ->getNameStart());
3320
3321 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003322 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 ->getNameStart());
3324
3325 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003326 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327
3328 if (clang_isDeclaration(C.kind))
3329 return getDeclSpelling(getCursorDecl(C));
3330
3331 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003332 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003333 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 }
3335
3336 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003337 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003338 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 }
3340
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003341 if (C.kind == CXCursor_PackedAttr) {
3342 return cxstring::createRef("packed");
3343 }
3344
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003345 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003346}
3347
3348CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3349 unsigned pieceIndex,
3350 unsigned options) {
3351 if (clang_Cursor_isNull(C))
3352 return clang_getNullRange();
3353
3354 ASTContext &Ctx = getCursorContext(C);
3355
3356 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003357 const Stmt *S = getCursorStmt(C);
3358 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 if (pieceIndex > 0)
3360 return clang_getNullRange();
3361 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3362 }
3363
3364 return clang_getNullRange();
3365 }
3366
3367 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003368 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3370 if (pieceIndex >= ME->getNumSelectorLocs())
3371 return clang_getNullRange();
3372 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3373 }
3374 }
3375
3376 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3377 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3380 if (pieceIndex >= MD->getNumSelectorLocs())
3381 return clang_getNullRange();
3382 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3383 }
3384 }
3385
3386 if (C.kind == CXCursor_ObjCCategoryDecl ||
3387 C.kind == CXCursor_ObjCCategoryImplDecl) {
3388 if (pieceIndex > 0)
3389 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003390 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3392 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3395 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3396 }
3397
3398 if (C.kind == CXCursor_ModuleImportDecl) {
3399 if (pieceIndex > 0)
3400 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 if (const ImportDecl *ImportD =
3402 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3404 if (!Locs.empty())
3405 return cxloc::translateSourceRange(Ctx,
3406 SourceRange(Locs.front(), Locs.back()));
3407 }
3408 return clang_getNullRange();
3409 }
3410
3411 // FIXME: A CXCursor_InclusionDirective should give the location of the
3412 // filename, but we don't keep track of this.
3413
3414 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3415 // but we don't keep track of this.
3416
3417 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3418 // but we don't keep track of this.
3419
3420 // Default handling, give the location of the cursor.
3421
3422 if (pieceIndex > 0)
3423 return clang_getNullRange();
3424
3425 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3426 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3427 return cxloc::translateSourceRange(Ctx, Loc);
3428}
3429
3430CXString clang_getCursorDisplayName(CXCursor C) {
3431 if (!clang_isDeclaration(C.kind))
3432 return clang_getCursorSpelling(C);
3433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003434 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003436 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003437
3438 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003439 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 D = FunTmpl->getTemplatedDecl();
3441
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003442 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 SmallString<64> Str;
3444 llvm::raw_svector_ostream OS(Str);
3445 OS << *Function;
3446 if (Function->getPrimaryTemplate())
3447 OS << "<>";
3448 OS << "(";
3449 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3450 if (I)
3451 OS << ", ";
3452 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3453 }
3454
3455 if (Function->isVariadic()) {
3456 if (Function->getNumParams())
3457 OS << ", ";
3458 OS << "...";
3459 }
3460 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003461 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 }
3463
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 SmallString<64> Str;
3466 llvm::raw_svector_ostream OS(Str);
3467 OS << *ClassTemplate;
3468 OS << "<";
3469 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3470 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3471 if (I)
3472 OS << ", ";
3473
3474 NamedDecl *Param = Params->getParam(I);
3475 if (Param->getIdentifier()) {
3476 OS << Param->getIdentifier()->getName();
3477 continue;
3478 }
3479
3480 // There is no parameter name, which makes this tricky. Try to come up
3481 // with something useful that isn't too long.
3482 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3483 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3484 else if (NonTypeTemplateParmDecl *NTTP
3485 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3486 OS << NTTP->getType().getAsString(Policy);
3487 else
3488 OS << "template<...> class";
3489 }
3490
3491 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 }
3494
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3497 // If the type was explicitly written, use that.
3498 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003499 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003500
Benjamin Kramer9170e912013-02-22 15:46:01 +00003501 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 llvm::raw_svector_ostream OS(Str);
3503 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003504 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 ClassSpec->getTemplateArgs().data(),
3506 ClassSpec->getTemplateArgs().size(),
3507 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 }
3510
3511 return clang_getCursorSpelling(C);
3512}
3513
3514CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3515 switch (Kind) {
3516 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003517 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003519 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003521 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003523 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003525 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003527 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003529 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003531 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003533 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003535 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003537 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003539 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003541 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003543 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003545 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003547 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003549 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003555 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003557 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003565 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003567 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003569 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003571 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003573 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003575 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003579 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003581 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003583 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003585 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003587 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003589 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003593 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003595 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003597 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003599 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003603 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003605 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003609 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003644 case CXCursor_ObjCSelfExpr:
3645 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003762 case CXCursor_PackedAttr:
3763 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003812 case CXCursor_OMPParallelDirective:
3813 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 }
3815
3816 llvm_unreachable("Unhandled CXCursorKind");
3817}
3818
3819struct GetCursorData {
3820 SourceLocation TokenBeginLoc;
3821 bool PointsAtMacroArgExpansion;
3822 bool VisitedObjCPropertyImplDecl;
3823 SourceLocation VisitedDeclaratorDeclStartLoc;
3824 CXCursor &BestCursor;
3825
3826 GetCursorData(SourceManager &SM,
3827 SourceLocation tokenBegin, CXCursor &outputCursor)
3828 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3829 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3830 VisitedObjCPropertyImplDecl = false;
3831 }
3832};
3833
3834static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3835 CXCursor parent,
3836 CXClientData client_data) {
3837 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3838 CXCursor *BestCursor = &Data->BestCursor;
3839
3840 // If we point inside a macro argument we should provide info of what the
3841 // token is so use the actual cursor, don't replace it with a macro expansion
3842 // cursor.
3843 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3844 return CXChildVisit_Recurse;
3845
3846 if (clang_isDeclaration(cursor.kind)) {
3847 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003848 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3850 if (MD->isImplicit())
3851 return CXChildVisit_Break;
3852
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003853 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3855 // Check that when we have multiple @class references in the same line,
3856 // that later ones do not override the previous ones.
3857 // If we have:
3858 // @class Foo, Bar;
3859 // source ranges for both start at '@', so 'Bar' will end up overriding
3860 // 'Foo' even though the cursor location was at 'Foo'.
3861 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3862 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003863 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3865 if (PrevID != ID &&
3866 !PrevID->isThisDeclarationADefinition() &&
3867 !ID->isThisDeclarationADefinition())
3868 return CXChildVisit_Break;
3869 }
3870
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003871 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3873 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3874 // Check that when we have multiple declarators in the same line,
3875 // that later ones do not override the previous ones.
3876 // If we have:
3877 // int Foo, Bar;
3878 // source ranges for both start at 'int', so 'Bar' will end up overriding
3879 // 'Foo' even though the cursor location was at 'Foo'.
3880 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3881 return CXChildVisit_Break;
3882 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003884 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3886 (void)PropImp;
3887 // Check that when we have multiple @synthesize in the same line,
3888 // that later ones do not override the previous ones.
3889 // If we have:
3890 // @synthesize Foo, Bar;
3891 // source ranges for both start at '@', so 'Bar' will end up overriding
3892 // 'Foo' even though the cursor location was at 'Foo'.
3893 if (Data->VisitedObjCPropertyImplDecl)
3894 return CXChildVisit_Break;
3895 Data->VisitedObjCPropertyImplDecl = true;
3896 }
3897 }
3898
3899 if (clang_isExpression(cursor.kind) &&
3900 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003901 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 // Avoid having the cursor of an expression replace the declaration cursor
3903 // when the expression source range overlaps the declaration range.
3904 // This can happen for C++ constructor expressions whose range generally
3905 // include the variable declaration, e.g.:
3906 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3907 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3908 D->getLocation() == Data->TokenBeginLoc)
3909 return CXChildVisit_Break;
3910 }
3911 }
3912
3913 // If our current best cursor is the construction of a temporary object,
3914 // don't replace that cursor with a type reference, because we want
3915 // clang_getCursor() to point at the constructor.
3916 if (clang_isExpression(BestCursor->kind) &&
3917 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3918 cursor.kind == CXCursor_TypeRef) {
3919 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3920 // as having the actual point on the type reference.
3921 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3922 return CXChildVisit_Recurse;
3923 }
3924
3925 *BestCursor = cursor;
3926 return CXChildVisit_Recurse;
3927}
3928
3929CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3930 if (!TU)
3931 return clang_getNullCursor();
3932
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003933 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3935
3936 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3937 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3938
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003939 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 CXFile SearchFile;
3941 unsigned SearchLine, SearchColumn;
3942 CXFile ResultFile;
3943 unsigned ResultLine, ResultColumn;
3944 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3945 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3946 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3947
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003948 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3949 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 &ResultColumn, 0);
3951 SearchFileName = clang_getFileName(SearchFile);
3952 ResultFileName = clang_getFileName(ResultFile);
3953 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3954 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003955 *Log << llvm::format("(%s:%d:%d) = %s",
3956 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3957 clang_getCString(KindSpelling))
3958 << llvm::format("(%s:%d:%d):%s%s",
3959 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3960 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 clang_disposeString(SearchFileName);
3962 clang_disposeString(ResultFileName);
3963 clang_disposeString(KindSpelling);
3964 clang_disposeString(USR);
3965
3966 CXCursor Definition = clang_getCursorDefinition(Result);
3967 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3968 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3969 CXString DefinitionKindSpelling
3970 = clang_getCursorKindSpelling(Definition.kind);
3971 CXFile DefinitionFile;
3972 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003973 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 &DefinitionLine, &DefinitionColumn, 0);
3975 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003976 *Log << llvm::format(" -> %s(%s:%d:%d)",
3977 clang_getCString(DefinitionKindSpelling),
3978 clang_getCString(DefinitionFileName),
3979 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 clang_disposeString(DefinitionFileName);
3981 clang_disposeString(DefinitionKindSpelling);
3982 }
3983 }
3984
3985 return Result;
3986}
3987
3988CXCursor clang_getNullCursor(void) {
3989 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3990}
3991
3992unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00003993 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3994 // can't set consistently. For example, when visiting a DeclStmt we will set
3995 // it but we don't set it on the result of clang_getCursorDefinition for
3996 // a reference of the same declaration.
3997 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3998 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3999 // to provide that kind of info.
4000 if (clang_isDeclaration(X.kind))
4001 X.data[1] = 0;
4002 if (clang_isDeclaration(Y.kind))
4003 Y.data[1] = 0;
4004
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 return X == Y;
4006}
4007
4008unsigned clang_hashCursor(CXCursor C) {
4009 unsigned Index = 0;
4010 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4011 Index = 1;
4012
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004013 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 std::make_pair(C.kind, C.data[Index]));
4015}
4016
4017unsigned clang_isInvalid(enum CXCursorKind K) {
4018 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4019}
4020
4021unsigned clang_isDeclaration(enum CXCursorKind K) {
4022 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4023 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4024}
4025
4026unsigned clang_isReference(enum CXCursorKind K) {
4027 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4028}
4029
4030unsigned clang_isExpression(enum CXCursorKind K) {
4031 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4032}
4033
4034unsigned clang_isStatement(enum CXCursorKind K) {
4035 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4036}
4037
4038unsigned clang_isAttribute(enum CXCursorKind K) {
4039 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4040}
4041
4042unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4043 return K == CXCursor_TranslationUnit;
4044}
4045
4046unsigned clang_isPreprocessing(enum CXCursorKind K) {
4047 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4048}
4049
4050unsigned clang_isUnexposed(enum CXCursorKind K) {
4051 switch (K) {
4052 case CXCursor_UnexposedDecl:
4053 case CXCursor_UnexposedExpr:
4054 case CXCursor_UnexposedStmt:
4055 case CXCursor_UnexposedAttr:
4056 return true;
4057 default:
4058 return false;
4059 }
4060}
4061
4062CXCursorKind clang_getCursorKind(CXCursor C) {
4063 return C.kind;
4064}
4065
4066CXSourceLocation clang_getCursorLocation(CXCursor C) {
4067 if (clang_isReference(C.kind)) {
4068 switch (C.kind) {
4069 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004070 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 = getCursorObjCSuperClassRef(C);
4072 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4073 }
4074
4075 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004076 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 = getCursorObjCProtocolRef(C);
4078 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4079 }
4080
4081 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004082 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 = getCursorObjCClassRef(C);
4084 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4085 }
4086
4087 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004088 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4090 }
4091
4092 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004093 std::pair<const TemplateDecl *, SourceLocation> P =
4094 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4096 }
4097
4098 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004099 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4101 }
4102
4103 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004104 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4106 }
4107
4108 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004109 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4111 }
4112
4113 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004114 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 if (!BaseSpec)
4116 return clang_getNullLocation();
4117
4118 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4119 return cxloc::translateSourceLocation(getCursorContext(C),
4120 TSInfo->getTypeLoc().getBeginLoc());
4121
4122 return cxloc::translateSourceLocation(getCursorContext(C),
4123 BaseSpec->getLocStart());
4124 }
4125
4126 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004127 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4129 }
4130
4131 case CXCursor_OverloadedDeclRef:
4132 return cxloc::translateSourceLocation(getCursorContext(C),
4133 getCursorOverloadedDeclRef(C).second);
4134
4135 default:
4136 // FIXME: Need a way to enumerate all non-reference cases.
4137 llvm_unreachable("Missed a reference kind");
4138 }
4139 }
4140
4141 if (clang_isExpression(C.kind))
4142 return cxloc::translateSourceLocation(getCursorContext(C),
4143 getLocationFromExpr(getCursorExpr(C)));
4144
4145 if (clang_isStatement(C.kind))
4146 return cxloc::translateSourceLocation(getCursorContext(C),
4147 getCursorStmt(C)->getLocStart());
4148
4149 if (C.kind == CXCursor_PreprocessingDirective) {
4150 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4151 return cxloc::translateSourceLocation(getCursorContext(C), L);
4152 }
4153
4154 if (C.kind == CXCursor_MacroExpansion) {
4155 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004156 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 return cxloc::translateSourceLocation(getCursorContext(C), L);
4158 }
4159
4160 if (C.kind == CXCursor_MacroDefinition) {
4161 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4162 return cxloc::translateSourceLocation(getCursorContext(C), L);
4163 }
4164
4165 if (C.kind == CXCursor_InclusionDirective) {
4166 SourceLocation L
4167 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4168 return cxloc::translateSourceLocation(getCursorContext(C), L);
4169 }
4170
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004171 if (clang_isAttribute(C.kind)) {
4172 SourceLocation L
4173 = cxcursor::getCursorAttr(C)->getLocation();
4174 return cxloc::translateSourceLocation(getCursorContext(C), L);
4175 }
4176
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 if (!clang_isDeclaration(C.kind))
4178 return clang_getNullLocation();
4179
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004180 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 if (!D)
4182 return clang_getNullLocation();
4183
4184 SourceLocation Loc = D->getLocation();
4185 // FIXME: Multiple variables declared in a single declaration
4186 // currently lack the information needed to correctly determine their
4187 // ranges when accounting for the type-specifier. We use context
4188 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4189 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004190 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 if (!cxcursor::isFirstInDeclGroup(C))
4192 Loc = VD->getLocation();
4193 }
4194
4195 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004196 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 Loc = MD->getSelectorStartLoc();
4198
4199 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4200}
4201
4202} // end extern "C"
4203
4204CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4205 assert(TU);
4206
4207 // Guard against an invalid SourceLocation, or we may assert in one
4208 // of the following calls.
4209 if (SLoc.isInvalid())
4210 return clang_getNullCursor();
4211
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004212 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004213
4214 // Translate the given source location to make it point at the beginning of
4215 // the token under the cursor.
4216 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4217 CXXUnit->getASTContext().getLangOpts());
4218
4219 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4220 if (SLoc.isValid()) {
4221 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4222 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4223 /*VisitPreprocessorLast=*/true,
4224 /*VisitIncludedEntities=*/false,
4225 SourceLocation(SLoc));
4226 CursorVis.visitFileRegion();
4227 }
4228
4229 return Result;
4230}
4231
4232static SourceRange getRawCursorExtent(CXCursor C) {
4233 if (clang_isReference(C.kind)) {
4234 switch (C.kind) {
4235 case CXCursor_ObjCSuperClassRef:
4236 return getCursorObjCSuperClassRef(C).second;
4237
4238 case CXCursor_ObjCProtocolRef:
4239 return getCursorObjCProtocolRef(C).second;
4240
4241 case CXCursor_ObjCClassRef:
4242 return getCursorObjCClassRef(C).second;
4243
4244 case CXCursor_TypeRef:
4245 return getCursorTypeRef(C).second;
4246
4247 case CXCursor_TemplateRef:
4248 return getCursorTemplateRef(C).second;
4249
4250 case CXCursor_NamespaceRef:
4251 return getCursorNamespaceRef(C).second;
4252
4253 case CXCursor_MemberRef:
4254 return getCursorMemberRef(C).second;
4255
4256 case CXCursor_CXXBaseSpecifier:
4257 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4258
4259 case CXCursor_LabelRef:
4260 return getCursorLabelRef(C).second;
4261
4262 case CXCursor_OverloadedDeclRef:
4263 return getCursorOverloadedDeclRef(C).second;
4264
4265 case CXCursor_VariableRef:
4266 return getCursorVariableRef(C).second;
4267
4268 default:
4269 // FIXME: Need a way to enumerate all non-reference cases.
4270 llvm_unreachable("Missed a reference kind");
4271 }
4272 }
4273
4274 if (clang_isExpression(C.kind))
4275 return getCursorExpr(C)->getSourceRange();
4276
4277 if (clang_isStatement(C.kind))
4278 return getCursorStmt(C)->getSourceRange();
4279
4280 if (clang_isAttribute(C.kind))
4281 return getCursorAttr(C)->getRange();
4282
4283 if (C.kind == CXCursor_PreprocessingDirective)
4284 return cxcursor::getCursorPreprocessingDirective(C);
4285
4286 if (C.kind == CXCursor_MacroExpansion) {
4287 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004288 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 return TU->mapRangeFromPreamble(Range);
4290 }
4291
4292 if (C.kind == CXCursor_MacroDefinition) {
4293 ASTUnit *TU = getCursorASTUnit(C);
4294 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4295 return TU->mapRangeFromPreamble(Range);
4296 }
4297
4298 if (C.kind == CXCursor_InclusionDirective) {
4299 ASTUnit *TU = getCursorASTUnit(C);
4300 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4301 return TU->mapRangeFromPreamble(Range);
4302 }
4303
4304 if (C.kind == CXCursor_TranslationUnit) {
4305 ASTUnit *TU = getCursorASTUnit(C);
4306 FileID MainID = TU->getSourceManager().getMainFileID();
4307 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4308 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4309 return SourceRange(Start, End);
4310 }
4311
4312 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004313 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 if (!D)
4315 return SourceRange();
4316
4317 SourceRange R = D->getSourceRange();
4318 // FIXME: Multiple variables declared in a single declaration
4319 // currently lack the information needed to correctly determine their
4320 // ranges when accounting for the type-specifier. We use context
4321 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4322 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004323 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 if (!cxcursor::isFirstInDeclGroup(C))
4325 R.setBegin(VD->getLocation());
4326 }
4327 return R;
4328 }
4329 return SourceRange();
4330}
4331
4332/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4333/// the decl-specifier-seq for declarations.
4334static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4335 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004336 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004337 if (!D)
4338 return SourceRange();
4339
4340 SourceRange R = D->getSourceRange();
4341
4342 // Adjust the start of the location for declarations preceded by
4343 // declaration specifiers.
4344 SourceLocation StartLoc;
4345 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4346 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4347 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004348 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4350 StartLoc = TI->getTypeLoc().getLocStart();
4351 }
4352
4353 if (StartLoc.isValid() && R.getBegin().isValid() &&
4354 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4355 R.setBegin(StartLoc);
4356
4357 // FIXME: Multiple variables declared in a single declaration
4358 // currently lack the information needed to correctly determine their
4359 // ranges when accounting for the type-specifier. We use context
4360 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4361 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004362 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 if (!cxcursor::isFirstInDeclGroup(C))
4364 R.setBegin(VD->getLocation());
4365 }
4366
4367 return R;
4368 }
4369
4370 return getRawCursorExtent(C);
4371}
4372
4373extern "C" {
4374
4375CXSourceRange clang_getCursorExtent(CXCursor C) {
4376 SourceRange R = getRawCursorExtent(C);
4377 if (R.isInvalid())
4378 return clang_getNullRange();
4379
4380 return cxloc::translateSourceRange(getCursorContext(C), R);
4381}
4382
4383CXCursor clang_getCursorReferenced(CXCursor C) {
4384 if (clang_isInvalid(C.kind))
4385 return clang_getNullCursor();
4386
4387 CXTranslationUnit tu = getCursorTU(C);
4388 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004389 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 if (!D)
4391 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004392 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004394 if (const ObjCPropertyImplDecl *PropImpl =
4395 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4397 return MakeCXCursor(Property, tu);
4398
4399 return C;
4400 }
4401
4402 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 const Expr *E = getCursorExpr(C);
4404 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 if (D) {
4406 CXCursor declCursor = MakeCXCursor(D, tu);
4407 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4408 declCursor);
4409 return declCursor;
4410 }
4411
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 return MakeCursorOverloadedDeclRef(Ovl, tu);
4414
4415 return clang_getNullCursor();
4416 }
4417
4418 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004419 const Stmt *S = getCursorStmt(C);
4420 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 if (LabelDecl *label = Goto->getLabel())
4422 if (LabelStmt *labelS = label->getStmt())
4423 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4424
4425 return clang_getNullCursor();
4426 }
4427
4428 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004429 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 return MakeMacroDefinitionCursor(Def, tu);
4431 }
4432
4433 if (!clang_isReference(C.kind))
4434 return clang_getNullCursor();
4435
4436 switch (C.kind) {
4437 case CXCursor_ObjCSuperClassRef:
4438 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4439
4440 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004441 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4442 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 return MakeCXCursor(Def, tu);
4444
4445 return MakeCXCursor(Prot, tu);
4446 }
4447
4448 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004449 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4450 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 return MakeCXCursor(Def, tu);
4452
4453 return MakeCXCursor(Class, tu);
4454 }
4455
4456 case CXCursor_TypeRef:
4457 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4458
4459 case CXCursor_TemplateRef:
4460 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4461
4462 case CXCursor_NamespaceRef:
4463 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4464
4465 case CXCursor_MemberRef:
4466 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4467
4468 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004469 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4471 tu ));
4472 }
4473
4474 case CXCursor_LabelRef:
4475 // FIXME: We end up faking the "parent" declaration here because we
4476 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004477 return MakeCXCursor(getCursorLabelRef(C).first,
4478 cxtu::getASTUnit(tu)->getASTContext()
4479 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 tu);
4481
4482 case CXCursor_OverloadedDeclRef:
4483 return C;
4484
4485 case CXCursor_VariableRef:
4486 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4487
4488 default:
4489 // We would prefer to enumerate all non-reference cursor kinds here.
4490 llvm_unreachable("Unhandled reference cursor kind");
4491 }
4492}
4493
4494CXCursor clang_getCursorDefinition(CXCursor C) {
4495 if (clang_isInvalid(C.kind))
4496 return clang_getNullCursor();
4497
4498 CXTranslationUnit TU = getCursorTU(C);
4499
4500 bool WasReference = false;
4501 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4502 C = clang_getCursorReferenced(C);
4503 WasReference = true;
4504 }
4505
4506 if (C.kind == CXCursor_MacroExpansion)
4507 return clang_getCursorReferenced(C);
4508
4509 if (!clang_isDeclaration(C.kind))
4510 return clang_getNullCursor();
4511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 if (!D)
4514 return clang_getNullCursor();
4515
4516 switch (D->getKind()) {
4517 // Declaration kinds that don't really separate the notions of
4518 // declaration and definition.
4519 case Decl::Namespace:
4520 case Decl::Typedef:
4521 case Decl::TypeAlias:
4522 case Decl::TypeAliasTemplate:
4523 case Decl::TemplateTypeParm:
4524 case Decl::EnumConstant:
4525 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004526 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case Decl::IndirectField:
4528 case Decl::ObjCIvar:
4529 case Decl::ObjCAtDefsField:
4530 case Decl::ImplicitParam:
4531 case Decl::ParmVar:
4532 case Decl::NonTypeTemplateParm:
4533 case Decl::TemplateTemplateParm:
4534 case Decl::ObjCCategoryImpl:
4535 case Decl::ObjCImplementation:
4536 case Decl::AccessSpec:
4537 case Decl::LinkageSpec:
4538 case Decl::ObjCPropertyImpl:
4539 case Decl::FileScopeAsm:
4540 case Decl::StaticAssert:
4541 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004542 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case Decl::Label: // FIXME: Is this right??
4544 case Decl::ClassScopeFunctionSpecialization:
4545 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004546 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 return C;
4548
4549 // Declaration kinds that don't make any sense here, but are
4550 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004551 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case Decl::TranslationUnit:
4553 break;
4554
4555 // Declaration kinds for which the definition is not resolvable.
4556 case Decl::UnresolvedUsingTypename:
4557 case Decl::UnresolvedUsingValue:
4558 break;
4559
4560 case Decl::UsingDirective:
4561 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4562 TU);
4563
4564 case Decl::NamespaceAlias:
4565 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4566
4567 case Decl::Enum:
4568 case Decl::Record:
4569 case Decl::CXXRecord:
4570 case Decl::ClassTemplateSpecialization:
4571 case Decl::ClassTemplatePartialSpecialization:
4572 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4573 return MakeCXCursor(Def, TU);
4574 return clang_getNullCursor();
4575
4576 case Decl::Function:
4577 case Decl::CXXMethod:
4578 case Decl::CXXConstructor:
4579 case Decl::CXXDestructor:
4580 case Decl::CXXConversion: {
4581 const FunctionDecl *Def = 0;
4582 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004583 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 return clang_getNullCursor();
4585 }
4586
Larisse Voufo39a1e502013-08-06 01:03:05 +00004587 case Decl::Var:
4588 case Decl::VarTemplateSpecialization:
4589 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004591 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 return MakeCXCursor(Def, TU);
4593 return clang_getNullCursor();
4594 }
4595
4596 case Decl::FunctionTemplate: {
4597 const FunctionDecl *Def = 0;
4598 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4599 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4600 return clang_getNullCursor();
4601 }
4602
4603 case Decl::ClassTemplate: {
4604 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4605 ->getDefinition())
4606 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4607 TU);
4608 return clang_getNullCursor();
4609 }
4610
Larisse Voufo39a1e502013-08-06 01:03:05 +00004611 case Decl::VarTemplate: {
4612 if (VarDecl *Def =
4613 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4614 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4615 return clang_getNullCursor();
4616 }
4617
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 case Decl::Using:
4619 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4620 D->getLocation(), TU);
4621
4622 case Decl::UsingShadow:
4623 return clang_getCursorDefinition(
4624 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4625 TU));
4626
4627 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004628 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 if (Method->isThisDeclarationADefinition())
4630 return C;
4631
4632 // Dig out the method definition in the associated
4633 // @implementation, if we have it.
4634 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004635 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4637 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4638 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4639 Method->isInstanceMethod()))
4640 if (Def->isThisDeclarationADefinition())
4641 return MakeCXCursor(Def, TU);
4642
4643 return clang_getNullCursor();
4644 }
4645
4646 case Decl::ObjCCategory:
4647 if (ObjCCategoryImplDecl *Impl
4648 = cast<ObjCCategoryDecl>(D)->getImplementation())
4649 return MakeCXCursor(Impl, TU);
4650 return clang_getNullCursor();
4651
4652 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004653 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 return MakeCXCursor(Def, TU);
4655 return clang_getNullCursor();
4656
4657 case Decl::ObjCInterface: {
4658 // There are two notions of a "definition" for an Objective-C
4659 // class: the interface and its implementation. When we resolved a
4660 // reference to an Objective-C class, produce the @interface as
4661 // the definition; when we were provided with the interface,
4662 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004663 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004665 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 return MakeCXCursor(Def, TU);
4667 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4668 return MakeCXCursor(Impl, TU);
4669 return clang_getNullCursor();
4670 }
4671
4672 case Decl::ObjCProperty:
4673 // FIXME: We don't really know where to find the
4674 // ObjCPropertyImplDecls that implement this property.
4675 return clang_getNullCursor();
4676
4677 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004678 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004680 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 return MakeCXCursor(Def, TU);
4682
4683 return clang_getNullCursor();
4684
4685 case Decl::Friend:
4686 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4687 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4688 return clang_getNullCursor();
4689
4690 case Decl::FriendTemplate:
4691 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4692 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4693 return clang_getNullCursor();
4694 }
4695
4696 return clang_getNullCursor();
4697}
4698
4699unsigned clang_isCursorDefinition(CXCursor C) {
4700 if (!clang_isDeclaration(C.kind))
4701 return 0;
4702
4703 return clang_getCursorDefinition(C) == C;
4704}
4705
4706CXCursor clang_getCanonicalCursor(CXCursor C) {
4707 if (!clang_isDeclaration(C.kind))
4708 return C;
4709
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004710 if (const Decl *D = getCursorDecl(C)) {
4711 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4713 return MakeCXCursor(CatD, getCursorTU(C));
4714
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004715 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4716 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 return MakeCXCursor(IFD, getCursorTU(C));
4718
4719 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4720 }
4721
4722 return C;
4723}
4724
4725int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4726 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4727}
4728
4729unsigned clang_getNumOverloadedDecls(CXCursor C) {
4730 if (C.kind != CXCursor_OverloadedDeclRef)
4731 return 0;
4732
4733 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004734 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 return E->getNumDecls();
4736
4737 if (OverloadedTemplateStorage *S
4738 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4739 return S->size();
4740
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004741 const Decl *D = Storage.get<const Decl *>();
4742 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 return Using->shadow_size();
4744
4745 return 0;
4746}
4747
4748CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4749 if (cursor.kind != CXCursor_OverloadedDeclRef)
4750 return clang_getNullCursor();
4751
4752 if (index >= clang_getNumOverloadedDecls(cursor))
4753 return clang_getNullCursor();
4754
4755 CXTranslationUnit TU = getCursorTU(cursor);
4756 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004757 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 return MakeCXCursor(E->decls_begin()[index], TU);
4759
4760 if (OverloadedTemplateStorage *S
4761 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4762 return MakeCXCursor(S->begin()[index], TU);
4763
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004764 const Decl *D = Storage.get<const Decl *>();
4765 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 // FIXME: This is, unfortunately, linear time.
4767 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4768 std::advance(Pos, index);
4769 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4770 }
4771
4772 return clang_getNullCursor();
4773}
4774
4775void clang_getDefinitionSpellingAndExtent(CXCursor C,
4776 const char **startBuf,
4777 const char **endBuf,
4778 unsigned *startLine,
4779 unsigned *startColumn,
4780 unsigned *endLine,
4781 unsigned *endColumn) {
4782 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4785
4786 SourceManager &SM = FD->getASTContext().getSourceManager();
4787 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4788 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4789 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4790 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4791 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4792 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4793}
4794
4795
4796CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4797 unsigned PieceIndex) {
4798 RefNamePieces Pieces;
4799
4800 switch (C.kind) {
4801 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004802 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4804 E->getQualifierLoc().getSourceRange());
4805 break;
4806
4807 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004808 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4810 E->getQualifierLoc().getSourceRange(),
4811 E->getOptionalExplicitTemplateArgs());
4812 break;
4813
4814 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004815 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004816 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004817 const Expr *Callee = OCE->getCallee();
4818 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 Callee = ICE->getSubExpr();
4820
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004821 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4823 DRE->getQualifierLoc().getSourceRange());
4824 }
4825 break;
4826
4827 default:
4828 break;
4829 }
4830
4831 if (Pieces.empty()) {
4832 if (PieceIndex == 0)
4833 return clang_getCursorExtent(C);
4834 } else if (PieceIndex < Pieces.size()) {
4835 SourceRange R = Pieces[PieceIndex];
4836 if (R.isValid())
4837 return cxloc::translateSourceRange(getCursorContext(C), R);
4838 }
4839
4840 return clang_getNullRange();
4841}
4842
4843void clang_enableStackTraces(void) {
4844 llvm::sys::PrintStackTraceOnErrorSignal();
4845}
4846
4847void clang_executeOnThread(void (*fn)(void*), void *user_data,
4848 unsigned stack_size) {
4849 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4850}
4851
4852} // end: extern "C"
4853
4854//===----------------------------------------------------------------------===//
4855// Token-based Operations.
4856//===----------------------------------------------------------------------===//
4857
4858/* CXToken layout:
4859 * int_data[0]: a CXTokenKind
4860 * int_data[1]: starting token location
4861 * int_data[2]: token length
4862 * int_data[3]: reserved
4863 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4864 * otherwise unused.
4865 */
4866extern "C" {
4867
4868CXTokenKind clang_getTokenKind(CXToken CXTok) {
4869 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4870}
4871
4872CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4873 switch (clang_getTokenKind(CXTok)) {
4874 case CXToken_Identifier:
4875 case CXToken_Keyword:
4876 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004877 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004878 ->getNameStart());
4879
4880 case CXToken_Literal: {
4881 // We have stashed the starting pointer in the ptr_data field. Use it.
4882 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004883 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 }
4885
4886 case CXToken_Punctuation:
4887 case CXToken_Comment:
4888 break;
4889 }
4890
4891 // We have to find the starting buffer pointer the hard way, by
4892 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004893 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004895 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004896
4897 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4898 std::pair<FileID, unsigned> LocInfo
4899 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4900 bool Invalid = false;
4901 StringRef Buffer
4902 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4903 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004904 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004905
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004906 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004907}
4908
4909CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004910 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 if (!CXXUnit)
4912 return clang_getNullLocation();
4913
4914 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4915 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4916}
4917
4918CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004919 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 if (!CXXUnit)
4921 return clang_getNullRange();
4922
4923 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4924 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4925}
4926
4927static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4928 SmallVectorImpl<CXToken> &CXTokens) {
4929 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4930 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004931 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004933 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004934
4935 // Cannot tokenize across files.
4936 if (BeginLocInfo.first != EndLocInfo.first)
4937 return;
4938
4939 // Create a lexer
4940 bool Invalid = false;
4941 StringRef Buffer
4942 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4943 if (Invalid)
4944 return;
4945
4946 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4947 CXXUnit->getASTContext().getLangOpts(),
4948 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4949 Lex.SetCommentRetentionState(true);
4950
4951 // Lex tokens until we hit the end of the range.
4952 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4953 Token Tok;
4954 bool previousWasAt = false;
4955 do {
4956 // Lex the next token
4957 Lex.LexFromRawLexer(Tok);
4958 if (Tok.is(tok::eof))
4959 break;
4960
4961 // Initialize the CXToken.
4962 CXToken CXTok;
4963
4964 // - Common fields
4965 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4966 CXTok.int_data[2] = Tok.getLength();
4967 CXTok.int_data[3] = 0;
4968
4969 // - Kind-specific fields
4970 if (Tok.isLiteral()) {
4971 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004972 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 } else if (Tok.is(tok::raw_identifier)) {
4974 // Lookup the identifier to determine whether we have a keyword.
4975 IdentifierInfo *II
4976 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4977
4978 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4979 CXTok.int_data[0] = CXToken_Keyword;
4980 }
4981 else {
4982 CXTok.int_data[0] = Tok.is(tok::identifier)
4983 ? CXToken_Identifier
4984 : CXToken_Keyword;
4985 }
4986 CXTok.ptr_data = II;
4987 } else if (Tok.is(tok::comment)) {
4988 CXTok.int_data[0] = CXToken_Comment;
4989 CXTok.ptr_data = 0;
4990 } else {
4991 CXTok.int_data[0] = CXToken_Punctuation;
4992 CXTok.ptr_data = 0;
4993 }
4994 CXTokens.push_back(CXTok);
4995 previousWasAt = Tok.is(tok::at);
4996 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4997}
4998
4999void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5000 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005001 LOG_FUNC_SECTION {
5002 *Log << TU << ' ' << Range;
5003 }
5004
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 if (Tokens)
5006 *Tokens = 0;
5007 if (NumTokens)
5008 *NumTokens = 0;
5009
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005010 if (!TU)
5011 return;
5012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 if (!CXXUnit || !Tokens || !NumTokens)
5015 return;
5016
5017 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5018
5019 SourceRange R = cxloc::translateCXSourceRange(Range);
5020 if (R.isInvalid())
5021 return;
5022
5023 SmallVector<CXToken, 32> CXTokens;
5024 getTokens(CXXUnit, R, CXTokens);
5025
5026 if (CXTokens.empty())
5027 return;
5028
5029 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5030 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5031 *NumTokens = CXTokens.size();
5032}
5033
5034void clang_disposeTokens(CXTranslationUnit TU,
5035 CXToken *Tokens, unsigned NumTokens) {
5036 free(Tokens);
5037}
5038
5039} // end: extern "C"
5040
5041//===----------------------------------------------------------------------===//
5042// Token annotation APIs.
5043//===----------------------------------------------------------------------===//
5044
Guy Benyei11169dd2012-12-18 14:30:41 +00005045static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5046 CXCursor parent,
5047 CXClientData client_data);
5048static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5049 CXClientData client_data);
5050
5051namespace {
5052class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 CXToken *Tokens;
5054 CXCursor *Cursors;
5055 unsigned NumTokens;
5056 unsigned TokIdx;
5057 unsigned PreprocessingTokIdx;
5058 CursorVisitor AnnotateVis;
5059 SourceManager &SrcMgr;
5060 bool HasContextSensitiveKeywords;
5061
5062 struct PostChildrenInfo {
5063 CXCursor Cursor;
5064 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005065 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 unsigned BeforeChildrenTokenIdx;
5067 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005068 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005069
5070 CXToken &getTok(unsigned Idx) {
5071 assert(Idx < NumTokens);
5072 return Tokens[Idx];
5073 }
5074 const CXToken &getTok(unsigned Idx) const {
5075 assert(Idx < NumTokens);
5076 return Tokens[Idx];
5077 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 bool MoreTokens() const { return TokIdx < NumTokens; }
5079 unsigned NextToken() const { return TokIdx; }
5080 void AdvanceToken() { ++TokIdx; }
5081 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005082 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 }
5084 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005085 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 }
5087 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005088 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 }
5090
5091 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005092 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 SourceRange);
5094
5095public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005096 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005097 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005098 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005100 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 AnnotateTokensVisitor, this,
5102 /*VisitPreprocessorLast=*/true,
5103 /*VisitIncludedEntities=*/false,
5104 RegionOfInterest,
5105 /*VisitDeclsOnly=*/false,
5106 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005107 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 HasContextSensitiveKeywords(false) { }
5109
5110 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5111 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5112 bool postVisitChildren(CXCursor cursor);
5113 void AnnotateTokens();
5114
5115 /// \brief Determine whether the annotator saw any cursors that have
5116 /// context-sensitive keywords.
5117 bool hasContextSensitiveKeywords() const {
5118 return HasContextSensitiveKeywords;
5119 }
5120
5121 ~AnnotateTokensWorker() {
5122 assert(PostChildrenInfos.empty());
5123 }
5124};
5125}
5126
5127void AnnotateTokensWorker::AnnotateTokens() {
5128 // Walk the AST within the region of interest, annotating tokens
5129 // along the way.
5130 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005131}
Guy Benyei11169dd2012-12-18 14:30:41 +00005132
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005133static inline void updateCursorAnnotation(CXCursor &Cursor,
5134 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005135 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005137 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005138}
5139
5140/// \brief It annotates and advances tokens with a cursor until the comparison
5141//// between the cursor location and the source range is the same as
5142/// \arg compResult.
5143///
5144/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5145/// Pass RangeOverlap to annotate tokens inside a range.
5146void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5147 RangeComparisonResult compResult,
5148 SourceRange range) {
5149 while (MoreTokens()) {
5150 const unsigned I = NextToken();
5151 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005152 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5153 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005154
5155 SourceLocation TokLoc = GetTokenLoc(I);
5156 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005157 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 AdvanceToken();
5159 continue;
5160 }
5161 break;
5162 }
5163}
5164
5165/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005166/// \returns true if it advanced beyond all macro tokens, false otherwise.
5167bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 CXCursor updateC,
5169 RangeComparisonResult compResult,
5170 SourceRange range) {
5171 assert(MoreTokens());
5172 assert(isFunctionMacroToken(NextToken()) &&
5173 "Should be called only for macro arg tokens");
5174
5175 // This works differently than annotateAndAdvanceTokens; because expanded
5176 // macro arguments can have arbitrary translation-unit source order, we do not
5177 // advance the token index one by one until a token fails the range test.
5178 // We only advance once past all of the macro arg tokens if all of them
5179 // pass the range test. If one of them fails we keep the token index pointing
5180 // at the start of the macro arg tokens so that the failing token will be
5181 // annotated by a subsequent annotation try.
5182
5183 bool atLeastOneCompFail = false;
5184
5185 unsigned I = NextToken();
5186 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5187 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5188 if (TokLoc.isFileID())
5189 continue; // not macro arg token, it's parens or comma.
5190 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5191 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5192 Cursors[I] = updateC;
5193 } else
5194 atLeastOneCompFail = true;
5195 }
5196
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005197 if (atLeastOneCompFail)
5198 return false;
5199
5200 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5201 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005202}
5203
5204enum CXChildVisitResult
5205AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 SourceRange cursorRange = getRawCursorExtent(cursor);
5207 if (cursorRange.isInvalid())
5208 return CXChildVisit_Recurse;
5209
5210 if (!HasContextSensitiveKeywords) {
5211 // Objective-C properties can have context-sensitive keywords.
5212 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005213 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5215 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5216 }
5217 // Objective-C methods can have context-sensitive keywords.
5218 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5219 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005220 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5222 if (Method->getObjCDeclQualifier())
5223 HasContextSensitiveKeywords = true;
5224 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005225 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5226 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 P != PEnd; ++P) {
5228 if ((*P)->getObjCDeclQualifier()) {
5229 HasContextSensitiveKeywords = true;
5230 break;
5231 }
5232 }
5233 }
5234 }
5235 }
5236 // C++ methods can have context-sensitive keywords.
5237 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005238 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5240 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5241 HasContextSensitiveKeywords = true;
5242 }
5243 }
5244 // C++ classes can have context-sensitive keywords.
5245 else if (cursor.kind == CXCursor_StructDecl ||
5246 cursor.kind == CXCursor_ClassDecl ||
5247 cursor.kind == CXCursor_ClassTemplate ||
5248 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005249 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 if (D->hasAttr<FinalAttr>())
5251 HasContextSensitiveKeywords = true;
5252 }
5253 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005254
5255 // Don't override a property annotation with its getter/setter method.
5256 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5257 parent.kind == CXCursor_ObjCPropertyDecl)
5258 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005259
5260 if (clang_isPreprocessing(cursor.kind)) {
5261 // Items in the preprocessing record are kept separate from items in
5262 // declarations, so we keep a separate token index.
5263 unsigned SavedTokIdx = TokIdx;
5264 TokIdx = PreprocessingTokIdx;
5265
5266 // Skip tokens up until we catch up to the beginning of the preprocessing
5267 // entry.
5268 while (MoreTokens()) {
5269 const unsigned I = NextToken();
5270 SourceLocation TokLoc = GetTokenLoc(I);
5271 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5272 case RangeBefore:
5273 AdvanceToken();
5274 continue;
5275 case RangeAfter:
5276 case RangeOverlap:
5277 break;
5278 }
5279 break;
5280 }
5281
5282 // Look at all of the tokens within this range.
5283 while (MoreTokens()) {
5284 const unsigned I = NextToken();
5285 SourceLocation TokLoc = GetTokenLoc(I);
5286 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5287 case RangeBefore:
5288 llvm_unreachable("Infeasible");
5289 case RangeAfter:
5290 break;
5291 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005292 // For macro expansions, just note where the beginning of the macro
5293 // expansion occurs.
5294 if (cursor.kind == CXCursor_MacroExpansion) {
5295 if (TokLoc == cursorRange.getBegin())
5296 Cursors[I] = cursor;
5297 AdvanceToken();
5298 break;
5299 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005300 // We may have already annotated macro names inside macro definitions.
5301 if (Cursors[I].kind != CXCursor_MacroExpansion)
5302 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 continue;
5305 }
5306 break;
5307 }
5308
5309 // Save the preprocessing token index; restore the non-preprocessing
5310 // token index.
5311 PreprocessingTokIdx = TokIdx;
5312 TokIdx = SavedTokIdx;
5313 return CXChildVisit_Recurse;
5314 }
5315
5316 if (cursorRange.isInvalid())
5317 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005318
5319 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 const enum CXCursorKind K = clang_getCursorKind(parent);
5322 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005323 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5324 // Attributes are annotated out-of-order, skip tokens until we reach it.
5325 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 ? clang_getNullCursor() : parent;
5327
5328 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5329
5330 // Avoid having the cursor of an expression "overwrite" the annotation of the
5331 // variable declaration that it belongs to.
5332 // This can happen for C++ constructor expressions whose range generally
5333 // include the variable declaration, e.g.:
5334 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005335 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005336 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005337 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 const unsigned I = NextToken();
5339 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5340 E->getLocStart() == D->getLocation() &&
5341 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005342 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 AdvanceToken();
5344 }
5345 }
5346 }
5347
5348 // Before recursing into the children keep some state that we are going
5349 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5350 // extra work after the child nodes are visited.
5351 // Note that we don't call VisitChildren here to avoid traversing statements
5352 // code-recursively which can blow the stack.
5353
5354 PostChildrenInfo Info;
5355 Info.Cursor = cursor;
5356 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005357 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 Info.BeforeChildrenTokenIdx = NextToken();
5359 PostChildrenInfos.push_back(Info);
5360
5361 return CXChildVisit_Recurse;
5362}
5363
5364bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5365 if (PostChildrenInfos.empty())
5366 return false;
5367 const PostChildrenInfo &Info = PostChildrenInfos.back();
5368 if (!clang_equalCursors(Info.Cursor, cursor))
5369 return false;
5370
5371 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5372 const unsigned AfterChildren = NextToken();
5373 SourceRange cursorRange = Info.CursorRange;
5374
5375 // Scan the tokens that are at the end of the cursor, but are not captured
5376 // but the child cursors.
5377 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5378
5379 // Scan the tokens that are at the beginning of the cursor, but are not
5380 // capture by the child cursors.
5381 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5382 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5383 break;
5384
5385 Cursors[I] = cursor;
5386 }
5387
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005388 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5389 // encountered the attribute cursor.
5390 if (clang_isAttribute(cursor.kind))
5391 TokIdx = Info.BeforeReachingCursorIdx;
5392
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 PostChildrenInfos.pop_back();
5394 return false;
5395}
5396
5397static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5398 CXCursor parent,
5399 CXClientData client_data) {
5400 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5401}
5402
5403static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5404 CXClientData client_data) {
5405 return static_cast<AnnotateTokensWorker*>(client_data)->
5406 postVisitChildren(cursor);
5407}
5408
5409namespace {
5410
5411/// \brief Uses the macro expansions in the preprocessing record to find
5412/// and mark tokens that are macro arguments. This info is used by the
5413/// AnnotateTokensWorker.
5414class MarkMacroArgTokensVisitor {
5415 SourceManager &SM;
5416 CXToken *Tokens;
5417 unsigned NumTokens;
5418 unsigned CurIdx;
5419
5420public:
5421 MarkMacroArgTokensVisitor(SourceManager &SM,
5422 CXToken *tokens, unsigned numTokens)
5423 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5424
5425 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5426 if (cursor.kind != CXCursor_MacroExpansion)
5427 return CXChildVisit_Continue;
5428
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005429 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 if (macroRange.getBegin() == macroRange.getEnd())
5431 return CXChildVisit_Continue; // it's not a function macro.
5432
5433 for (; CurIdx < NumTokens; ++CurIdx) {
5434 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5435 macroRange.getBegin()))
5436 break;
5437 }
5438
5439 if (CurIdx == NumTokens)
5440 return CXChildVisit_Break;
5441
5442 for (; CurIdx < NumTokens; ++CurIdx) {
5443 SourceLocation tokLoc = getTokenLoc(CurIdx);
5444 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5445 break;
5446
5447 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5448 }
5449
5450 if (CurIdx == NumTokens)
5451 return CXChildVisit_Break;
5452
5453 return CXChildVisit_Continue;
5454 }
5455
5456private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005457 CXToken &getTok(unsigned Idx) {
5458 assert(Idx < NumTokens);
5459 return Tokens[Idx];
5460 }
5461 const CXToken &getTok(unsigned Idx) const {
5462 assert(Idx < NumTokens);
5463 return Tokens[Idx];
5464 }
5465
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005467 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 }
5469
5470 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5471 // The third field is reserved and currently not used. Use it here
5472 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005473 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 }
5475};
5476
5477} // end anonymous namespace
5478
5479static CXChildVisitResult
5480MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5481 CXClientData client_data) {
5482 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5483 parent);
5484}
5485
5486namespace {
5487 struct clang_annotateTokens_Data {
5488 CXTranslationUnit TU;
5489 ASTUnit *CXXUnit;
5490 CXToken *Tokens;
5491 unsigned NumTokens;
5492 CXCursor *Cursors;
5493 };
5494}
5495
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005496/// \brief Used by \c annotatePreprocessorTokens.
5497/// \returns true if lexing was finished, false otherwise.
5498static bool lexNext(Lexer &Lex, Token &Tok,
5499 unsigned &NextIdx, unsigned NumTokens) {
5500 if (NextIdx >= NumTokens)
5501 return true;
5502
5503 ++NextIdx;
5504 Lex.LexFromRawLexer(Tok);
5505 if (Tok.is(tok::eof))
5506 return true;
5507
5508 return false;
5509}
5510
Guy Benyei11169dd2012-12-18 14:30:41 +00005511static void annotatePreprocessorTokens(CXTranslationUnit TU,
5512 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005513 CXCursor *Cursors,
5514 CXToken *Tokens,
5515 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005516 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005517
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005518 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5520 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005521 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005523 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005524
5525 if (BeginLocInfo.first != EndLocInfo.first)
5526 return;
5527
5528 StringRef Buffer;
5529 bool Invalid = false;
5530 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5531 if (Buffer.empty() || Invalid)
5532 return;
5533
5534 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5535 CXXUnit->getASTContext().getLangOpts(),
5536 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5537 Buffer.end());
5538 Lex.SetCommentRetentionState(true);
5539
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005540 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 // Lex tokens in raw mode until we hit the end of the range, to avoid
5542 // entering #includes or expanding macros.
5543 while (true) {
5544 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005545 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5546 break;
5547 unsigned TokIdx = NextIdx-1;
5548 assert(Tok.getLocation() ==
5549 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005550
5551 reprocess:
5552 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005553 // We have found a preprocessing directive. Annotate the tokens
5554 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 //
5556 // FIXME: Some simple tests here could identify macro definitions and
5557 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005558
5559 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005560 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5561 break;
5562
5563 MacroInfo *MI = 0;
5564 if (Tok.is(tok::raw_identifier) &&
5565 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5566 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5567 break;
5568
5569 if (Tok.is(tok::raw_identifier)) {
5570 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5571 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5572 SourceLocation MappedTokLoc =
5573 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5574 MI = getMacroInfo(II, MappedTokLoc, TU);
5575 }
5576 }
5577
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005578 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005580 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5581 finished = true;
5582 break;
5583 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005584 // If we are in a macro definition, check if the token was ever a
5585 // macro name and annotate it if that's the case.
5586 if (MI) {
5587 SourceLocation SaveLoc = Tok.getLocation();
5588 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5589 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5590 Tok.setLocation(SaveLoc);
5591 if (MacroDef)
5592 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5593 Tok.getLocation(), TU);
5594 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005595 } while (!Tok.isAtStartOfLine());
5596
5597 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5598 assert(TokIdx <= LastIdx);
5599 SourceLocation EndLoc =
5600 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5601 CXCursor Cursor =
5602 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5603
5604 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005605 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005606
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005607 if (finished)
5608 break;
5609 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 }
5612}
5613
5614// This gets run a separate thread to avoid stack blowout.
5615static void clang_annotateTokensImpl(void *UserData) {
5616 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5617 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5618 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5619 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5620 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5621
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005622 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5624 setThreadBackgroundPriority();
5625
5626 // Determine the region of interest, which contains all of the tokens.
5627 SourceRange RegionOfInterest;
5628 RegionOfInterest.setBegin(
5629 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5630 RegionOfInterest.setEnd(
5631 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5632 Tokens[NumTokens-1])));
5633
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 // Relex the tokens within the source range to look for preprocessing
5635 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005636 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005637
5638 // If begin location points inside a macro argument, set it to the expansion
5639 // location so we can have the full context when annotating semantically.
5640 {
5641 SourceManager &SM = CXXUnit->getSourceManager();
5642 SourceLocation Loc =
5643 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5644 if (Loc.isMacroID())
5645 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5646 }
5647
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5649 // Search and mark tokens that are macro argument expansions.
5650 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5651 Tokens, NumTokens);
5652 CursorVisitor MacroArgMarker(TU,
5653 MarkMacroArgTokensVisitorDelegate, &Visitor,
5654 /*VisitPreprocessorLast=*/true,
5655 /*VisitIncludedEntities=*/false,
5656 RegionOfInterest);
5657 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5658 }
5659
5660 // Annotate all of the source locations in the region of interest that map to
5661 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005662 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005663
5664 // FIXME: We use a ridiculous stack size here because the data-recursion
5665 // algorithm uses a large stack frame than the non-data recursive version,
5666 // and AnnotationTokensWorker currently transforms the data-recursion
5667 // algorithm back into a traditional recursion by explicitly calling
5668 // VisitChildren(). We will need to remove this explicit recursive call.
5669 W.AnnotateTokens();
5670
5671 // If we ran into any entities that involve context-sensitive keywords,
5672 // take another pass through the tokens to mark them as such.
5673 if (W.hasContextSensitiveKeywords()) {
5674 for (unsigned I = 0; I != NumTokens; ++I) {
5675 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5676 continue;
5677
5678 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5679 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005680 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5682 if (Property->getPropertyAttributesAsWritten() != 0 &&
5683 llvm::StringSwitch<bool>(II->getName())
5684 .Case("readonly", true)
5685 .Case("assign", true)
5686 .Case("unsafe_unretained", true)
5687 .Case("readwrite", true)
5688 .Case("retain", true)
5689 .Case("copy", true)
5690 .Case("nonatomic", true)
5691 .Case("atomic", true)
5692 .Case("getter", true)
5693 .Case("setter", true)
5694 .Case("strong", true)
5695 .Case("weak", true)
5696 .Default(false))
5697 Tokens[I].int_data[0] = CXToken_Keyword;
5698 }
5699 continue;
5700 }
5701
5702 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5703 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5704 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5705 if (llvm::StringSwitch<bool>(II->getName())
5706 .Case("in", true)
5707 .Case("out", true)
5708 .Case("inout", true)
5709 .Case("oneway", true)
5710 .Case("bycopy", true)
5711 .Case("byref", true)
5712 .Default(false))
5713 Tokens[I].int_data[0] = CXToken_Keyword;
5714 continue;
5715 }
5716
5717 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5718 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5719 Tokens[I].int_data[0] = CXToken_Keyword;
5720 continue;
5721 }
5722 }
5723 }
5724}
5725
5726extern "C" {
5727
5728void clang_annotateTokens(CXTranslationUnit TU,
5729 CXToken *Tokens, unsigned NumTokens,
5730 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005731 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005732 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005734 }
5735
5736 LOG_FUNC_SECTION {
5737 *Log << TU << ' ';
5738 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5739 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5740 *Log << clang_getRange(bloc, eloc);
5741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005742
5743 // Any token we don't specifically annotate will have a NULL cursor.
5744 CXCursor C = clang_getNullCursor();
5745 for (unsigned I = 0; I != NumTokens; ++I)
5746 Cursors[I] = C;
5747
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005748 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 if (!CXXUnit)
5750 return;
5751
5752 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5753
5754 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5755 llvm::CrashRecoveryContext CRC;
5756 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5757 GetSafetyThreadStackSize() * 2)) {
5758 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5759 }
5760}
5761
5762} // end: extern "C"
5763
5764//===----------------------------------------------------------------------===//
5765// Operations for querying linkage of a cursor.
5766//===----------------------------------------------------------------------===//
5767
5768extern "C" {
5769CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5770 if (!clang_isDeclaration(cursor.kind))
5771 return CXLinkage_Invalid;
5772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005773 const Decl *D = cxcursor::getCursorDecl(cursor);
5774 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005775 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005776 case NoLinkage:
5777 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 case InternalLinkage: return CXLinkage_Internal;
5779 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5780 case ExternalLinkage: return CXLinkage_External;
5781 };
5782
5783 return CXLinkage_Invalid;
5784}
5785} // end: extern "C"
5786
5787//===----------------------------------------------------------------------===//
5788// Operations for querying language of a cursor.
5789//===----------------------------------------------------------------------===//
5790
5791static CXLanguageKind getDeclLanguage(const Decl *D) {
5792 if (!D)
5793 return CXLanguage_C;
5794
5795 switch (D->getKind()) {
5796 default:
5797 break;
5798 case Decl::ImplicitParam:
5799 case Decl::ObjCAtDefsField:
5800 case Decl::ObjCCategory:
5801 case Decl::ObjCCategoryImpl:
5802 case Decl::ObjCCompatibleAlias:
5803 case Decl::ObjCImplementation:
5804 case Decl::ObjCInterface:
5805 case Decl::ObjCIvar:
5806 case Decl::ObjCMethod:
5807 case Decl::ObjCProperty:
5808 case Decl::ObjCPropertyImpl:
5809 case Decl::ObjCProtocol:
5810 return CXLanguage_ObjC;
5811 case Decl::CXXConstructor:
5812 case Decl::CXXConversion:
5813 case Decl::CXXDestructor:
5814 case Decl::CXXMethod:
5815 case Decl::CXXRecord:
5816 case Decl::ClassTemplate:
5817 case Decl::ClassTemplatePartialSpecialization:
5818 case Decl::ClassTemplateSpecialization:
5819 case Decl::Friend:
5820 case Decl::FriendTemplate:
5821 case Decl::FunctionTemplate:
5822 case Decl::LinkageSpec:
5823 case Decl::Namespace:
5824 case Decl::NamespaceAlias:
5825 case Decl::NonTypeTemplateParm:
5826 case Decl::StaticAssert:
5827 case Decl::TemplateTemplateParm:
5828 case Decl::TemplateTypeParm:
5829 case Decl::UnresolvedUsingTypename:
5830 case Decl::UnresolvedUsingValue:
5831 case Decl::Using:
5832 case Decl::UsingDirective:
5833 case Decl::UsingShadow:
5834 return CXLanguage_CPlusPlus;
5835 }
5836
5837 return CXLanguage_C;
5838}
5839
5840extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005841
5842static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5843 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5844 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005845
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005846 switch (D->getAvailability()) {
5847 case AR_Available:
5848 case AR_NotYetIntroduced:
5849 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005850 return getCursorAvailabilityForDecl(
5851 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005852 return CXAvailability_Available;
5853
5854 case AR_Deprecated:
5855 return CXAvailability_Deprecated;
5856
5857 case AR_Unavailable:
5858 return CXAvailability_NotAvailable;
5859 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005860
5861 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005862}
5863
Guy Benyei11169dd2012-12-18 14:30:41 +00005864enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5865 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005866 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5867 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005868
5869 return CXAvailability_Available;
5870}
5871
5872static CXVersion convertVersion(VersionTuple In) {
5873 CXVersion Out = { -1, -1, -1 };
5874 if (In.empty())
5875 return Out;
5876
5877 Out.Major = In.getMajor();
5878
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005879 Optional<unsigned> Minor = In.getMinor();
5880 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 Out.Minor = *Minor;
5882 else
5883 return Out;
5884
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005885 Optional<unsigned> Subminor = In.getSubminor();
5886 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 Out.Subminor = *Subminor;
5888
5889 return Out;
5890}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005891
5892static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5893 int *always_deprecated,
5894 CXString *deprecated_message,
5895 int *always_unavailable,
5896 CXString *unavailable_message,
5897 CXPlatformAvailability *availability,
5898 int availability_size) {
5899 bool HadAvailAttr = false;
5900 int N = 0;
5901 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5902 ++A) {
5903 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5904 HadAvailAttr = true;
5905 if (always_deprecated)
5906 *always_deprecated = 1;
5907 if (deprecated_message)
5908 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5909 continue;
5910 }
5911
5912 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5913 HadAvailAttr = true;
5914 if (always_unavailable)
5915 *always_unavailable = 1;
5916 if (unavailable_message) {
5917 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5918 }
5919 continue;
5920 }
5921
5922 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5923 HadAvailAttr = true;
5924 if (N < availability_size) {
5925 availability[N].Platform
5926 = cxstring::createDup(Avail->getPlatform()->getName());
5927 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5928 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5929 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5930 availability[N].Unavailable = Avail->getUnavailable();
5931 availability[N].Message = cxstring::createDup(Avail->getMessage());
5932 }
5933 ++N;
5934 }
5935 }
5936
5937 if (!HadAvailAttr)
5938 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5939 return getCursorPlatformAvailabilityForDecl(
5940 cast<Decl>(EnumConst->getDeclContext()),
5941 always_deprecated,
5942 deprecated_message,
5943 always_unavailable,
5944 unavailable_message,
5945 availability,
5946 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005947
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005948 return N;
5949}
5950
Guy Benyei11169dd2012-12-18 14:30:41 +00005951int clang_getCursorPlatformAvailability(CXCursor cursor,
5952 int *always_deprecated,
5953 CXString *deprecated_message,
5954 int *always_unavailable,
5955 CXString *unavailable_message,
5956 CXPlatformAvailability *availability,
5957 int availability_size) {
5958 if (always_deprecated)
5959 *always_deprecated = 0;
5960 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005961 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005962 if (always_unavailable)
5963 *always_unavailable = 0;
5964 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005965 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005966
Guy Benyei11169dd2012-12-18 14:30:41 +00005967 if (!clang_isDeclaration(cursor.kind))
5968 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005969
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005970 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005971 if (!D)
5972 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005973
5974 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5975 deprecated_message,
5976 always_unavailable,
5977 unavailable_message,
5978 availability,
5979 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005980}
5981
5982void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5983 clang_disposeString(availability->Platform);
5984 clang_disposeString(availability->Message);
5985}
5986
5987CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5988 if (clang_isDeclaration(cursor.kind))
5989 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5990
5991 return CXLanguage_Invalid;
5992}
5993
5994 /// \brief If the given cursor is the "templated" declaration
5995 /// descibing a class or function template, return the class or
5996 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005997static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 if (!D)
5999 return 0;
6000
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006001 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006002 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6003 return FunTmpl;
6004
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006005 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6007 return ClassTmpl;
6008
6009 return D;
6010}
6011
6012CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6013 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006014 if (const Decl *D = getCursorDecl(cursor)) {
6015 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 if (!DC)
6017 return clang_getNullCursor();
6018
6019 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6020 getCursorTU(cursor));
6021 }
6022 }
6023
6024 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006025 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 return MakeCXCursor(D, getCursorTU(cursor));
6027 }
6028
6029 return clang_getNullCursor();
6030}
6031
6032CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6033 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006034 if (const Decl *D = getCursorDecl(cursor)) {
6035 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 if (!DC)
6037 return clang_getNullCursor();
6038
6039 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6040 getCursorTU(cursor));
6041 }
6042 }
6043
6044 // FIXME: Note that we can't easily compute the lexical context of a
6045 // statement or expression, so we return nothing.
6046 return clang_getNullCursor();
6047}
6048
6049CXFile clang_getIncludedFile(CXCursor cursor) {
6050 if (cursor.kind != CXCursor_InclusionDirective)
6051 return 0;
6052
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006053 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006054 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006055}
6056
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006057unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6058 if (C.kind != CXCursor_ObjCPropertyDecl)
6059 return CXObjCPropertyAttr_noattr;
6060
6061 unsigned Result = CXObjCPropertyAttr_noattr;
6062 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6063 ObjCPropertyDecl::PropertyAttributeKind Attr =
6064 PD->getPropertyAttributesAsWritten();
6065
6066#define SET_CXOBJCPROP_ATTR(A) \
6067 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6068 Result |= CXObjCPropertyAttr_##A
6069 SET_CXOBJCPROP_ATTR(readonly);
6070 SET_CXOBJCPROP_ATTR(getter);
6071 SET_CXOBJCPROP_ATTR(assign);
6072 SET_CXOBJCPROP_ATTR(readwrite);
6073 SET_CXOBJCPROP_ATTR(retain);
6074 SET_CXOBJCPROP_ATTR(copy);
6075 SET_CXOBJCPROP_ATTR(nonatomic);
6076 SET_CXOBJCPROP_ATTR(setter);
6077 SET_CXOBJCPROP_ATTR(atomic);
6078 SET_CXOBJCPROP_ATTR(weak);
6079 SET_CXOBJCPROP_ATTR(strong);
6080 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6081#undef SET_CXOBJCPROP_ATTR
6082
6083 return Result;
6084}
6085
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006086unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6087 if (!clang_isDeclaration(C.kind))
6088 return CXObjCDeclQualifier_None;
6089
6090 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6091 const Decl *D = getCursorDecl(C);
6092 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6093 QT = MD->getObjCDeclQualifier();
6094 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6095 QT = PD->getObjCDeclQualifier();
6096 if (QT == Decl::OBJC_TQ_None)
6097 return CXObjCDeclQualifier_None;
6098
6099 unsigned Result = CXObjCDeclQualifier_None;
6100 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6101 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6102 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6103 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6104 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6105 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6106
6107 return Result;
6108}
6109
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006110unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6111 if (!clang_isDeclaration(C.kind))
6112 return 0;
6113
6114 const Decl *D = getCursorDecl(C);
6115 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6116 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6117 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6118 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6119
6120 return 0;
6121}
6122
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006123unsigned clang_Cursor_isVariadic(CXCursor C) {
6124 if (!clang_isDeclaration(C.kind))
6125 return 0;
6126
6127 const Decl *D = getCursorDecl(C);
6128 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6129 return FD->isVariadic();
6130 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6131 return MD->isVariadic();
6132
6133 return 0;
6134}
6135
Guy Benyei11169dd2012-12-18 14:30:41 +00006136CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6137 if (!clang_isDeclaration(C.kind))
6138 return clang_getNullRange();
6139
6140 const Decl *D = getCursorDecl(C);
6141 ASTContext &Context = getCursorContext(C);
6142 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6143 if (!RC)
6144 return clang_getNullRange();
6145
6146 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6147}
6148
6149CXString clang_Cursor_getRawCommentText(CXCursor C) {
6150 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006151 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006152
6153 const Decl *D = getCursorDecl(C);
6154 ASTContext &Context = getCursorContext(C);
6155 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6156 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6157 StringRef();
6158
6159 // Don't duplicate the string because RawText points directly into source
6160 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006161 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006162}
6163
6164CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6165 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006166 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006167
6168 const Decl *D = getCursorDecl(C);
6169 const ASTContext &Context = getCursorContext(C);
6170 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6171
6172 if (RC) {
6173 StringRef BriefText = RC->getBriefText(Context);
6174
6175 // Don't duplicate the string because RawComment ensures that this memory
6176 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006177 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006178 }
6179
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006180 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006181}
6182
6183CXComment clang_Cursor_getParsedComment(CXCursor C) {
6184 if (!clang_isDeclaration(C.kind))
6185 return cxcomment::createCXComment(NULL, NULL);
6186
6187 const Decl *D = getCursorDecl(C);
6188 const ASTContext &Context = getCursorContext(C);
6189 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6190
6191 return cxcomment::createCXComment(FC, getCursorTU(C));
6192}
6193
6194CXModule clang_Cursor_getModule(CXCursor C) {
6195 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006196 if (const ImportDecl *ImportD =
6197 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 return ImportD->getImportedModule();
6199 }
6200
6201 return 0;
6202}
6203
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006204CXFile clang_Module_getASTFile(CXModule CXMod) {
6205 if (!CXMod)
6206 return 0;
6207 Module *Mod = static_cast<Module*>(CXMod);
6208 return const_cast<FileEntry *>(Mod->getASTFile());
6209}
6210
Guy Benyei11169dd2012-12-18 14:30:41 +00006211CXModule clang_Module_getParent(CXModule CXMod) {
6212 if (!CXMod)
6213 return 0;
6214 Module *Mod = static_cast<Module*>(CXMod);
6215 return Mod->Parent;
6216}
6217
6218CXString clang_Module_getName(CXModule CXMod) {
6219 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006220 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006222 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006223}
6224
6225CXString clang_Module_getFullName(CXModule CXMod) {
6226 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006227 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006229 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006230}
6231
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006232unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6233 CXModule CXMod) {
6234 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006235 return 0;
6236 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006237 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6238 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6239 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006240}
6241
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006242CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6243 CXModule CXMod, unsigned Index) {
6244 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 return 0;
6246 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006247 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006248
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006249 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6250 if (Index < TopHeaders.size())
6251 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006252
6253 return 0;
6254}
6255
6256} // end: extern "C"
6257
6258//===----------------------------------------------------------------------===//
6259// C++ AST instrospection.
6260//===----------------------------------------------------------------------===//
6261
6262extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006263unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6264 if (!clang_isDeclaration(C.kind))
6265 return 0;
6266
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006267 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006268 const CXXMethodDecl *Method =
6269 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006270 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6271}
6272
Guy Benyei11169dd2012-12-18 14:30:41 +00006273unsigned clang_CXXMethod_isStatic(CXCursor C) {
6274 if (!clang_isDeclaration(C.kind))
6275 return 0;
6276
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006277 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006278 const CXXMethodDecl *Method =
6279 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 return (Method && Method->isStatic()) ? 1 : 0;
6281}
6282
6283unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6284 if (!clang_isDeclaration(C.kind))
6285 return 0;
6286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006287 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006288 const CXXMethodDecl *Method =
6289 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006290 return (Method && Method->isVirtual()) ? 1 : 0;
6291}
6292} // end: extern "C"
6293
6294//===----------------------------------------------------------------------===//
6295// Attribute introspection.
6296//===----------------------------------------------------------------------===//
6297
6298extern "C" {
6299CXType clang_getIBOutletCollectionType(CXCursor C) {
6300 if (C.kind != CXCursor_IBOutletCollectionAttr)
6301 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6302
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006303 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006304 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6305
6306 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6307}
6308} // end: extern "C"
6309
6310//===----------------------------------------------------------------------===//
6311// Inspecting memory usage.
6312//===----------------------------------------------------------------------===//
6313
6314typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6315
6316static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6317 enum CXTUResourceUsageKind k,
6318 unsigned long amount) {
6319 CXTUResourceUsageEntry entry = { k, amount };
6320 entries.push_back(entry);
6321}
6322
6323extern "C" {
6324
6325const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6326 const char *str = "";
6327 switch (kind) {
6328 case CXTUResourceUsage_AST:
6329 str = "ASTContext: expressions, declarations, and types";
6330 break;
6331 case CXTUResourceUsage_Identifiers:
6332 str = "ASTContext: identifiers";
6333 break;
6334 case CXTUResourceUsage_Selectors:
6335 str = "ASTContext: selectors";
6336 break;
6337 case CXTUResourceUsage_GlobalCompletionResults:
6338 str = "Code completion: cached global results";
6339 break;
6340 case CXTUResourceUsage_SourceManagerContentCache:
6341 str = "SourceManager: content cache allocator";
6342 break;
6343 case CXTUResourceUsage_AST_SideTables:
6344 str = "ASTContext: side tables";
6345 break;
6346 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6347 str = "SourceManager: malloc'ed memory buffers";
6348 break;
6349 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6350 str = "SourceManager: mmap'ed memory buffers";
6351 break;
6352 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6353 str = "ExternalASTSource: malloc'ed memory buffers";
6354 break;
6355 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6356 str = "ExternalASTSource: mmap'ed memory buffers";
6357 break;
6358 case CXTUResourceUsage_Preprocessor:
6359 str = "Preprocessor: malloc'ed memory";
6360 break;
6361 case CXTUResourceUsage_PreprocessingRecord:
6362 str = "Preprocessor: PreprocessingRecord";
6363 break;
6364 case CXTUResourceUsage_SourceManager_DataStructures:
6365 str = "SourceManager: data structures and tables";
6366 break;
6367 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6368 str = "Preprocessor: header search tables";
6369 break;
6370 }
6371 return str;
6372}
6373
6374CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6375 if (!TU) {
6376 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6377 return usage;
6378 }
6379
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006380 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6382 ASTContext &astContext = astUnit->getASTContext();
6383
6384 // How much memory is used by AST nodes and types?
6385 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6386 (unsigned long) astContext.getASTAllocatedMemory());
6387
6388 // How much memory is used by identifiers?
6389 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6390 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6391
6392 // How much memory is used for selectors?
6393 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6394 (unsigned long) astContext.Selectors.getTotalMemory());
6395
6396 // How much memory is used by ASTContext's side tables?
6397 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6398 (unsigned long) astContext.getSideTableAllocatedMemory());
6399
6400 // How much memory is used for caching global code completion results?
6401 unsigned long completionBytes = 0;
6402 if (GlobalCodeCompletionAllocator *completionAllocator =
6403 astUnit->getCachedCompletionAllocator().getPtr()) {
6404 completionBytes = completionAllocator->getTotalMemory();
6405 }
6406 createCXTUResourceUsageEntry(*entries,
6407 CXTUResourceUsage_GlobalCompletionResults,
6408 completionBytes);
6409
6410 // How much memory is being used by SourceManager's content cache?
6411 createCXTUResourceUsageEntry(*entries,
6412 CXTUResourceUsage_SourceManagerContentCache,
6413 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6414
6415 // How much memory is being used by the MemoryBuffer's in SourceManager?
6416 const SourceManager::MemoryBufferSizes &srcBufs =
6417 astUnit->getSourceManager().getMemoryBufferSizes();
6418
6419 createCXTUResourceUsageEntry(*entries,
6420 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6421 (unsigned long) srcBufs.malloc_bytes);
6422 createCXTUResourceUsageEntry(*entries,
6423 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6424 (unsigned long) srcBufs.mmap_bytes);
6425 createCXTUResourceUsageEntry(*entries,
6426 CXTUResourceUsage_SourceManager_DataStructures,
6427 (unsigned long) astContext.getSourceManager()
6428 .getDataStructureSizes());
6429
6430 // How much memory is being used by the ExternalASTSource?
6431 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6432 const ExternalASTSource::MemoryBufferSizes &sizes =
6433 esrc->getMemoryBufferSizes();
6434
6435 createCXTUResourceUsageEntry(*entries,
6436 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6437 (unsigned long) sizes.malloc_bytes);
6438 createCXTUResourceUsageEntry(*entries,
6439 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6440 (unsigned long) sizes.mmap_bytes);
6441 }
6442
6443 // How much memory is being used by the Preprocessor?
6444 Preprocessor &pp = astUnit->getPreprocessor();
6445 createCXTUResourceUsageEntry(*entries,
6446 CXTUResourceUsage_Preprocessor,
6447 pp.getTotalMemory());
6448
6449 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6450 createCXTUResourceUsageEntry(*entries,
6451 CXTUResourceUsage_PreprocessingRecord,
6452 pRec->getTotalMemory());
6453 }
6454
6455 createCXTUResourceUsageEntry(*entries,
6456 CXTUResourceUsage_Preprocessor_HeaderSearch,
6457 pp.getHeaderSearchInfo().getTotalMemory());
6458
6459 CXTUResourceUsage usage = { (void*) entries.get(),
6460 (unsigned) entries->size(),
6461 entries->size() ? &(*entries)[0] : 0 };
6462 entries.take();
6463 return usage;
6464}
6465
6466void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6467 if (usage.data)
6468 delete (MemUsageEntries*) usage.data;
6469}
6470
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006471CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6472 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006473 skipped->count = 0;
6474 skipped->ranges = 0;
6475
6476 if (!file)
6477 return skipped;
6478
6479 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6480 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6481 if (!ppRec)
6482 return skipped;
6483
6484 ASTContext &Ctx = astUnit->getASTContext();
6485 SourceManager &sm = Ctx.getSourceManager();
6486 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6487 FileID wantedFileID = sm.translateFile(fileEntry);
6488
6489 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6490 std::vector<SourceRange> wantedRanges;
6491 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6492 i != ei; ++i) {
6493 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6494 wantedRanges.push_back(*i);
6495 }
6496
6497 skipped->count = wantedRanges.size();
6498 skipped->ranges = new CXSourceRange[skipped->count];
6499 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6500 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6501
6502 return skipped;
6503}
6504
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006505void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6506 if (ranges) {
6507 delete[] ranges->ranges;
6508 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006509 }
6510}
6511
Guy Benyei11169dd2012-12-18 14:30:41 +00006512} // end extern "C"
6513
6514void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6515 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6516 for (unsigned I = 0; I != Usage.numEntries; ++I)
6517 fprintf(stderr, " %s: %lu\n",
6518 clang_getTUResourceUsageName(Usage.entries[I].kind),
6519 Usage.entries[I].amount);
6520
6521 clang_disposeCXTUResourceUsage(Usage);
6522}
6523
6524//===----------------------------------------------------------------------===//
6525// Misc. utility functions.
6526//===----------------------------------------------------------------------===//
6527
6528/// Default to using an 8 MB stack size on "safety" threads.
6529static unsigned SafetyStackThreadSize = 8 << 20;
6530
6531namespace clang {
6532
6533bool RunSafely(llvm::CrashRecoveryContext &CRC,
6534 void (*Fn)(void*), void *UserData,
6535 unsigned Size) {
6536 if (!Size)
6537 Size = GetSafetyThreadStackSize();
6538 if (Size)
6539 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6540 return CRC.RunSafely(Fn, UserData);
6541}
6542
6543unsigned GetSafetyThreadStackSize() {
6544 return SafetyStackThreadSize;
6545}
6546
6547void SetSafetyThreadStackSize(unsigned Value) {
6548 SafetyStackThreadSize = Value;
6549}
6550
6551}
6552
6553void clang::setThreadBackgroundPriority() {
6554 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6555 return;
6556
6557 // FIXME: Move to llvm/Support and make it cross-platform.
6558#ifdef __APPLE__
6559 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6560#endif
6561}
6562
6563void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6564 if (!Unit)
6565 return;
6566
6567 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6568 DEnd = Unit->stored_diag_end();
6569 D != DEnd; ++D) {
6570 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6571 CXString Msg = clang_formatDiagnostic(&Diag,
6572 clang_defaultDiagnosticDisplayOptions());
6573 fprintf(stderr, "%s\n", clang_getCString(Msg));
6574 clang_disposeString(Msg);
6575 }
6576#ifdef LLVM_ON_WIN32
6577 // On Windows, force a flush, since there may be multiple copies of
6578 // stderr and stdout in the file system, all with different buffers
6579 // but writing to the same device.
6580 fflush(stderr);
6581#endif
6582}
6583
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006584MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6585 SourceLocation MacroDefLoc,
6586 CXTranslationUnit TU){
6587 if (MacroDefLoc.isInvalid() || !TU)
6588 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006589 if (!II.hadMacroDefinition())
6590 return 0;
6591
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006592 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006593 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006594 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006595 if (MD) {
6596 for (MacroDirective::DefInfo
6597 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6598 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6599 return Def.getMacroInfo();
6600 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006601 }
6602
6603 return 0;
6604}
6605
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006606const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6607 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006608 if (!MacroDef || !TU)
6609 return 0;
6610 const IdentifierInfo *II = MacroDef->getName();
6611 if (!II)
6612 return 0;
6613
6614 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6615}
6616
6617MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6618 const Token &Tok,
6619 CXTranslationUnit TU) {
6620 if (!MI || !TU)
6621 return 0;
6622 if (Tok.isNot(tok::raw_identifier))
6623 return 0;
6624
6625 if (MI->getNumTokens() == 0)
6626 return 0;
6627 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6628 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006629 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006630
6631 // Check that the token is inside the definition and not its argument list.
6632 SourceManager &SM = Unit->getSourceManager();
6633 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6634 return 0;
6635 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6636 return 0;
6637
6638 Preprocessor &PP = Unit->getPreprocessor();
6639 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6640 if (!PPRec)
6641 return 0;
6642
6643 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6644 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6645 if (!II.hadMacroDefinition())
6646 return 0;
6647
6648 // Check that the identifier is not one of the macro arguments.
6649 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6650 return 0;
6651
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006652 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6653 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006654 return 0;
6655
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006656 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006657}
6658
6659MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6660 SourceLocation Loc,
6661 CXTranslationUnit TU) {
6662 if (Loc.isInvalid() || !MI || !TU)
6663 return 0;
6664
6665 if (MI->getNumTokens() == 0)
6666 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006667 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006668 Preprocessor &PP = Unit->getPreprocessor();
6669 if (!PP.getPreprocessingRecord())
6670 return 0;
6671 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6672 Token Tok;
6673 if (PP.getRawToken(Loc, Tok))
6674 return 0;
6675
6676 return checkForMacroInMacroDefinition(MI, Tok, TU);
6677}
6678
Guy Benyei11169dd2012-12-18 14:30:41 +00006679extern "C" {
6680
6681CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006682 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006683}
6684
6685} // end: extern "C"
6686
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006687Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6688 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006689 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006690 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006691 if (Unit->isMainFileAST())
6692 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006693 return *this;
6694 }
6695 }
6696
6697 LogOS << "<NULL TU>";
6698 return *this;
6699}
6700
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006701Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6702 *this << FE->getName();
6703 return *this;
6704}
6705
6706Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6707 CXString cursorName = clang_getCursorDisplayName(cursor);
6708 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6709 clang_disposeString(cursorName);
6710 return *this;
6711}
6712
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006713Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6714 CXFile File;
6715 unsigned Line, Column;
6716 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6717 CXString FileName = clang_getFileName(File);
6718 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6719 clang_disposeString(FileName);
6720 return *this;
6721}
6722
6723Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6724 CXSourceLocation BLoc = clang_getRangeStart(range);
6725 CXSourceLocation ELoc = clang_getRangeEnd(range);
6726
6727 CXFile BFile;
6728 unsigned BLine, BColumn;
6729 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6730
6731 CXFile EFile;
6732 unsigned ELine, EColumn;
6733 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6734
6735 CXString BFileName = clang_getFileName(BFile);
6736 if (BFile == EFile) {
6737 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6738 BLine, BColumn, ELine, EColumn);
6739 } else {
6740 CXString EFileName = clang_getFileName(EFile);
6741 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6742 BLine, BColumn)
6743 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6744 ELine, EColumn);
6745 clang_disposeString(EFileName);
6746 }
6747 clang_disposeString(BFileName);
6748 return *this;
6749}
6750
6751Logger &cxindex::Logger::operator<<(CXString Str) {
6752 *this << clang_getCString(Str);
6753 return *this;
6754}
6755
6756Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6757 LogOS << Fmt;
6758 return *this;
6759}
6760
6761cxindex::Logger::~Logger() {
6762 LogOS.flush();
6763
6764 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6765
6766 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6767
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006768 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006769 OS << "[libclang:" << Name << ':';
6770
6771 // FIXME: Portability.
6772#if HAVE_PTHREAD_H && __APPLE__
6773 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6774 OS << tid << ':';
6775#endif
6776
6777 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6778 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6779 OS << Msg.str() << '\n';
6780
6781 if (Trace) {
6782 llvm::sys::PrintStackTrace(stderr);
6783 OS << "--------------------------------------------------\n";
6784 }
6785}