blob: 656fbd1b1b7ff6737dc4e67a34c9d6388af9b98b [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.
David Blaikie6adc78e2013-02-18 22:06:02 +0000772 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
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) {
898 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
899 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) {
1520 if (!SkipResultType && Visit(TL.getResultLoc()))
1521 return true;
1522
1523 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1524 if (Decl *D = TL.getArg(I))
1525 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);
1842 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1843 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1844 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1845 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1846 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1847 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1848 void VisitVAArgExpr(const VAArgExpr *E);
1849 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1850 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1851 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1852 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001853 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1854 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855
Guy Benyei11169dd2012-12-18 14:30:41 +00001856private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001858 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1859 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1861 void AddStmt(const Stmt *S);
1862 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001914namespace {
1915class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1916 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001917 /// \brief Process clauses with list of variables.
1918 template <typename T>
1919 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920public:
1921 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1922#define OPENMP_CLAUSE(Name, Class) \
1923 void Visit##Class(const Class *C);
1924#include "clang/Basic/OpenMPKinds.def"
1925};
1926
1927void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001928
1929template<typename T>
1930void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1931 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1932 E = Node->varlist_end();
1933 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001934 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001935}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001936
1937void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001938 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001940void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1941 const OMPFirstprivateClause *C) {
1942 VisitOMPClauseList(C);
1943}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001944void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001945 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947}
Alexey Bataev756c1962013-09-24 03:17:45 +00001948
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1950 unsigned size = WL.size();
1951 OMPClauseEnqueue Visitor(this);
1952 Visitor.Visit(S);
1953 if (size == WL.size())
1954 return;
1955 // Now reverse the entries we just added. This will match the DFS
1956 // ordering performed by the worklist.
1957 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1958 std::reverse(I, E);
1959}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001961 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1962}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001964 AddDecl(B->getBlockDecl());
1965}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001966void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001967 EnqueueChildren(E);
1968 AddTypeLoc(E->getTypeSourceInfo());
1969}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001970void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1971 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 E = S->body_rend(); I != E; ++I) {
1973 AddStmt(*I);
1974 }
1975}
1976void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 AddStmt(S->getSubStmt());
1979 AddDeclarationNameInfo(S);
1980 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1981 AddNestedNameSpecifierLoc(QualifierLoc);
1982}
1983
1984void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1987 AddDeclarationNameInfo(E);
1988 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1989 AddNestedNameSpecifierLoc(QualifierLoc);
1990 if (!E->isImplicitAccess())
1991 AddStmt(E->getBase());
1992}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 // Enqueue the initializer , if any.
1995 AddStmt(E->getInitializer());
1996 // Enqueue the array size, if any.
1997 AddStmt(E->getArraySize());
1998 // Enqueue the allocated type.
1999 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2000 // Enqueue the placement arguments.
2001 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2002 AddStmt(E->getPlacementArg(I-1));
2003}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2006 AddStmt(CE->getArg(I-1));
2007 AddStmt(CE->getCallee());
2008 AddStmt(CE->getArg(0));
2009}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2011 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002012 // Visit the name of the type being destroyed.
2013 AddTypeLoc(E->getDestroyedTypeInfo());
2014 // Visit the scope type that looks disturbingly like the nested-name-specifier
2015 // but isn't.
2016 AddTypeLoc(E->getScopeTypeInfo());
2017 // Visit the nested-name-specifier.
2018 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2019 AddNestedNameSpecifierLoc(QualifierLoc);
2020 // Visit base expression.
2021 AddStmt(E->getBase());
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2024 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 AddTypeLoc(E->getTypeSourceInfo());
2026}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002027void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2028 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 EnqueueChildren(E);
2030 AddTypeLoc(E->getTypeSourceInfo());
2031}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002032void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 EnqueueChildren(E);
2034 if (E->isTypeOperand())
2035 AddTypeLoc(E->getTypeOperandSourceInfo());
2036}
2037
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2039 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 EnqueueChildren(E);
2041 AddTypeLoc(E->getTypeSourceInfo());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 EnqueueChildren(E);
2045 if (E->isTypeOperand())
2046 AddTypeLoc(E->getTypeOperandSourceInfo());
2047}
2048
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 EnqueueChildren(S);
2051 AddDecl(S->getExceptionDecl());
2052}
2053
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 if (DR->hasExplicitTemplateArgs()) {
2056 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2057 }
2058 WL.push_back(DeclRefExprParts(DR, Parent));
2059}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2061 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2063 AddDeclarationNameInfo(E);
2064 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 unsigned size = WL.size();
2068 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 D != DEnd; ++D) {
2071 AddDecl(*D, isFirst);
2072 isFirst = false;
2073 }
2074 if (size == WL.size())
2075 return;
2076 // Now reverse the entries we just added. This will match the DFS
2077 // ordering performed by the worklist.
2078 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2079 std::reverse(I, E);
2080}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 D = E->designators_rbegin(), DEnd = E->designators_rend();
2085 D != DEnd; ++D) {
2086 if (D->isFieldDesignator()) {
2087 if (FieldDecl *Field = D->getField())
2088 AddMemberRef(Field, D->getFieldLoc());
2089 continue;
2090 }
2091 if (D->isArrayDesignator()) {
2092 AddStmt(E->getArrayIndex(*D));
2093 continue;
2094 }
2095 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2096 AddStmt(E->getArrayRangeEnd(*D));
2097 AddStmt(E->getArrayRangeStart(*D));
2098 }
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 EnqueueChildren(E);
2102 AddTypeLoc(E->getTypeInfoAsWritten());
2103}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 AddStmt(FS->getBody());
2106 AddStmt(FS->getInc());
2107 AddStmt(FS->getCond());
2108 AddDecl(FS->getConditionVariable());
2109 AddStmt(FS->getInit());
2110}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 AddStmt(If->getElse());
2116 AddStmt(If->getThen());
2117 AddStmt(If->getCond());
2118 AddDecl(If->getConditionVariable());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 // We care about the syntactic form of the initializer list, only.
2122 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2123 IE = Syntactic;
2124 EnqueueChildren(IE);
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 WL.push_back(MemberExprParts(M, Parent));
2128
2129 // If the base of the member access expression is an implicit 'this', don't
2130 // visit it.
2131 // FIXME: If we ever want to show these implicit accesses, this will be
2132 // unfortunate. However, clang_getCursor() relies on this behavior.
2133 if (!M->isImplicitAccess())
2134 AddStmt(M->getBase());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 AddTypeLoc(E->getEncodedTypeSourceInfo());
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 EnqueueChildren(M);
2141 AddTypeLoc(M->getClassReceiverTypeInfo());
2142}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 // Visit the components of the offsetof expression.
2145 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2146 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2147 const OffsetOfNode &Node = E->getComponent(I-1);
2148 switch (Node.getKind()) {
2149 case OffsetOfNode::Array:
2150 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2151 break;
2152 case OffsetOfNode::Field:
2153 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2154 break;
2155 case OffsetOfNode::Identifier:
2156 case OffsetOfNode::Base:
2157 continue;
2158 }
2159 }
2160 // Visit the type into which we're computing the offset.
2161 AddTypeLoc(E->getTypeSourceInfo());
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2165 WL.push_back(OverloadExprParts(E, Parent));
2166}
2167void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 EnqueueChildren(E);
2170 if (E->isArgumentType())
2171 AddTypeLoc(E->getArgumentTypeInfo());
2172}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 EnqueueChildren(S);
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 AddStmt(S->getBody());
2178 AddStmt(S->getCond());
2179 AddDecl(S->getConditionVariable());
2180}
2181
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 AddStmt(W->getBody());
2184 AddStmt(W->getCond());
2185 AddDecl(W->getConditionVariable());
2186}
2187
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddTypeLoc(E->getQueriedTypeSourceInfo());
2190}
2191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddTypeLoc(E->getRhsTypeSourceInfo());
2194 AddTypeLoc(E->getLhsTypeSourceInfo());
2195}
2196
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 for (unsigned I = E->getNumArgs(); I > 0; --I)
2199 AddTypeLoc(E->getArg(I-1));
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 AddTypeLoc(E->getQueriedTypeSourceInfo());
2204}
2205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 EnqueueChildren(E);
2208}
2209
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 VisitOverloadExpr(U);
2212 if (!U->isImplicitAccess())
2213 AddStmt(U->getBase());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 AddStmt(E->getSubExpr());
2217 AddTypeLoc(E->getWrittenTypeInfo());
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 WL.push_back(SizeOfPackExprParts(E, Parent));
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 // If the opaque value has a source expression, just transparently
2224 // visit that. This is useful for (e.g.) pseudo-object expressions.
2225 if (Expr *SourceExpr = E->getSourceExpr())
2226 return Visit(SourceExpr);
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 AddStmt(E->getBody());
2230 WL.push_back(LambdaExprParts(E, Parent));
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 // Treat the expression like its syntactic form.
2234 Visit(E->getSyntacticForm());
2235}
2236
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002237void EnqueueVisitor::VisitOMPExecutableDirective(
2238 const OMPExecutableDirective *D) {
2239 EnqueueChildren(D);
2240 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2241 E = D->clauses().end();
2242 I != E; ++I)
2243 EnqueueChildren(*I);
2244}
2245
2246void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2247 VisitOMPExecutableDirective(D);
2248}
2249
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2252}
2253
2254bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2255 if (RegionOfInterest.isValid()) {
2256 SourceRange Range = getRawCursorExtent(C);
2257 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2258 return false;
2259 }
2260 return true;
2261}
2262
2263bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2264 while (!WL.empty()) {
2265 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002266 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002267
2268 // Set the Parent field, then back to its old value once we're done.
2269 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2270
2271 switch (LI.getKind()) {
2272 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 if (!D)
2275 continue;
2276
2277 // For now, perform default visitation for Decls.
2278 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2279 cast<DeclVisit>(&LI)->isFirst())))
2280 return true;
2281
2282 continue;
2283 }
2284 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2285 const ASTTemplateArgumentListInfo *ArgList =
2286 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2287 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2288 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2289 Arg != ArgEnd; ++Arg) {
2290 if (VisitTemplateArgumentLoc(*Arg))
2291 return true;
2292 }
2293 continue;
2294 }
2295 case VisitorJob::TypeLocVisitKind: {
2296 // Perform default visitation for TypeLocs.
2297 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2298 return true;
2299 continue;
2300 }
2301 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 if (LabelStmt *stmt = LS->getStmt()) {
2304 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2305 TU))) {
2306 return true;
2307 }
2308 }
2309 continue;
2310 }
2311
2312 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2313 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2314 if (VisitNestedNameSpecifierLoc(V->get()))
2315 return true;
2316 continue;
2317 }
2318
2319 case VisitorJob::DeclarationNameInfoVisitKind: {
2320 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2321 ->get()))
2322 return true;
2323 continue;
2324 }
2325 case VisitorJob::MemberRefVisitKind: {
2326 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2327 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2328 return true;
2329 continue;
2330 }
2331 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 if (!S)
2334 continue;
2335
2336 // Update the current cursor.
2337 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2338 if (!IsInRegionOfInterest(Cursor))
2339 continue;
2340 switch (Visitor(Cursor, Parent, ClientData)) {
2341 case CXChildVisit_Break: return true;
2342 case CXChildVisit_Continue: break;
2343 case CXChildVisit_Recurse:
2344 if (PostChildrenVisitor)
2345 WL.push_back(PostChildrenVisit(0, Cursor));
2346 EnqueueWorkList(WL, S);
2347 break;
2348 }
2349 continue;
2350 }
2351 case VisitorJob::MemberExprPartsKind: {
2352 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002354
2355 // Visit the nested-name-specifier
2356 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2357 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2358 return true;
2359
2360 // Visit the declaration name.
2361 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2362 return true;
2363
2364 // Visit the explicitly-specified template arguments, if any.
2365 if (M->hasExplicitTemplateArgs()) {
2366 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2367 *ArgEnd = Arg + M->getNumTemplateArgs();
2368 Arg != ArgEnd; ++Arg) {
2369 if (VisitTemplateArgumentLoc(*Arg))
2370 return true;
2371 }
2372 }
2373 continue;
2374 }
2375 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 // Visit nested-name-specifier, if present.
2378 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2379 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2380 return true;
2381 // Visit declaration name.
2382 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2383 return true;
2384 continue;
2385 }
2386 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 // Visit the nested-name-specifier.
2389 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2390 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2391 return true;
2392 // Visit the declaration name.
2393 if (VisitDeclarationNameInfo(O->getNameInfo()))
2394 return true;
2395 // Visit the overloaded declaration reference.
2396 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2397 return true;
2398 continue;
2399 }
2400 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 NamedDecl *Pack = E->getPack();
2403 if (isa<TemplateTypeParmDecl>(Pack)) {
2404 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2405 E->getPackLoc(), TU)))
2406 return true;
2407
2408 continue;
2409 }
2410
2411 if (isa<TemplateTemplateParmDecl>(Pack)) {
2412 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2413 E->getPackLoc(), TU)))
2414 return true;
2415
2416 continue;
2417 }
2418
2419 // Non-type template parameter packs and function parameter packs are
2420 // treated like DeclRefExpr cursors.
2421 continue;
2422 }
2423
2424 case VisitorJob::LambdaExprPartsKind: {
2425 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2428 CEnd = E->explicit_capture_end();
2429 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002430 // FIXME: Lambda init-captures.
2431 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002433
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2435 C->getLocation(),
2436 TU)))
2437 return true;
2438 }
2439
2440 // Visit parameters and return type, if present.
2441 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2442 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2443 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2444 // Visit the whole type.
2445 if (Visit(TL))
2446 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002447 } else if (FunctionProtoTypeLoc Proto =
2448 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 if (E->hasExplicitParameters()) {
2450 // Visit parameters.
2451 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2452 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2453 return true;
2454 } else {
2455 // Visit result type.
2456 if (Visit(Proto.getResultLoc()))
2457 return true;
2458 }
2459 }
2460 }
2461 break;
2462 }
2463
2464 case VisitorJob::PostChildrenVisitKind:
2465 if (PostChildrenVisitor(Parent, ClientData))
2466 return true;
2467 break;
2468 }
2469 }
2470 return false;
2471}
2472
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002473bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 VisitorWorkList *WL = 0;
2475 if (!WorkListFreeList.empty()) {
2476 WL = WorkListFreeList.back();
2477 WL->clear();
2478 WorkListFreeList.pop_back();
2479 }
2480 else {
2481 WL = new VisitorWorkList();
2482 WorkListCache.push_back(WL);
2483 }
2484 EnqueueWorkList(*WL, S);
2485 bool result = RunVisitorWorkList(*WL);
2486 WorkListFreeList.push_back(WL);
2487 return result;
2488}
2489
2490namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002491typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002492RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2493 const DeclarationNameInfo &NI,
2494 const SourceRange &QLoc,
2495 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2496 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2497 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2498 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2499
2500 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2501
2502 RefNamePieces Pieces;
2503
2504 if (WantQualifier && QLoc.isValid())
2505 Pieces.push_back(QLoc);
2506
2507 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2508 Pieces.push_back(NI.getLoc());
2509
2510 if (WantTemplateArgs && TemplateArgs)
2511 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2512 TemplateArgs->RAngleLoc));
2513
2514 if (Kind == DeclarationName::CXXOperatorName) {
2515 Pieces.push_back(SourceLocation::getFromRawEncoding(
2516 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2517 Pieces.push_back(SourceLocation::getFromRawEncoding(
2518 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2519 }
2520
2521 if (WantSinglePiece) {
2522 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2523 Pieces.clear();
2524 Pieces.push_back(R);
2525 }
2526
2527 return Pieces;
2528}
2529}
2530
2531//===----------------------------------------------------------------------===//
2532// Misc. API hooks.
2533//===----------------------------------------------------------------------===//
2534
2535static llvm::sys::Mutex EnableMultithreadingMutex;
2536static bool EnabledMultithreading;
2537
Chad Rosier05c71aa2013-03-27 18:28:23 +00002538static void fatal_error_handler(void *user_data, const std::string& reason,
2539 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 // Write the result out to stderr avoiding errs() because raw_ostreams can
2541 // call report_fatal_error.
2542 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2543 ::abort();
2544}
2545
2546extern "C" {
2547CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2548 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 // We use crash recovery to make some of our APIs more reliable, implicitly
2550 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002551 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2552 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002553
2554 // Enable support for multithreading in LLVM.
2555 {
2556 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2557 if (!EnabledMultithreading) {
2558 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2559 llvm::llvm_start_multithreaded();
2560 EnabledMultithreading = true;
2561 }
2562 }
2563
2564 CIndexer *CIdxr = new CIndexer();
2565 if (excludeDeclarationsFromPCH)
2566 CIdxr->setOnlyLocalDecls();
2567 if (displayDiagnostics)
2568 CIdxr->setDisplayDiagnostics();
2569
2570 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2571 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2572 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2573 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2574 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2575 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2576
2577 return CIdxr;
2578}
2579
2580void clang_disposeIndex(CXIndex CIdx) {
2581 if (CIdx)
2582 delete static_cast<CIndexer *>(CIdx);
2583}
2584
2585void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2586 if (CIdx)
2587 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2588}
2589
2590unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2591 if (CIdx)
2592 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2593 return 0;
2594}
2595
2596void clang_toggleCrashRecovery(unsigned isEnabled) {
2597 if (isEnabled)
2598 llvm::CrashRecoveryContext::Enable();
2599 else
2600 llvm::CrashRecoveryContext::Disable();
2601}
2602
2603CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2604 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002605 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002606 return 0;
2607
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002608 LOG_FUNC_SECTION {
2609 *Log << ast_filename;
2610 }
2611
Guy Benyei11169dd2012-12-18 14:30:41 +00002612 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2613 FileSystemOptions FileSystemOpts;
2614
2615 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2616 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2617 CXXIdx->getOnlyLocalDecls(),
2618 0, 0,
2619 /*CaptureDiagnostics=*/true,
2620 /*AllowPCHWithCompilerErrors=*/true,
2621 /*UserFilesAreVolatile=*/true);
2622 return MakeCXTranslationUnit(CXXIdx, TU);
2623}
2624
2625unsigned clang_defaultEditingTranslationUnitOptions() {
2626 return CXTranslationUnit_PrecompiledPreamble |
2627 CXTranslationUnit_CacheCompletionResults;
2628}
2629
2630CXTranslationUnit
2631clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2632 const char *source_filename,
2633 int num_command_line_args,
2634 const char * const *command_line_args,
2635 unsigned num_unsaved_files,
2636 struct CXUnsavedFile *unsaved_files) {
2637 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2638 return clang_parseTranslationUnit(CIdx, source_filename,
2639 command_line_args, num_command_line_args,
2640 unsaved_files, num_unsaved_files,
2641 Options);
2642}
2643
2644struct ParseTranslationUnitInfo {
2645 CXIndex CIdx;
2646 const char *source_filename;
2647 const char *const *command_line_args;
2648 int num_command_line_args;
2649 struct CXUnsavedFile *unsaved_files;
2650 unsigned num_unsaved_files;
2651 unsigned options;
2652 CXTranslationUnit result;
2653};
2654static void clang_parseTranslationUnit_Impl(void *UserData) {
2655 ParseTranslationUnitInfo *PTUI =
2656 static_cast<ParseTranslationUnitInfo*>(UserData);
2657 CXIndex CIdx = PTUI->CIdx;
2658 const char *source_filename = PTUI->source_filename;
2659 const char * const *command_line_args = PTUI->command_line_args;
2660 int num_command_line_args = PTUI->num_command_line_args;
2661 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2662 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2663 unsigned options = PTUI->options;
2664 PTUI->result = 0;
2665
2666 if (!CIdx)
2667 return;
2668
2669 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2670
2671 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2672 setThreadBackgroundPriority();
2673
2674 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2675 // FIXME: Add a flag for modules.
2676 TranslationUnitKind TUKind
2677 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002678 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002679 = options & CXTranslationUnit_CacheCompletionResults;
2680 bool IncludeBriefCommentsInCodeCompletion
2681 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2682 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2683 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2684
2685 // Configure the diagnostics.
2686 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002687 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
2689 // Recover resources if we crash before exiting this function.
2690 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2691 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2692 DiagCleanup(Diags.getPtr());
2693
2694 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2695 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2696
2697 // Recover resources if we crash before exiting this function.
2698 llvm::CrashRecoveryContextCleanupRegistrar<
2699 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2700
2701 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2702 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2703 const llvm::MemoryBuffer *Buffer
2704 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2705 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2706 Buffer));
2707 }
2708
2709 OwningPtr<std::vector<const char *> >
2710 Args(new std::vector<const char*>());
2711
2712 // Recover resources if we crash before exiting this method.
2713 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2714 ArgsCleanup(Args.get());
2715
2716 // Since the Clang C library is primarily used by batch tools dealing with
2717 // (often very broken) source code, where spell-checking can have a
2718 // significant negative impact on performance (particularly when
2719 // precompiled headers are involved), we disable it by default.
2720 // Only do this if we haven't found a spell-checking-related argument.
2721 bool FoundSpellCheckingArgument = false;
2722 for (int I = 0; I != num_command_line_args; ++I) {
2723 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2724 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2725 FoundSpellCheckingArgument = true;
2726 break;
2727 }
2728 }
2729 if (!FoundSpellCheckingArgument)
2730 Args->push_back("-fno-spell-checking");
2731
2732 Args->insert(Args->end(), command_line_args,
2733 command_line_args + num_command_line_args);
2734
2735 // The 'source_filename' argument is optional. If the caller does not
2736 // specify it then it is assumed that the source file is specified
2737 // in the actual argument list.
2738 // Put the source file after command_line_args otherwise if '-x' flag is
2739 // present it will be unused.
2740 if (source_filename)
2741 Args->push_back(source_filename);
2742
2743 // Do we need the detailed preprocessing record?
2744 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2745 Args->push_back("-Xclang");
2746 Args->push_back("-detailed-preprocessing-record");
2747 }
2748
2749 unsigned NumErrors = Diags->getClient()->getNumErrors();
2750 OwningPtr<ASTUnit> ErrUnit;
2751 OwningPtr<ASTUnit> Unit(
2752 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2753 /* vector::data() not portable */,
2754 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2755 Diags,
2756 CXXIdx->getClangResourcesPath(),
2757 CXXIdx->getOnlyLocalDecls(),
2758 /*CaptureDiagnostics=*/true,
2759 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2760 RemappedFiles->size(),
2761 /*RemappedFilesKeepOriginalName=*/true,
2762 PrecompilePreamble,
2763 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002764 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002765 IncludeBriefCommentsInCodeCompletion,
2766 /*AllowPCHWithCompilerErrors=*/true,
2767 SkipFunctionBodies,
2768 /*UserFilesAreVolatile=*/true,
2769 ForSerialization,
2770 &ErrUnit));
2771
2772 if (NumErrors != Diags->getClient()->getNumErrors()) {
2773 // Make sure to check that 'Unit' is non-NULL.
2774 if (CXXIdx->getDisplayDiagnostics())
2775 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2776 }
2777
2778 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2779}
2780CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2781 const char *source_filename,
2782 const char * const *command_line_args,
2783 int num_command_line_args,
2784 struct CXUnsavedFile *unsaved_files,
2785 unsigned num_unsaved_files,
2786 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002787 LOG_FUNC_SECTION {
2788 *Log << source_filename << ": ";
2789 for (int i = 0; i != num_command_line_args; ++i)
2790 *Log << command_line_args[i] << " ";
2791 }
2792
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2794 num_command_line_args, unsaved_files,
2795 num_unsaved_files, options, 0 };
2796 llvm::CrashRecoveryContext CRC;
2797
2798 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2799 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2800 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2801 fprintf(stderr, " 'command_line_args' : [");
2802 for (int i = 0; i != num_command_line_args; ++i) {
2803 if (i)
2804 fprintf(stderr, ", ");
2805 fprintf(stderr, "'%s'", command_line_args[i]);
2806 }
2807 fprintf(stderr, "],\n");
2808 fprintf(stderr, " 'unsaved_files' : [");
2809 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2810 if (i)
2811 fprintf(stderr, ", ");
2812 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2813 unsaved_files[i].Length);
2814 }
2815 fprintf(stderr, "],\n");
2816 fprintf(stderr, " 'options' : %d,\n", options);
2817 fprintf(stderr, "}\n");
2818
2819 return 0;
2820 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2821 PrintLibclangResourceUsage(PTUI.result);
2822 }
2823
2824 return PTUI.result;
2825}
2826
2827unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2828 return CXSaveTranslationUnit_None;
2829}
2830
2831namespace {
2832
2833struct SaveTranslationUnitInfo {
2834 CXTranslationUnit TU;
2835 const char *FileName;
2836 unsigned options;
2837 CXSaveError result;
2838};
2839
2840}
2841
2842static void clang_saveTranslationUnit_Impl(void *UserData) {
2843 SaveTranslationUnitInfo *STUI =
2844 static_cast<SaveTranslationUnitInfo*>(UserData);
2845
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002846 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002847 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2848 setThreadBackgroundPriority();
2849
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002850 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2852}
2853
2854int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2855 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002856 LOG_FUNC_SECTION {
2857 *Log << TU << ' ' << FileName;
2858 }
2859
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 if (!TU)
2861 return CXSaveError_InvalidTU;
2862
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002863 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002864 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2865 if (!CXXUnit->hasSema())
2866 return CXSaveError_InvalidTU;
2867
2868 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2869
2870 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2871 getenv("LIBCLANG_NOTHREADS")) {
2872 clang_saveTranslationUnit_Impl(&STUI);
2873
2874 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2875 PrintLibclangResourceUsage(TU);
2876
2877 return STUI.result;
2878 }
2879
2880 // We have an AST that has invalid nodes due to compiler errors.
2881 // Use a crash recovery thread for protection.
2882
2883 llvm::CrashRecoveryContext CRC;
2884
2885 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2886 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2887 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2888 fprintf(stderr, " 'options' : %d,\n", options);
2889 fprintf(stderr, "}\n");
2890
2891 return CXSaveError_Unknown;
2892
2893 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2894 PrintLibclangResourceUsage(TU);
2895 }
2896
2897 return STUI.result;
2898}
2899
2900void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2901 if (CTUnit) {
2902 // If the translation unit has been marked as unsafe to free, just discard
2903 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002904 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 return;
2906
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002907 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002908 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2910 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002911 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 delete CTUnit;
2913 }
2914}
2915
2916unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2917 return CXReparse_None;
2918}
2919
2920struct ReparseTranslationUnitInfo {
2921 CXTranslationUnit TU;
2922 unsigned num_unsaved_files;
2923 struct CXUnsavedFile *unsaved_files;
2924 unsigned options;
2925 int result;
2926};
2927
2928static void clang_reparseTranslationUnit_Impl(void *UserData) {
2929 ReparseTranslationUnitInfo *RTUI =
2930 static_cast<ReparseTranslationUnitInfo*>(UserData);
2931 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002932 if (!TU)
2933 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002934
2935 // Reset the associated diagnostics.
2936 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2937 TU->Diagnostics = 0;
2938
2939 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2940 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2941 unsigned options = RTUI->options;
2942 (void) options;
2943 RTUI->result = 1;
2944
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002945 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002946 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2947 setThreadBackgroundPriority();
2948
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002949 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2951
2952 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2953 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2954
2955 // Recover resources if we crash before exiting this function.
2956 llvm::CrashRecoveryContextCleanupRegistrar<
2957 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2958
2959 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2960 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2961 const llvm::MemoryBuffer *Buffer
2962 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2963 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2964 Buffer));
2965 }
2966
2967 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2968 RemappedFiles->size()))
2969 RTUI->result = 0;
2970}
2971
2972int clang_reparseTranslationUnit(CXTranslationUnit TU,
2973 unsigned num_unsaved_files,
2974 struct CXUnsavedFile *unsaved_files,
2975 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002976 LOG_FUNC_SECTION {
2977 *Log << TU;
2978 }
2979
Guy Benyei11169dd2012-12-18 14:30:41 +00002980 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2981 options, 0 };
2982
2983 if (getenv("LIBCLANG_NOTHREADS")) {
2984 clang_reparseTranslationUnit_Impl(&RTUI);
2985 return RTUI.result;
2986 }
2987
2988 llvm::CrashRecoveryContext CRC;
2989
2990 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2991 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002992 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 return 1;
2994 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2995 PrintLibclangResourceUsage(TU);
2996
2997 return RTUI.result;
2998}
2999
3000
3001CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3002 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003003 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003004
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003005 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003006 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003007}
3008
3009CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003010 if (!TU)
3011 return clang_getNullCursor();
3012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3015}
3016
3017} // end: extern "C"
3018
3019//===----------------------------------------------------------------------===//
3020// CXFile Operations.
3021//===----------------------------------------------------------------------===//
3022
3023extern "C" {
3024CXString clang_getFileName(CXFile SFile) {
3025 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003026 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003027
3028 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003029 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003030}
3031
3032time_t clang_getFileTime(CXFile SFile) {
3033 if (!SFile)
3034 return 0;
3035
3036 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3037 return FEnt->getModificationTime();
3038}
3039
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003040CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3041 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 return 0;
3043
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003044 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003045
3046 FileManager &FMgr = CXXUnit->getFileManager();
3047 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3048}
3049
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003050unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3051 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 return 0;
3053
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003055 FileEntry *FEnt = static_cast<FileEntry *>(file);
3056 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3057 .isFileMultipleIncludeGuarded(FEnt);
3058}
3059
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003060int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3061 if (!file || !outID)
3062 return 1;
3063
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003064 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003065 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3066 outID->data[0] = ID.getDevice();
3067 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003068 outID->data[2] = FEnt->getModificationTime();
3069 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003070}
3071
Guy Benyei11169dd2012-12-18 14:30:41 +00003072} // end: extern "C"
3073
3074//===----------------------------------------------------------------------===//
3075// CXCursor Operations.
3076//===----------------------------------------------------------------------===//
3077
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003078static const Decl *getDeclFromExpr(const Stmt *E) {
3079 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 return getDeclFromExpr(CE->getSubExpr());
3081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003082 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003084 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003086 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003087 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003088 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 if (PRE->isExplicitProperty())
3090 return PRE->getExplicitProperty();
3091 // It could be messaging both getter and setter as in:
3092 // ++myobj.myprop;
3093 // in which case prefer to associate the setter since it is less obvious
3094 // from inspecting the source that the setter is going to get called.
3095 if (PRE->isMessagingSetter())
3096 return PRE->getImplicitPropertySetter();
3097 return PRE->getImplicitPropertyGetter();
3098 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003099 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003101 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 if (Expr *Src = OVE->getSourceExpr())
3103 return getDeclFromExpr(Src);
3104
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003105 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003107 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 if (!CE->isElidable())
3109 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003110 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 return OME->getMethodDecl();
3112
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003113 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003115 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3117 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003118 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3120 isa<ParmVarDecl>(SizeOfPack->getPack()))
3121 return SizeOfPack->getPack();
3122
3123 return 0;
3124}
3125
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003126static SourceLocation getLocationFromExpr(const Expr *E) {
3127 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return getLocationFromExpr(CE->getSubExpr());
3129
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003130 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003132 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003134 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003136 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003138 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003140 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 return PropRef->getLocation();
3142
3143 return E->getLocStart();
3144}
3145
3146extern "C" {
3147
3148unsigned clang_visitChildren(CXCursor parent,
3149 CXCursorVisitor visitor,
3150 CXClientData client_data) {
3151 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3152 /*VisitPreprocessorLast=*/false);
3153 return CursorVis.VisitChildren(parent);
3154}
3155
3156#ifndef __has_feature
3157#define __has_feature(x) 0
3158#endif
3159#if __has_feature(blocks)
3160typedef enum CXChildVisitResult
3161 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3162
3163static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3164 CXClientData client_data) {
3165 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3166 return block(cursor, parent);
3167}
3168#else
3169// If we are compiled with a compiler that doesn't have native blocks support,
3170// define and call the block manually, so the
3171typedef struct _CXChildVisitResult
3172{
3173 void *isa;
3174 int flags;
3175 int reserved;
3176 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3177 CXCursor);
3178} *CXCursorVisitorBlock;
3179
3180static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3181 CXClientData client_data) {
3182 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3183 return block->invoke(block, cursor, parent);
3184}
3185#endif
3186
3187
3188unsigned clang_visitChildrenWithBlock(CXCursor parent,
3189 CXCursorVisitorBlock block) {
3190 return clang_visitChildren(parent, visitWithBlock, block);
3191}
3192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003195 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const ObjCPropertyImplDecl *PropImpl =
3200 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003202 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003203
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003204 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003206 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003207
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003208 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 }
3210
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003211 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003212 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003213
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003214 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3216 // and returns different names. NamedDecl returns the class name and
3217 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003218 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003219
3220 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003221 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003222
3223 SmallString<1024> S;
3224 llvm::raw_svector_ostream os(S);
3225 ND->printName(os);
3226
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003227 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003228}
3229
3230CXString clang_getCursorSpelling(CXCursor C) {
3231 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003232 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003233
3234 if (clang_isReference(C.kind)) {
3235 switch (C.kind) {
3236 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003237 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003238 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 }
3240 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003241 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003242 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 }
3244 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003245 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003247 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 }
3249 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003250 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003251 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 }
3253 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003254 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003255 assert(Type && "Missing type decl");
3256
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003257 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 getAsString());
3259 }
3260 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003261 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 assert(Template && "Missing template decl");
3263
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003264 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 }
3266
3267 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003268 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 assert(NS && "Missing namespace decl");
3270
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003271 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 }
3273
3274 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003275 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 assert(Field && "Missing member decl");
3277
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003278 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 }
3280
3281 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003282 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 assert(Label && "Missing label");
3284
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003285 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 }
3287
3288 case CXCursor_OverloadedDeclRef: {
3289 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3291 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003292 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003293 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003295 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 OverloadedTemplateStorage *Ovl
3298 = Storage.get<OverloadedTemplateStorage*>();
3299 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003300 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003301 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 }
3303
3304 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003305 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 assert(Var && "Missing variable decl");
3307
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003308 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 }
3310
3311 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003312 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 }
3314 }
3315
3316 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003317 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 if (D)
3319 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003320 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 }
3322
3323 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003324 const Stmt *S = getCursorStmt(C);
3325 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003326 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003328 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
3330
3331 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003332 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 ->getNameStart());
3334
3335 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003336 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 ->getNameStart());
3338
3339 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003341
3342 if (clang_isDeclaration(C.kind))
3343 return getDeclSpelling(getCursorDecl(C));
3344
3345 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003346 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
3350 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003351 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003352 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 }
3354
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003355 if (C.kind == CXCursor_PackedAttr) {
3356 return cxstring::createRef("packed");
3357 }
3358
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003359 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003360}
3361
3362CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3363 unsigned pieceIndex,
3364 unsigned options) {
3365 if (clang_Cursor_isNull(C))
3366 return clang_getNullRange();
3367
3368 ASTContext &Ctx = getCursorContext(C);
3369
3370 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003371 const Stmt *S = getCursorStmt(C);
3372 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 if (pieceIndex > 0)
3374 return clang_getNullRange();
3375 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3376 }
3377
3378 return clang_getNullRange();
3379 }
3380
3381 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003382 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3384 if (pieceIndex >= ME->getNumSelectorLocs())
3385 return clang_getNullRange();
3386 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3387 }
3388 }
3389
3390 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3391 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003392 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3394 if (pieceIndex >= MD->getNumSelectorLocs())
3395 return clang_getNullRange();
3396 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3397 }
3398 }
3399
3400 if (C.kind == CXCursor_ObjCCategoryDecl ||
3401 C.kind == CXCursor_ObjCCategoryImplDecl) {
3402 if (pieceIndex > 0)
3403 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3406 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3409 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3410 }
3411
3412 if (C.kind == CXCursor_ModuleImportDecl) {
3413 if (pieceIndex > 0)
3414 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003415 if (const ImportDecl *ImportD =
3416 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3418 if (!Locs.empty())
3419 return cxloc::translateSourceRange(Ctx,
3420 SourceRange(Locs.front(), Locs.back()));
3421 }
3422 return clang_getNullRange();
3423 }
3424
3425 // FIXME: A CXCursor_InclusionDirective should give the location of the
3426 // filename, but we don't keep track of this.
3427
3428 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3429 // but we don't keep track of this.
3430
3431 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3432 // but we don't keep track of this.
3433
3434 // Default handling, give the location of the cursor.
3435
3436 if (pieceIndex > 0)
3437 return clang_getNullRange();
3438
3439 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3440 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3441 return cxloc::translateSourceRange(Ctx, Loc);
3442}
3443
3444CXString clang_getCursorDisplayName(CXCursor C) {
3445 if (!clang_isDeclaration(C.kind))
3446 return clang_getCursorSpelling(C);
3447
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003448 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003450 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003451
3452 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003453 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 D = FunTmpl->getTemplatedDecl();
3455
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003456 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 SmallString<64> Str;
3458 llvm::raw_svector_ostream OS(Str);
3459 OS << *Function;
3460 if (Function->getPrimaryTemplate())
3461 OS << "<>";
3462 OS << "(";
3463 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3464 if (I)
3465 OS << ", ";
3466 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3467 }
3468
3469 if (Function->isVariadic()) {
3470 if (Function->getNumParams())
3471 OS << ", ";
3472 OS << "...";
3473 }
3474 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003475 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 }
3477
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003478 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 SmallString<64> Str;
3480 llvm::raw_svector_ostream OS(Str);
3481 OS << *ClassTemplate;
3482 OS << "<";
3483 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3484 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3485 if (I)
3486 OS << ", ";
3487
3488 NamedDecl *Param = Params->getParam(I);
3489 if (Param->getIdentifier()) {
3490 OS << Param->getIdentifier()->getName();
3491 continue;
3492 }
3493
3494 // There is no parameter name, which makes this tricky. Try to come up
3495 // with something useful that isn't too long.
3496 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3497 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3498 else if (NonTypeTemplateParmDecl *NTTP
3499 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3500 OS << NTTP->getType().getAsString(Policy);
3501 else
3502 OS << "template<...> class";
3503 }
3504
3505 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003506 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 }
3508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3511 // If the type was explicitly written, use that.
3512 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003513 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003514
Benjamin Kramer9170e912013-02-22 15:46:01 +00003515 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 llvm::raw_svector_ostream OS(Str);
3517 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003518 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 ClassSpec->getTemplateArgs().data(),
3520 ClassSpec->getTemplateArgs().size(),
3521 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003522 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 }
3524
3525 return clang_getCursorSpelling(C);
3526}
3527
3528CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3529 switch (Kind) {
3530 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003531 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003533 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003535 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003537 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003539 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003541 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003543 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003545 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003547 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003549 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003565 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003567 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003569 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003571 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003573 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003575 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003579 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003581 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003583 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003585 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003587 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003589 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003593 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003595 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003597 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003599 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003603 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003605 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003609 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003658 case CXCursor_ObjCSelfExpr:
3659 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003776 case CXCursor_PackedAttr:
3777 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003826 case CXCursor_OMPParallelDirective:
3827 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 }
3829
3830 llvm_unreachable("Unhandled CXCursorKind");
3831}
3832
3833struct GetCursorData {
3834 SourceLocation TokenBeginLoc;
3835 bool PointsAtMacroArgExpansion;
3836 bool VisitedObjCPropertyImplDecl;
3837 SourceLocation VisitedDeclaratorDeclStartLoc;
3838 CXCursor &BestCursor;
3839
3840 GetCursorData(SourceManager &SM,
3841 SourceLocation tokenBegin, CXCursor &outputCursor)
3842 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3843 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3844 VisitedObjCPropertyImplDecl = false;
3845 }
3846};
3847
3848static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3849 CXCursor parent,
3850 CXClientData client_data) {
3851 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3852 CXCursor *BestCursor = &Data->BestCursor;
3853
3854 // If we point inside a macro argument we should provide info of what the
3855 // token is so use the actual cursor, don't replace it with a macro expansion
3856 // cursor.
3857 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3858 return CXChildVisit_Recurse;
3859
3860 if (clang_isDeclaration(cursor.kind)) {
3861 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003862 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3864 if (MD->isImplicit())
3865 return CXChildVisit_Break;
3866
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003867 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3869 // Check that when we have multiple @class references in the same line,
3870 // that later ones do not override the previous ones.
3871 // If we have:
3872 // @class Foo, Bar;
3873 // source ranges for both start at '@', so 'Bar' will end up overriding
3874 // 'Foo' even though the cursor location was at 'Foo'.
3875 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3876 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003877 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3879 if (PrevID != ID &&
3880 !PrevID->isThisDeclarationADefinition() &&
3881 !ID->isThisDeclarationADefinition())
3882 return CXChildVisit_Break;
3883 }
3884
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003885 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3887 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3888 // Check that when we have multiple declarators in the same line,
3889 // that later ones do not override the previous ones.
3890 // If we have:
3891 // int Foo, Bar;
3892 // source ranges for both start at 'int', so 'Bar' will end up overriding
3893 // 'Foo' even though the cursor location was at 'Foo'.
3894 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3895 return CXChildVisit_Break;
3896 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003898 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3900 (void)PropImp;
3901 // Check that when we have multiple @synthesize in the same line,
3902 // that later ones do not override the previous ones.
3903 // If we have:
3904 // @synthesize Foo, Bar;
3905 // source ranges for both start at '@', so 'Bar' will end up overriding
3906 // 'Foo' even though the cursor location was at 'Foo'.
3907 if (Data->VisitedObjCPropertyImplDecl)
3908 return CXChildVisit_Break;
3909 Data->VisitedObjCPropertyImplDecl = true;
3910 }
3911 }
3912
3913 if (clang_isExpression(cursor.kind) &&
3914 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 // Avoid having the cursor of an expression replace the declaration cursor
3917 // when the expression source range overlaps the declaration range.
3918 // This can happen for C++ constructor expressions whose range generally
3919 // include the variable declaration, e.g.:
3920 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3921 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3922 D->getLocation() == Data->TokenBeginLoc)
3923 return CXChildVisit_Break;
3924 }
3925 }
3926
3927 // If our current best cursor is the construction of a temporary object,
3928 // don't replace that cursor with a type reference, because we want
3929 // clang_getCursor() to point at the constructor.
3930 if (clang_isExpression(BestCursor->kind) &&
3931 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3932 cursor.kind == CXCursor_TypeRef) {
3933 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3934 // as having the actual point on the type reference.
3935 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3936 return CXChildVisit_Recurse;
3937 }
3938
3939 *BestCursor = cursor;
3940 return CXChildVisit_Recurse;
3941}
3942
3943CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3944 if (!TU)
3945 return clang_getNullCursor();
3946
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003947 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3949
3950 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3951 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3952
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003953 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 CXFile SearchFile;
3955 unsigned SearchLine, SearchColumn;
3956 CXFile ResultFile;
3957 unsigned ResultLine, ResultColumn;
3958 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3959 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3960 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3961
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003962 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3963 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 &ResultColumn, 0);
3965 SearchFileName = clang_getFileName(SearchFile);
3966 ResultFileName = clang_getFileName(ResultFile);
3967 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3968 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003969 *Log << llvm::format("(%s:%d:%d) = %s",
3970 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3971 clang_getCString(KindSpelling))
3972 << llvm::format("(%s:%d:%d):%s%s",
3973 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3974 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 clang_disposeString(SearchFileName);
3976 clang_disposeString(ResultFileName);
3977 clang_disposeString(KindSpelling);
3978 clang_disposeString(USR);
3979
3980 CXCursor Definition = clang_getCursorDefinition(Result);
3981 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3982 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3983 CXString DefinitionKindSpelling
3984 = clang_getCursorKindSpelling(Definition.kind);
3985 CXFile DefinitionFile;
3986 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003987 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 &DefinitionLine, &DefinitionColumn, 0);
3989 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003990 *Log << llvm::format(" -> %s(%s:%d:%d)",
3991 clang_getCString(DefinitionKindSpelling),
3992 clang_getCString(DefinitionFileName),
3993 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 clang_disposeString(DefinitionFileName);
3995 clang_disposeString(DefinitionKindSpelling);
3996 }
3997 }
3998
3999 return Result;
4000}
4001
4002CXCursor clang_getNullCursor(void) {
4003 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4004}
4005
4006unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004007 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4008 // can't set consistently. For example, when visiting a DeclStmt we will set
4009 // it but we don't set it on the result of clang_getCursorDefinition for
4010 // a reference of the same declaration.
4011 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4012 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4013 // to provide that kind of info.
4014 if (clang_isDeclaration(X.kind))
4015 X.data[1] = 0;
4016 if (clang_isDeclaration(Y.kind))
4017 Y.data[1] = 0;
4018
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 return X == Y;
4020}
4021
4022unsigned clang_hashCursor(CXCursor C) {
4023 unsigned Index = 0;
4024 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4025 Index = 1;
4026
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004027 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 std::make_pair(C.kind, C.data[Index]));
4029}
4030
4031unsigned clang_isInvalid(enum CXCursorKind K) {
4032 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4033}
4034
4035unsigned clang_isDeclaration(enum CXCursorKind K) {
4036 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4037 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4038}
4039
4040unsigned clang_isReference(enum CXCursorKind K) {
4041 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4042}
4043
4044unsigned clang_isExpression(enum CXCursorKind K) {
4045 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4046}
4047
4048unsigned clang_isStatement(enum CXCursorKind K) {
4049 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4050}
4051
4052unsigned clang_isAttribute(enum CXCursorKind K) {
4053 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4054}
4055
4056unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4057 return K == CXCursor_TranslationUnit;
4058}
4059
4060unsigned clang_isPreprocessing(enum CXCursorKind K) {
4061 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4062}
4063
4064unsigned clang_isUnexposed(enum CXCursorKind K) {
4065 switch (K) {
4066 case CXCursor_UnexposedDecl:
4067 case CXCursor_UnexposedExpr:
4068 case CXCursor_UnexposedStmt:
4069 case CXCursor_UnexposedAttr:
4070 return true;
4071 default:
4072 return false;
4073 }
4074}
4075
4076CXCursorKind clang_getCursorKind(CXCursor C) {
4077 return C.kind;
4078}
4079
4080CXSourceLocation clang_getCursorLocation(CXCursor C) {
4081 if (clang_isReference(C.kind)) {
4082 switch (C.kind) {
4083 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004084 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 = getCursorObjCSuperClassRef(C);
4086 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4087 }
4088
4089 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004090 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 = getCursorObjCProtocolRef(C);
4092 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4093 }
4094
4095 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004096 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 = getCursorObjCClassRef(C);
4098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4104 }
4105
4106 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004107 std::pair<const TemplateDecl *, SourceLocation> P =
4108 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4110 }
4111
4112 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4115 }
4116
4117 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004118 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4120 }
4121
4122 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4125 }
4126
4127 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004128 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 if (!BaseSpec)
4130 return clang_getNullLocation();
4131
4132 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4133 return cxloc::translateSourceLocation(getCursorContext(C),
4134 TSInfo->getTypeLoc().getBeginLoc());
4135
4136 return cxloc::translateSourceLocation(getCursorContext(C),
4137 BaseSpec->getLocStart());
4138 }
4139
4140 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004141 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4143 }
4144
4145 case CXCursor_OverloadedDeclRef:
4146 return cxloc::translateSourceLocation(getCursorContext(C),
4147 getCursorOverloadedDeclRef(C).second);
4148
4149 default:
4150 // FIXME: Need a way to enumerate all non-reference cases.
4151 llvm_unreachable("Missed a reference kind");
4152 }
4153 }
4154
4155 if (clang_isExpression(C.kind))
4156 return cxloc::translateSourceLocation(getCursorContext(C),
4157 getLocationFromExpr(getCursorExpr(C)));
4158
4159 if (clang_isStatement(C.kind))
4160 return cxloc::translateSourceLocation(getCursorContext(C),
4161 getCursorStmt(C)->getLocStart());
4162
4163 if (C.kind == CXCursor_PreprocessingDirective) {
4164 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4165 return cxloc::translateSourceLocation(getCursorContext(C), L);
4166 }
4167
4168 if (C.kind == CXCursor_MacroExpansion) {
4169 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004170 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
4174 if (C.kind == CXCursor_MacroDefinition) {
4175 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4176 return cxloc::translateSourceLocation(getCursorContext(C), L);
4177 }
4178
4179 if (C.kind == CXCursor_InclusionDirective) {
4180 SourceLocation L
4181 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4182 return cxloc::translateSourceLocation(getCursorContext(C), L);
4183 }
4184
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004185 if (clang_isAttribute(C.kind)) {
4186 SourceLocation L
4187 = cxcursor::getCursorAttr(C)->getLocation();
4188 return cxloc::translateSourceLocation(getCursorContext(C), L);
4189 }
4190
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 if (!clang_isDeclaration(C.kind))
4192 return clang_getNullLocation();
4193
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004194 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 if (!D)
4196 return clang_getNullLocation();
4197
4198 SourceLocation Loc = D->getLocation();
4199 // FIXME: Multiple variables declared in a single declaration
4200 // currently lack the information needed to correctly determine their
4201 // ranges when accounting for the type-specifier. We use context
4202 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4203 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004204 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 if (!cxcursor::isFirstInDeclGroup(C))
4206 Loc = VD->getLocation();
4207 }
4208
4209 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004210 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 Loc = MD->getSelectorStartLoc();
4212
4213 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4214}
4215
4216} // end extern "C"
4217
4218CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4219 assert(TU);
4220
4221 // Guard against an invalid SourceLocation, or we may assert in one
4222 // of the following calls.
4223 if (SLoc.isInvalid())
4224 return clang_getNullCursor();
4225
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004226 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004227
4228 // Translate the given source location to make it point at the beginning of
4229 // the token under the cursor.
4230 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4231 CXXUnit->getASTContext().getLangOpts());
4232
4233 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4234 if (SLoc.isValid()) {
4235 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4236 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4237 /*VisitPreprocessorLast=*/true,
4238 /*VisitIncludedEntities=*/false,
4239 SourceLocation(SLoc));
4240 CursorVis.visitFileRegion();
4241 }
4242
4243 return Result;
4244}
4245
4246static SourceRange getRawCursorExtent(CXCursor C) {
4247 if (clang_isReference(C.kind)) {
4248 switch (C.kind) {
4249 case CXCursor_ObjCSuperClassRef:
4250 return getCursorObjCSuperClassRef(C).second;
4251
4252 case CXCursor_ObjCProtocolRef:
4253 return getCursorObjCProtocolRef(C).second;
4254
4255 case CXCursor_ObjCClassRef:
4256 return getCursorObjCClassRef(C).second;
4257
4258 case CXCursor_TypeRef:
4259 return getCursorTypeRef(C).second;
4260
4261 case CXCursor_TemplateRef:
4262 return getCursorTemplateRef(C).second;
4263
4264 case CXCursor_NamespaceRef:
4265 return getCursorNamespaceRef(C).second;
4266
4267 case CXCursor_MemberRef:
4268 return getCursorMemberRef(C).second;
4269
4270 case CXCursor_CXXBaseSpecifier:
4271 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4272
4273 case CXCursor_LabelRef:
4274 return getCursorLabelRef(C).second;
4275
4276 case CXCursor_OverloadedDeclRef:
4277 return getCursorOverloadedDeclRef(C).second;
4278
4279 case CXCursor_VariableRef:
4280 return getCursorVariableRef(C).second;
4281
4282 default:
4283 // FIXME: Need a way to enumerate all non-reference cases.
4284 llvm_unreachable("Missed a reference kind");
4285 }
4286 }
4287
4288 if (clang_isExpression(C.kind))
4289 return getCursorExpr(C)->getSourceRange();
4290
4291 if (clang_isStatement(C.kind))
4292 return getCursorStmt(C)->getSourceRange();
4293
4294 if (clang_isAttribute(C.kind))
4295 return getCursorAttr(C)->getRange();
4296
4297 if (C.kind == CXCursor_PreprocessingDirective)
4298 return cxcursor::getCursorPreprocessingDirective(C);
4299
4300 if (C.kind == CXCursor_MacroExpansion) {
4301 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004302 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 return TU->mapRangeFromPreamble(Range);
4304 }
4305
4306 if (C.kind == CXCursor_MacroDefinition) {
4307 ASTUnit *TU = getCursorASTUnit(C);
4308 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4309 return TU->mapRangeFromPreamble(Range);
4310 }
4311
4312 if (C.kind == CXCursor_InclusionDirective) {
4313 ASTUnit *TU = getCursorASTUnit(C);
4314 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4315 return TU->mapRangeFromPreamble(Range);
4316 }
4317
4318 if (C.kind == CXCursor_TranslationUnit) {
4319 ASTUnit *TU = getCursorASTUnit(C);
4320 FileID MainID = TU->getSourceManager().getMainFileID();
4321 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4322 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4323 return SourceRange(Start, End);
4324 }
4325
4326 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004327 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 if (!D)
4329 return SourceRange();
4330
4331 SourceRange R = D->getSourceRange();
4332 // FIXME: Multiple variables declared in a single declaration
4333 // currently lack the information needed to correctly determine their
4334 // ranges when accounting for the type-specifier. We use context
4335 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4336 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004337 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 if (!cxcursor::isFirstInDeclGroup(C))
4339 R.setBegin(VD->getLocation());
4340 }
4341 return R;
4342 }
4343 return SourceRange();
4344}
4345
4346/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4347/// the decl-specifier-seq for declarations.
4348static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4349 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004350 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 if (!D)
4352 return SourceRange();
4353
4354 SourceRange R = D->getSourceRange();
4355
4356 // Adjust the start of the location for declarations preceded by
4357 // declaration specifiers.
4358 SourceLocation StartLoc;
4359 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4360 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4361 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004362 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4364 StartLoc = TI->getTypeLoc().getLocStart();
4365 }
4366
4367 if (StartLoc.isValid() && R.getBegin().isValid() &&
4368 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4369 R.setBegin(StartLoc);
4370
4371 // FIXME: Multiple variables declared in a single declaration
4372 // currently lack the information needed to correctly determine their
4373 // ranges when accounting for the type-specifier. We use context
4374 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4375 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004376 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 if (!cxcursor::isFirstInDeclGroup(C))
4378 R.setBegin(VD->getLocation());
4379 }
4380
4381 return R;
4382 }
4383
4384 return getRawCursorExtent(C);
4385}
4386
4387extern "C" {
4388
4389CXSourceRange clang_getCursorExtent(CXCursor C) {
4390 SourceRange R = getRawCursorExtent(C);
4391 if (R.isInvalid())
4392 return clang_getNullRange();
4393
4394 return cxloc::translateSourceRange(getCursorContext(C), R);
4395}
4396
4397CXCursor clang_getCursorReferenced(CXCursor C) {
4398 if (clang_isInvalid(C.kind))
4399 return clang_getNullCursor();
4400
4401 CXTranslationUnit tu = getCursorTU(C);
4402 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 if (!D)
4405 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004408 if (const ObjCPropertyImplDecl *PropImpl =
4409 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4411 return MakeCXCursor(Property, tu);
4412
4413 return C;
4414 }
4415
4416 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 const Expr *E = getCursorExpr(C);
4418 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 if (D) {
4420 CXCursor declCursor = MakeCXCursor(D, tu);
4421 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4422 declCursor);
4423 return declCursor;
4424 }
4425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004426 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 return MakeCursorOverloadedDeclRef(Ovl, tu);
4428
4429 return clang_getNullCursor();
4430 }
4431
4432 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004433 const Stmt *S = getCursorStmt(C);
4434 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 if (LabelDecl *label = Goto->getLabel())
4436 if (LabelStmt *labelS = label->getStmt())
4437 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4438
4439 return clang_getNullCursor();
4440 }
4441
4442 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004443 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 return MakeMacroDefinitionCursor(Def, tu);
4445 }
4446
4447 if (!clang_isReference(C.kind))
4448 return clang_getNullCursor();
4449
4450 switch (C.kind) {
4451 case CXCursor_ObjCSuperClassRef:
4452 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4453
4454 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004455 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4456 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 return MakeCXCursor(Def, tu);
4458
4459 return MakeCXCursor(Prot, tu);
4460 }
4461
4462 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004463 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4464 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 return MakeCXCursor(Def, tu);
4466
4467 return MakeCXCursor(Class, tu);
4468 }
4469
4470 case CXCursor_TypeRef:
4471 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4472
4473 case CXCursor_TemplateRef:
4474 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4475
4476 case CXCursor_NamespaceRef:
4477 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4478
4479 case CXCursor_MemberRef:
4480 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4481
4482 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004483 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4485 tu ));
4486 }
4487
4488 case CXCursor_LabelRef:
4489 // FIXME: We end up faking the "parent" declaration here because we
4490 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004491 return MakeCXCursor(getCursorLabelRef(C).first,
4492 cxtu::getASTUnit(tu)->getASTContext()
4493 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 tu);
4495
4496 case CXCursor_OverloadedDeclRef:
4497 return C;
4498
4499 case CXCursor_VariableRef:
4500 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4501
4502 default:
4503 // We would prefer to enumerate all non-reference cursor kinds here.
4504 llvm_unreachable("Unhandled reference cursor kind");
4505 }
4506}
4507
4508CXCursor clang_getCursorDefinition(CXCursor C) {
4509 if (clang_isInvalid(C.kind))
4510 return clang_getNullCursor();
4511
4512 CXTranslationUnit TU = getCursorTU(C);
4513
4514 bool WasReference = false;
4515 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4516 C = clang_getCursorReferenced(C);
4517 WasReference = true;
4518 }
4519
4520 if (C.kind == CXCursor_MacroExpansion)
4521 return clang_getCursorReferenced(C);
4522
4523 if (!clang_isDeclaration(C.kind))
4524 return clang_getNullCursor();
4525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 if (!D)
4528 return clang_getNullCursor();
4529
4530 switch (D->getKind()) {
4531 // Declaration kinds that don't really separate the notions of
4532 // declaration and definition.
4533 case Decl::Namespace:
4534 case Decl::Typedef:
4535 case Decl::TypeAlias:
4536 case Decl::TypeAliasTemplate:
4537 case Decl::TemplateTypeParm:
4538 case Decl::EnumConstant:
4539 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004540 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case Decl::IndirectField:
4542 case Decl::ObjCIvar:
4543 case Decl::ObjCAtDefsField:
4544 case Decl::ImplicitParam:
4545 case Decl::ParmVar:
4546 case Decl::NonTypeTemplateParm:
4547 case Decl::TemplateTemplateParm:
4548 case Decl::ObjCCategoryImpl:
4549 case Decl::ObjCImplementation:
4550 case Decl::AccessSpec:
4551 case Decl::LinkageSpec:
4552 case Decl::ObjCPropertyImpl:
4553 case Decl::FileScopeAsm:
4554 case Decl::StaticAssert:
4555 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004556 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case Decl::Label: // FIXME: Is this right??
4558 case Decl::ClassScopeFunctionSpecialization:
4559 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004560 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return C;
4562
4563 // Declaration kinds that don't make any sense here, but are
4564 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004565 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case Decl::TranslationUnit:
4567 break;
4568
4569 // Declaration kinds for which the definition is not resolvable.
4570 case Decl::UnresolvedUsingTypename:
4571 case Decl::UnresolvedUsingValue:
4572 break;
4573
4574 case Decl::UsingDirective:
4575 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4576 TU);
4577
4578 case Decl::NamespaceAlias:
4579 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4580
4581 case Decl::Enum:
4582 case Decl::Record:
4583 case Decl::CXXRecord:
4584 case Decl::ClassTemplateSpecialization:
4585 case Decl::ClassTemplatePartialSpecialization:
4586 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4587 return MakeCXCursor(Def, TU);
4588 return clang_getNullCursor();
4589
4590 case Decl::Function:
4591 case Decl::CXXMethod:
4592 case Decl::CXXConstructor:
4593 case Decl::CXXDestructor:
4594 case Decl::CXXConversion: {
4595 const FunctionDecl *Def = 0;
4596 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004597 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 return clang_getNullCursor();
4599 }
4600
Larisse Voufo39a1e502013-08-06 01:03:05 +00004601 case Decl::Var:
4602 case Decl::VarTemplateSpecialization:
4603 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004605 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 return MakeCXCursor(Def, TU);
4607 return clang_getNullCursor();
4608 }
4609
4610 case Decl::FunctionTemplate: {
4611 const FunctionDecl *Def = 0;
4612 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4613 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4614 return clang_getNullCursor();
4615 }
4616
4617 case Decl::ClassTemplate: {
4618 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4619 ->getDefinition())
4620 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4621 TU);
4622 return clang_getNullCursor();
4623 }
4624
Larisse Voufo39a1e502013-08-06 01:03:05 +00004625 case Decl::VarTemplate: {
4626 if (VarDecl *Def =
4627 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4628 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4629 return clang_getNullCursor();
4630 }
4631
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 case Decl::Using:
4633 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4634 D->getLocation(), TU);
4635
4636 case Decl::UsingShadow:
4637 return clang_getCursorDefinition(
4638 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4639 TU));
4640
4641 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004642 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 if (Method->isThisDeclarationADefinition())
4644 return C;
4645
4646 // Dig out the method definition in the associated
4647 // @implementation, if we have it.
4648 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004649 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4651 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4652 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4653 Method->isInstanceMethod()))
4654 if (Def->isThisDeclarationADefinition())
4655 return MakeCXCursor(Def, TU);
4656
4657 return clang_getNullCursor();
4658 }
4659
4660 case Decl::ObjCCategory:
4661 if (ObjCCategoryImplDecl *Impl
4662 = cast<ObjCCategoryDecl>(D)->getImplementation())
4663 return MakeCXCursor(Impl, TU);
4664 return clang_getNullCursor();
4665
4666 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004667 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 return MakeCXCursor(Def, TU);
4669 return clang_getNullCursor();
4670
4671 case Decl::ObjCInterface: {
4672 // There are two notions of a "definition" for an Objective-C
4673 // class: the interface and its implementation. When we resolved a
4674 // reference to an Objective-C class, produce the @interface as
4675 // the definition; when we were provided with the interface,
4676 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004677 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004679 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 return MakeCXCursor(Def, TU);
4681 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4682 return MakeCXCursor(Impl, TU);
4683 return clang_getNullCursor();
4684 }
4685
4686 case Decl::ObjCProperty:
4687 // FIXME: We don't really know where to find the
4688 // ObjCPropertyImplDecls that implement this property.
4689 return clang_getNullCursor();
4690
4691 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004692 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004694 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 return MakeCXCursor(Def, TU);
4696
4697 return clang_getNullCursor();
4698
4699 case Decl::Friend:
4700 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4701 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4702 return clang_getNullCursor();
4703
4704 case Decl::FriendTemplate:
4705 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4706 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4707 return clang_getNullCursor();
4708 }
4709
4710 return clang_getNullCursor();
4711}
4712
4713unsigned clang_isCursorDefinition(CXCursor C) {
4714 if (!clang_isDeclaration(C.kind))
4715 return 0;
4716
4717 return clang_getCursorDefinition(C) == C;
4718}
4719
4720CXCursor clang_getCanonicalCursor(CXCursor C) {
4721 if (!clang_isDeclaration(C.kind))
4722 return C;
4723
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 if (const Decl *D = getCursorDecl(C)) {
4725 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4727 return MakeCXCursor(CatD, getCursorTU(C));
4728
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4730 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 return MakeCXCursor(IFD, getCursorTU(C));
4732
4733 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4734 }
4735
4736 return C;
4737}
4738
4739int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4740 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4741}
4742
4743unsigned clang_getNumOverloadedDecls(CXCursor C) {
4744 if (C.kind != CXCursor_OverloadedDeclRef)
4745 return 0;
4746
4747 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004748 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 return E->getNumDecls();
4750
4751 if (OverloadedTemplateStorage *S
4752 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4753 return S->size();
4754
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004755 const Decl *D = Storage.get<const Decl *>();
4756 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 return Using->shadow_size();
4758
4759 return 0;
4760}
4761
4762CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4763 if (cursor.kind != CXCursor_OverloadedDeclRef)
4764 return clang_getNullCursor();
4765
4766 if (index >= clang_getNumOverloadedDecls(cursor))
4767 return clang_getNullCursor();
4768
4769 CXTranslationUnit TU = getCursorTU(cursor);
4770 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return MakeCXCursor(E->decls_begin()[index], TU);
4773
4774 if (OverloadedTemplateStorage *S
4775 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4776 return MakeCXCursor(S->begin()[index], TU);
4777
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004778 const Decl *D = Storage.get<const Decl *>();
4779 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 // FIXME: This is, unfortunately, linear time.
4781 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4782 std::advance(Pos, index);
4783 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4784 }
4785
4786 return clang_getNullCursor();
4787}
4788
4789void clang_getDefinitionSpellingAndExtent(CXCursor C,
4790 const char **startBuf,
4791 const char **endBuf,
4792 unsigned *startLine,
4793 unsigned *startColumn,
4794 unsigned *endLine,
4795 unsigned *endColumn) {
4796 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004797 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004798 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4799
4800 SourceManager &SM = FD->getASTContext().getSourceManager();
4801 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4802 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4803 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4804 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4805 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4806 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4807}
4808
4809
4810CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4811 unsigned PieceIndex) {
4812 RefNamePieces Pieces;
4813
4814 switch (C.kind) {
4815 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004816 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4818 E->getQualifierLoc().getSourceRange());
4819 break;
4820
4821 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004822 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4824 E->getQualifierLoc().getSourceRange(),
4825 E->getOptionalExplicitTemplateArgs());
4826 break;
4827
4828 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004829 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004831 const Expr *Callee = OCE->getCallee();
4832 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 Callee = ICE->getSubExpr();
4834
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004835 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4837 DRE->getQualifierLoc().getSourceRange());
4838 }
4839 break;
4840
4841 default:
4842 break;
4843 }
4844
4845 if (Pieces.empty()) {
4846 if (PieceIndex == 0)
4847 return clang_getCursorExtent(C);
4848 } else if (PieceIndex < Pieces.size()) {
4849 SourceRange R = Pieces[PieceIndex];
4850 if (R.isValid())
4851 return cxloc::translateSourceRange(getCursorContext(C), R);
4852 }
4853
4854 return clang_getNullRange();
4855}
4856
4857void clang_enableStackTraces(void) {
4858 llvm::sys::PrintStackTraceOnErrorSignal();
4859}
4860
4861void clang_executeOnThread(void (*fn)(void*), void *user_data,
4862 unsigned stack_size) {
4863 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4864}
4865
4866} // end: extern "C"
4867
4868//===----------------------------------------------------------------------===//
4869// Token-based Operations.
4870//===----------------------------------------------------------------------===//
4871
4872/* CXToken layout:
4873 * int_data[0]: a CXTokenKind
4874 * int_data[1]: starting token location
4875 * int_data[2]: token length
4876 * int_data[3]: reserved
4877 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4878 * otherwise unused.
4879 */
4880extern "C" {
4881
4882CXTokenKind clang_getTokenKind(CXToken CXTok) {
4883 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4884}
4885
4886CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4887 switch (clang_getTokenKind(CXTok)) {
4888 case CXToken_Identifier:
4889 case CXToken_Keyword:
4890 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004891 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 ->getNameStart());
4893
4894 case CXToken_Literal: {
4895 // We have stashed the starting pointer in the ptr_data field. Use it.
4896 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004897 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 }
4899
4900 case CXToken_Punctuation:
4901 case CXToken_Comment:
4902 break;
4903 }
4904
4905 // We have to find the starting buffer pointer the hard way, by
4906 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004907 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004909 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004910
4911 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4912 std::pair<FileID, unsigned> LocInfo
4913 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4914 bool Invalid = false;
4915 StringRef Buffer
4916 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4917 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004918 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004919
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004920 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004921}
4922
4923CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 if (!CXXUnit)
4926 return clang_getNullLocation();
4927
4928 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4929 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4930}
4931
4932CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004933 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 if (!CXXUnit)
4935 return clang_getNullRange();
4936
4937 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4938 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4939}
4940
4941static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4942 SmallVectorImpl<CXToken> &CXTokens) {
4943 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4944 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004945 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004947 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004948
4949 // Cannot tokenize across files.
4950 if (BeginLocInfo.first != EndLocInfo.first)
4951 return;
4952
4953 // Create a lexer
4954 bool Invalid = false;
4955 StringRef Buffer
4956 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4957 if (Invalid)
4958 return;
4959
4960 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4961 CXXUnit->getASTContext().getLangOpts(),
4962 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4963 Lex.SetCommentRetentionState(true);
4964
4965 // Lex tokens until we hit the end of the range.
4966 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4967 Token Tok;
4968 bool previousWasAt = false;
4969 do {
4970 // Lex the next token
4971 Lex.LexFromRawLexer(Tok);
4972 if (Tok.is(tok::eof))
4973 break;
4974
4975 // Initialize the CXToken.
4976 CXToken CXTok;
4977
4978 // - Common fields
4979 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4980 CXTok.int_data[2] = Tok.getLength();
4981 CXTok.int_data[3] = 0;
4982
4983 // - Kind-specific fields
4984 if (Tok.isLiteral()) {
4985 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004986 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 } else if (Tok.is(tok::raw_identifier)) {
4988 // Lookup the identifier to determine whether we have a keyword.
4989 IdentifierInfo *II
4990 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4991
4992 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4993 CXTok.int_data[0] = CXToken_Keyword;
4994 }
4995 else {
4996 CXTok.int_data[0] = Tok.is(tok::identifier)
4997 ? CXToken_Identifier
4998 : CXToken_Keyword;
4999 }
5000 CXTok.ptr_data = II;
5001 } else if (Tok.is(tok::comment)) {
5002 CXTok.int_data[0] = CXToken_Comment;
5003 CXTok.ptr_data = 0;
5004 } else {
5005 CXTok.int_data[0] = CXToken_Punctuation;
5006 CXTok.ptr_data = 0;
5007 }
5008 CXTokens.push_back(CXTok);
5009 previousWasAt = Tok.is(tok::at);
5010 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5011}
5012
5013void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5014 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005015 LOG_FUNC_SECTION {
5016 *Log << TU << ' ' << Range;
5017 }
5018
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 if (Tokens)
5020 *Tokens = 0;
5021 if (NumTokens)
5022 *NumTokens = 0;
5023
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005024 if (!TU)
5025 return;
5026
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005027 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 if (!CXXUnit || !Tokens || !NumTokens)
5029 return;
5030
5031 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5032
5033 SourceRange R = cxloc::translateCXSourceRange(Range);
5034 if (R.isInvalid())
5035 return;
5036
5037 SmallVector<CXToken, 32> CXTokens;
5038 getTokens(CXXUnit, R, CXTokens);
5039
5040 if (CXTokens.empty())
5041 return;
5042
5043 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5044 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5045 *NumTokens = CXTokens.size();
5046}
5047
5048void clang_disposeTokens(CXTranslationUnit TU,
5049 CXToken *Tokens, unsigned NumTokens) {
5050 free(Tokens);
5051}
5052
5053} // end: extern "C"
5054
5055//===----------------------------------------------------------------------===//
5056// Token annotation APIs.
5057//===----------------------------------------------------------------------===//
5058
Guy Benyei11169dd2012-12-18 14:30:41 +00005059static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5060 CXCursor parent,
5061 CXClientData client_data);
5062static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5063 CXClientData client_data);
5064
5065namespace {
5066class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 CXToken *Tokens;
5068 CXCursor *Cursors;
5069 unsigned NumTokens;
5070 unsigned TokIdx;
5071 unsigned PreprocessingTokIdx;
5072 CursorVisitor AnnotateVis;
5073 SourceManager &SrcMgr;
5074 bool HasContextSensitiveKeywords;
5075
5076 struct PostChildrenInfo {
5077 CXCursor Cursor;
5078 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005079 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 unsigned BeforeChildrenTokenIdx;
5081 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005082 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005083
5084 CXToken &getTok(unsigned Idx) {
5085 assert(Idx < NumTokens);
5086 return Tokens[Idx];
5087 }
5088 const CXToken &getTok(unsigned Idx) const {
5089 assert(Idx < NumTokens);
5090 return Tokens[Idx];
5091 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 bool MoreTokens() const { return TokIdx < NumTokens; }
5093 unsigned NextToken() const { return TokIdx; }
5094 void AdvanceToken() { ++TokIdx; }
5095 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005096 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 }
5098 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005099 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 }
5101 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005102 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 }
5104
5105 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005106 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 SourceRange);
5108
5109public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005110 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005111 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005112 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005114 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 AnnotateTokensVisitor, this,
5116 /*VisitPreprocessorLast=*/true,
5117 /*VisitIncludedEntities=*/false,
5118 RegionOfInterest,
5119 /*VisitDeclsOnly=*/false,
5120 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005121 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 HasContextSensitiveKeywords(false) { }
5123
5124 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5125 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5126 bool postVisitChildren(CXCursor cursor);
5127 void AnnotateTokens();
5128
5129 /// \brief Determine whether the annotator saw any cursors that have
5130 /// context-sensitive keywords.
5131 bool hasContextSensitiveKeywords() const {
5132 return HasContextSensitiveKeywords;
5133 }
5134
5135 ~AnnotateTokensWorker() {
5136 assert(PostChildrenInfos.empty());
5137 }
5138};
5139}
5140
5141void AnnotateTokensWorker::AnnotateTokens() {
5142 // Walk the AST within the region of interest, annotating tokens
5143 // along the way.
5144 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005145}
Guy Benyei11169dd2012-12-18 14:30:41 +00005146
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005147static inline void updateCursorAnnotation(CXCursor &Cursor,
5148 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005149 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005151 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005152}
5153
5154/// \brief It annotates and advances tokens with a cursor until the comparison
5155//// between the cursor location and the source range is the same as
5156/// \arg compResult.
5157///
5158/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5159/// Pass RangeOverlap to annotate tokens inside a range.
5160void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5161 RangeComparisonResult compResult,
5162 SourceRange range) {
5163 while (MoreTokens()) {
5164 const unsigned I = NextToken();
5165 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005166 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5167 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005168
5169 SourceLocation TokLoc = GetTokenLoc(I);
5170 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005171 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 AdvanceToken();
5173 continue;
5174 }
5175 break;
5176 }
5177}
5178
5179/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005180/// \returns true if it advanced beyond all macro tokens, false otherwise.
5181bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 CXCursor updateC,
5183 RangeComparisonResult compResult,
5184 SourceRange range) {
5185 assert(MoreTokens());
5186 assert(isFunctionMacroToken(NextToken()) &&
5187 "Should be called only for macro arg tokens");
5188
5189 // This works differently than annotateAndAdvanceTokens; because expanded
5190 // macro arguments can have arbitrary translation-unit source order, we do not
5191 // advance the token index one by one until a token fails the range test.
5192 // We only advance once past all of the macro arg tokens if all of them
5193 // pass the range test. If one of them fails we keep the token index pointing
5194 // at the start of the macro arg tokens so that the failing token will be
5195 // annotated by a subsequent annotation try.
5196
5197 bool atLeastOneCompFail = false;
5198
5199 unsigned I = NextToken();
5200 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5201 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5202 if (TokLoc.isFileID())
5203 continue; // not macro arg token, it's parens or comma.
5204 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5205 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5206 Cursors[I] = updateC;
5207 } else
5208 atLeastOneCompFail = true;
5209 }
5210
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005211 if (atLeastOneCompFail)
5212 return false;
5213
5214 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5215 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005216}
5217
5218enum CXChildVisitResult
5219AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 SourceRange cursorRange = getRawCursorExtent(cursor);
5221 if (cursorRange.isInvalid())
5222 return CXChildVisit_Recurse;
5223
5224 if (!HasContextSensitiveKeywords) {
5225 // Objective-C properties can have context-sensitive keywords.
5226 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005227 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5229 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5230 }
5231 // Objective-C methods can have context-sensitive keywords.
5232 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5233 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005234 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5236 if (Method->getObjCDeclQualifier())
5237 HasContextSensitiveKeywords = true;
5238 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005239 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5240 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 P != PEnd; ++P) {
5242 if ((*P)->getObjCDeclQualifier()) {
5243 HasContextSensitiveKeywords = true;
5244 break;
5245 }
5246 }
5247 }
5248 }
5249 }
5250 // C++ methods can have context-sensitive keywords.
5251 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005252 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5254 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5255 HasContextSensitiveKeywords = true;
5256 }
5257 }
5258 // C++ classes can have context-sensitive keywords.
5259 else if (cursor.kind == CXCursor_StructDecl ||
5260 cursor.kind == CXCursor_ClassDecl ||
5261 cursor.kind == CXCursor_ClassTemplate ||
5262 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005263 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 if (D->hasAttr<FinalAttr>())
5265 HasContextSensitiveKeywords = true;
5266 }
5267 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005268
5269 // Don't override a property annotation with its getter/setter method.
5270 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5271 parent.kind == CXCursor_ObjCPropertyDecl)
5272 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005273
5274 if (clang_isPreprocessing(cursor.kind)) {
5275 // Items in the preprocessing record are kept separate from items in
5276 // declarations, so we keep a separate token index.
5277 unsigned SavedTokIdx = TokIdx;
5278 TokIdx = PreprocessingTokIdx;
5279
5280 // Skip tokens up until we catch up to the beginning of the preprocessing
5281 // entry.
5282 while (MoreTokens()) {
5283 const unsigned I = NextToken();
5284 SourceLocation TokLoc = GetTokenLoc(I);
5285 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5286 case RangeBefore:
5287 AdvanceToken();
5288 continue;
5289 case RangeAfter:
5290 case RangeOverlap:
5291 break;
5292 }
5293 break;
5294 }
5295
5296 // Look at all of the tokens within this range.
5297 while (MoreTokens()) {
5298 const unsigned I = NextToken();
5299 SourceLocation TokLoc = GetTokenLoc(I);
5300 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5301 case RangeBefore:
5302 llvm_unreachable("Infeasible");
5303 case RangeAfter:
5304 break;
5305 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005306 // For macro expansions, just note where the beginning of the macro
5307 // expansion occurs.
5308 if (cursor.kind == CXCursor_MacroExpansion) {
5309 if (TokLoc == cursorRange.getBegin())
5310 Cursors[I] = cursor;
5311 AdvanceToken();
5312 break;
5313 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005314 // We may have already annotated macro names inside macro definitions.
5315 if (Cursors[I].kind != CXCursor_MacroExpansion)
5316 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005317 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 continue;
5319 }
5320 break;
5321 }
5322
5323 // Save the preprocessing token index; restore the non-preprocessing
5324 // token index.
5325 PreprocessingTokIdx = TokIdx;
5326 TokIdx = SavedTokIdx;
5327 return CXChildVisit_Recurse;
5328 }
5329
5330 if (cursorRange.isInvalid())
5331 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005332
5333 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 const enum CXCursorKind K = clang_getCursorKind(parent);
5336 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005337 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5338 // Attributes are annotated out-of-order, skip tokens until we reach it.
5339 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 ? clang_getNullCursor() : parent;
5341
5342 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5343
5344 // Avoid having the cursor of an expression "overwrite" the annotation of the
5345 // variable declaration that it belongs to.
5346 // This can happen for C++ constructor expressions whose range generally
5347 // include the variable declaration, e.g.:
5348 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005349 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005350 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005351 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 const unsigned I = NextToken();
5353 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5354 E->getLocStart() == D->getLocation() &&
5355 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005356 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 AdvanceToken();
5358 }
5359 }
5360 }
5361
5362 // Before recursing into the children keep some state that we are going
5363 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5364 // extra work after the child nodes are visited.
5365 // Note that we don't call VisitChildren here to avoid traversing statements
5366 // code-recursively which can blow the stack.
5367
5368 PostChildrenInfo Info;
5369 Info.Cursor = cursor;
5370 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005371 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 Info.BeforeChildrenTokenIdx = NextToken();
5373 PostChildrenInfos.push_back(Info);
5374
5375 return CXChildVisit_Recurse;
5376}
5377
5378bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5379 if (PostChildrenInfos.empty())
5380 return false;
5381 const PostChildrenInfo &Info = PostChildrenInfos.back();
5382 if (!clang_equalCursors(Info.Cursor, cursor))
5383 return false;
5384
5385 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5386 const unsigned AfterChildren = NextToken();
5387 SourceRange cursorRange = Info.CursorRange;
5388
5389 // Scan the tokens that are at the end of the cursor, but are not captured
5390 // but the child cursors.
5391 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5392
5393 // Scan the tokens that are at the beginning of the cursor, but are not
5394 // capture by the child cursors.
5395 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5396 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5397 break;
5398
5399 Cursors[I] = cursor;
5400 }
5401
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005402 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5403 // encountered the attribute cursor.
5404 if (clang_isAttribute(cursor.kind))
5405 TokIdx = Info.BeforeReachingCursorIdx;
5406
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 PostChildrenInfos.pop_back();
5408 return false;
5409}
5410
5411static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5412 CXCursor parent,
5413 CXClientData client_data) {
5414 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5415}
5416
5417static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5418 CXClientData client_data) {
5419 return static_cast<AnnotateTokensWorker*>(client_data)->
5420 postVisitChildren(cursor);
5421}
5422
5423namespace {
5424
5425/// \brief Uses the macro expansions in the preprocessing record to find
5426/// and mark tokens that are macro arguments. This info is used by the
5427/// AnnotateTokensWorker.
5428class MarkMacroArgTokensVisitor {
5429 SourceManager &SM;
5430 CXToken *Tokens;
5431 unsigned NumTokens;
5432 unsigned CurIdx;
5433
5434public:
5435 MarkMacroArgTokensVisitor(SourceManager &SM,
5436 CXToken *tokens, unsigned numTokens)
5437 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5438
5439 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5440 if (cursor.kind != CXCursor_MacroExpansion)
5441 return CXChildVisit_Continue;
5442
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005443 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 if (macroRange.getBegin() == macroRange.getEnd())
5445 return CXChildVisit_Continue; // it's not a function macro.
5446
5447 for (; CurIdx < NumTokens; ++CurIdx) {
5448 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5449 macroRange.getBegin()))
5450 break;
5451 }
5452
5453 if (CurIdx == NumTokens)
5454 return CXChildVisit_Break;
5455
5456 for (; CurIdx < NumTokens; ++CurIdx) {
5457 SourceLocation tokLoc = getTokenLoc(CurIdx);
5458 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5459 break;
5460
5461 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5462 }
5463
5464 if (CurIdx == NumTokens)
5465 return CXChildVisit_Break;
5466
5467 return CXChildVisit_Continue;
5468 }
5469
5470private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005471 CXToken &getTok(unsigned Idx) {
5472 assert(Idx < NumTokens);
5473 return Tokens[Idx];
5474 }
5475 const CXToken &getTok(unsigned Idx) const {
5476 assert(Idx < NumTokens);
5477 return Tokens[Idx];
5478 }
5479
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005481 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 }
5483
5484 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5485 // The third field is reserved and currently not used. Use it here
5486 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005487 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 }
5489};
5490
5491} // end anonymous namespace
5492
5493static CXChildVisitResult
5494MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5495 CXClientData client_data) {
5496 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5497 parent);
5498}
5499
5500namespace {
5501 struct clang_annotateTokens_Data {
5502 CXTranslationUnit TU;
5503 ASTUnit *CXXUnit;
5504 CXToken *Tokens;
5505 unsigned NumTokens;
5506 CXCursor *Cursors;
5507 };
5508}
5509
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005510/// \brief Used by \c annotatePreprocessorTokens.
5511/// \returns true if lexing was finished, false otherwise.
5512static bool lexNext(Lexer &Lex, Token &Tok,
5513 unsigned &NextIdx, unsigned NumTokens) {
5514 if (NextIdx >= NumTokens)
5515 return true;
5516
5517 ++NextIdx;
5518 Lex.LexFromRawLexer(Tok);
5519 if (Tok.is(tok::eof))
5520 return true;
5521
5522 return false;
5523}
5524
Guy Benyei11169dd2012-12-18 14:30:41 +00005525static void annotatePreprocessorTokens(CXTranslationUnit TU,
5526 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005527 CXCursor *Cursors,
5528 CXToken *Tokens,
5529 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005530 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005531
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005532 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5534 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005535 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005536 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005537 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005538
5539 if (BeginLocInfo.first != EndLocInfo.first)
5540 return;
5541
5542 StringRef Buffer;
5543 bool Invalid = false;
5544 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5545 if (Buffer.empty() || Invalid)
5546 return;
5547
5548 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5549 CXXUnit->getASTContext().getLangOpts(),
5550 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5551 Buffer.end());
5552 Lex.SetCommentRetentionState(true);
5553
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005554 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 // Lex tokens in raw mode until we hit the end of the range, to avoid
5556 // entering #includes or expanding macros.
5557 while (true) {
5558 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005559 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5560 break;
5561 unsigned TokIdx = NextIdx-1;
5562 assert(Tok.getLocation() ==
5563 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005564
5565 reprocess:
5566 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005567 // We have found a preprocessing directive. Annotate the tokens
5568 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 //
5570 // FIXME: Some simple tests here could identify macro definitions and
5571 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005572
5573 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005574 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5575 break;
5576
5577 MacroInfo *MI = 0;
5578 if (Tok.is(tok::raw_identifier) &&
5579 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5580 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5581 break;
5582
5583 if (Tok.is(tok::raw_identifier)) {
5584 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5585 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5586 SourceLocation MappedTokLoc =
5587 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5588 MI = getMacroInfo(II, MappedTokLoc, TU);
5589 }
5590 }
5591
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005592 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005594 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5595 finished = true;
5596 break;
5597 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005598 // If we are in a macro definition, check if the token was ever a
5599 // macro name and annotate it if that's the case.
5600 if (MI) {
5601 SourceLocation SaveLoc = Tok.getLocation();
5602 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5603 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5604 Tok.setLocation(SaveLoc);
5605 if (MacroDef)
5606 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5607 Tok.getLocation(), TU);
5608 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005609 } while (!Tok.isAtStartOfLine());
5610
5611 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5612 assert(TokIdx <= LastIdx);
5613 SourceLocation EndLoc =
5614 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5615 CXCursor Cursor =
5616 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5617
5618 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005619 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005620
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005621 if (finished)
5622 break;
5623 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 }
5626}
5627
5628// This gets run a separate thread to avoid stack blowout.
5629static void clang_annotateTokensImpl(void *UserData) {
5630 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5631 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5632 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5633 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5634 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5635
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005636 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5638 setThreadBackgroundPriority();
5639
5640 // Determine the region of interest, which contains all of the tokens.
5641 SourceRange RegionOfInterest;
5642 RegionOfInterest.setBegin(
5643 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5644 RegionOfInterest.setEnd(
5645 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5646 Tokens[NumTokens-1])));
5647
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 // Relex the tokens within the source range to look for preprocessing
5649 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005650 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005651
5652 // If begin location points inside a macro argument, set it to the expansion
5653 // location so we can have the full context when annotating semantically.
5654 {
5655 SourceManager &SM = CXXUnit->getSourceManager();
5656 SourceLocation Loc =
5657 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5658 if (Loc.isMacroID())
5659 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5660 }
5661
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5663 // Search and mark tokens that are macro argument expansions.
5664 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5665 Tokens, NumTokens);
5666 CursorVisitor MacroArgMarker(TU,
5667 MarkMacroArgTokensVisitorDelegate, &Visitor,
5668 /*VisitPreprocessorLast=*/true,
5669 /*VisitIncludedEntities=*/false,
5670 RegionOfInterest);
5671 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5672 }
5673
5674 // Annotate all of the source locations in the region of interest that map to
5675 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005676 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005677
5678 // FIXME: We use a ridiculous stack size here because the data-recursion
5679 // algorithm uses a large stack frame than the non-data recursive version,
5680 // and AnnotationTokensWorker currently transforms the data-recursion
5681 // algorithm back into a traditional recursion by explicitly calling
5682 // VisitChildren(). We will need to remove this explicit recursive call.
5683 W.AnnotateTokens();
5684
5685 // If we ran into any entities that involve context-sensitive keywords,
5686 // take another pass through the tokens to mark them as such.
5687 if (W.hasContextSensitiveKeywords()) {
5688 for (unsigned I = 0; I != NumTokens; ++I) {
5689 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5690 continue;
5691
5692 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5693 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005694 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5696 if (Property->getPropertyAttributesAsWritten() != 0 &&
5697 llvm::StringSwitch<bool>(II->getName())
5698 .Case("readonly", true)
5699 .Case("assign", true)
5700 .Case("unsafe_unretained", true)
5701 .Case("readwrite", true)
5702 .Case("retain", true)
5703 .Case("copy", true)
5704 .Case("nonatomic", true)
5705 .Case("atomic", true)
5706 .Case("getter", true)
5707 .Case("setter", true)
5708 .Case("strong", true)
5709 .Case("weak", true)
5710 .Default(false))
5711 Tokens[I].int_data[0] = CXToken_Keyword;
5712 }
5713 continue;
5714 }
5715
5716 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5717 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5718 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5719 if (llvm::StringSwitch<bool>(II->getName())
5720 .Case("in", true)
5721 .Case("out", true)
5722 .Case("inout", true)
5723 .Case("oneway", true)
5724 .Case("bycopy", true)
5725 .Case("byref", true)
5726 .Default(false))
5727 Tokens[I].int_data[0] = CXToken_Keyword;
5728 continue;
5729 }
5730
5731 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5732 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5733 Tokens[I].int_data[0] = CXToken_Keyword;
5734 continue;
5735 }
5736 }
5737 }
5738}
5739
5740extern "C" {
5741
5742void clang_annotateTokens(CXTranslationUnit TU,
5743 CXToken *Tokens, unsigned NumTokens,
5744 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005745 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005746 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005748 }
5749
5750 LOG_FUNC_SECTION {
5751 *Log << TU << ' ';
5752 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5753 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5754 *Log << clang_getRange(bloc, eloc);
5755 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005756
5757 // Any token we don't specifically annotate will have a NULL cursor.
5758 CXCursor C = clang_getNullCursor();
5759 for (unsigned I = 0; I != NumTokens; ++I)
5760 Cursors[I] = C;
5761
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005762 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 if (!CXXUnit)
5764 return;
5765
5766 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5767
5768 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5769 llvm::CrashRecoveryContext CRC;
5770 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5771 GetSafetyThreadStackSize() * 2)) {
5772 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5773 }
5774}
5775
5776} // end: extern "C"
5777
5778//===----------------------------------------------------------------------===//
5779// Operations for querying linkage of a cursor.
5780//===----------------------------------------------------------------------===//
5781
5782extern "C" {
5783CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5784 if (!clang_isDeclaration(cursor.kind))
5785 return CXLinkage_Invalid;
5786
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005787 const Decl *D = cxcursor::getCursorDecl(cursor);
5788 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005789 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005790 case NoLinkage:
5791 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 case InternalLinkage: return CXLinkage_Internal;
5793 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5794 case ExternalLinkage: return CXLinkage_External;
5795 };
5796
5797 return CXLinkage_Invalid;
5798}
5799} // end: extern "C"
5800
5801//===----------------------------------------------------------------------===//
5802// Operations for querying language of a cursor.
5803//===----------------------------------------------------------------------===//
5804
5805static CXLanguageKind getDeclLanguage(const Decl *D) {
5806 if (!D)
5807 return CXLanguage_C;
5808
5809 switch (D->getKind()) {
5810 default:
5811 break;
5812 case Decl::ImplicitParam:
5813 case Decl::ObjCAtDefsField:
5814 case Decl::ObjCCategory:
5815 case Decl::ObjCCategoryImpl:
5816 case Decl::ObjCCompatibleAlias:
5817 case Decl::ObjCImplementation:
5818 case Decl::ObjCInterface:
5819 case Decl::ObjCIvar:
5820 case Decl::ObjCMethod:
5821 case Decl::ObjCProperty:
5822 case Decl::ObjCPropertyImpl:
5823 case Decl::ObjCProtocol:
5824 return CXLanguage_ObjC;
5825 case Decl::CXXConstructor:
5826 case Decl::CXXConversion:
5827 case Decl::CXXDestructor:
5828 case Decl::CXXMethod:
5829 case Decl::CXXRecord:
5830 case Decl::ClassTemplate:
5831 case Decl::ClassTemplatePartialSpecialization:
5832 case Decl::ClassTemplateSpecialization:
5833 case Decl::Friend:
5834 case Decl::FriendTemplate:
5835 case Decl::FunctionTemplate:
5836 case Decl::LinkageSpec:
5837 case Decl::Namespace:
5838 case Decl::NamespaceAlias:
5839 case Decl::NonTypeTemplateParm:
5840 case Decl::StaticAssert:
5841 case Decl::TemplateTemplateParm:
5842 case Decl::TemplateTypeParm:
5843 case Decl::UnresolvedUsingTypename:
5844 case Decl::UnresolvedUsingValue:
5845 case Decl::Using:
5846 case Decl::UsingDirective:
5847 case Decl::UsingShadow:
5848 return CXLanguage_CPlusPlus;
5849 }
5850
5851 return CXLanguage_C;
5852}
5853
5854extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005855
5856static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5857 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5858 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005859
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005860 switch (D->getAvailability()) {
5861 case AR_Available:
5862 case AR_NotYetIntroduced:
5863 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005864 return getCursorAvailabilityForDecl(
5865 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005866 return CXAvailability_Available;
5867
5868 case AR_Deprecated:
5869 return CXAvailability_Deprecated;
5870
5871 case AR_Unavailable:
5872 return CXAvailability_NotAvailable;
5873 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005874
5875 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005876}
5877
Guy Benyei11169dd2012-12-18 14:30:41 +00005878enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5879 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005880 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5881 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005882
5883 return CXAvailability_Available;
5884}
5885
5886static CXVersion convertVersion(VersionTuple In) {
5887 CXVersion Out = { -1, -1, -1 };
5888 if (In.empty())
5889 return Out;
5890
5891 Out.Major = In.getMajor();
5892
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005893 Optional<unsigned> Minor = In.getMinor();
5894 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 Out.Minor = *Minor;
5896 else
5897 return Out;
5898
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005899 Optional<unsigned> Subminor = In.getSubminor();
5900 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 Out.Subminor = *Subminor;
5902
5903 return Out;
5904}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005905
5906static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5907 int *always_deprecated,
5908 CXString *deprecated_message,
5909 int *always_unavailable,
5910 CXString *unavailable_message,
5911 CXPlatformAvailability *availability,
5912 int availability_size) {
5913 bool HadAvailAttr = false;
5914 int N = 0;
5915 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5916 ++A) {
5917 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5918 HadAvailAttr = true;
5919 if (always_deprecated)
5920 *always_deprecated = 1;
5921 if (deprecated_message)
5922 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5923 continue;
5924 }
5925
5926 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5927 HadAvailAttr = true;
5928 if (always_unavailable)
5929 *always_unavailable = 1;
5930 if (unavailable_message) {
5931 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5932 }
5933 continue;
5934 }
5935
5936 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5937 HadAvailAttr = true;
5938 if (N < availability_size) {
5939 availability[N].Platform
5940 = cxstring::createDup(Avail->getPlatform()->getName());
5941 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5942 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5943 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5944 availability[N].Unavailable = Avail->getUnavailable();
5945 availability[N].Message = cxstring::createDup(Avail->getMessage());
5946 }
5947 ++N;
5948 }
5949 }
5950
5951 if (!HadAvailAttr)
5952 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5953 return getCursorPlatformAvailabilityForDecl(
5954 cast<Decl>(EnumConst->getDeclContext()),
5955 always_deprecated,
5956 deprecated_message,
5957 always_unavailable,
5958 unavailable_message,
5959 availability,
5960 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005961
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005962 return N;
5963}
5964
Guy Benyei11169dd2012-12-18 14:30:41 +00005965int clang_getCursorPlatformAvailability(CXCursor cursor,
5966 int *always_deprecated,
5967 CXString *deprecated_message,
5968 int *always_unavailable,
5969 CXString *unavailable_message,
5970 CXPlatformAvailability *availability,
5971 int availability_size) {
5972 if (always_deprecated)
5973 *always_deprecated = 0;
5974 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005975 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 if (always_unavailable)
5977 *always_unavailable = 0;
5978 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005979 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005980
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 if (!clang_isDeclaration(cursor.kind))
5982 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005983
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005984 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005985 if (!D)
5986 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005987
5988 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5989 deprecated_message,
5990 always_unavailable,
5991 unavailable_message,
5992 availability,
5993 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005994}
5995
5996void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5997 clang_disposeString(availability->Platform);
5998 clang_disposeString(availability->Message);
5999}
6000
6001CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6002 if (clang_isDeclaration(cursor.kind))
6003 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6004
6005 return CXLanguage_Invalid;
6006}
6007
6008 /// \brief If the given cursor is the "templated" declaration
6009 /// descibing a class or function template, return the class or
6010 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006011static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 if (!D)
6013 return 0;
6014
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006015 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6017 return FunTmpl;
6018
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006019 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6021 return ClassTmpl;
6022
6023 return D;
6024}
6025
6026CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6027 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006028 if (const Decl *D = getCursorDecl(cursor)) {
6029 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 if (!DC)
6031 return clang_getNullCursor();
6032
6033 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6034 getCursorTU(cursor));
6035 }
6036 }
6037
6038 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006039 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006040 return MakeCXCursor(D, getCursorTU(cursor));
6041 }
6042
6043 return clang_getNullCursor();
6044}
6045
6046CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6047 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006048 if (const Decl *D = getCursorDecl(cursor)) {
6049 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 if (!DC)
6051 return clang_getNullCursor();
6052
6053 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6054 getCursorTU(cursor));
6055 }
6056 }
6057
6058 // FIXME: Note that we can't easily compute the lexical context of a
6059 // statement or expression, so we return nothing.
6060 return clang_getNullCursor();
6061}
6062
6063CXFile clang_getIncludedFile(CXCursor cursor) {
6064 if (cursor.kind != CXCursor_InclusionDirective)
6065 return 0;
6066
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006067 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006068 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006069}
6070
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006071unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6072 if (C.kind != CXCursor_ObjCPropertyDecl)
6073 return CXObjCPropertyAttr_noattr;
6074
6075 unsigned Result = CXObjCPropertyAttr_noattr;
6076 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6077 ObjCPropertyDecl::PropertyAttributeKind Attr =
6078 PD->getPropertyAttributesAsWritten();
6079
6080#define SET_CXOBJCPROP_ATTR(A) \
6081 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6082 Result |= CXObjCPropertyAttr_##A
6083 SET_CXOBJCPROP_ATTR(readonly);
6084 SET_CXOBJCPROP_ATTR(getter);
6085 SET_CXOBJCPROP_ATTR(assign);
6086 SET_CXOBJCPROP_ATTR(readwrite);
6087 SET_CXOBJCPROP_ATTR(retain);
6088 SET_CXOBJCPROP_ATTR(copy);
6089 SET_CXOBJCPROP_ATTR(nonatomic);
6090 SET_CXOBJCPROP_ATTR(setter);
6091 SET_CXOBJCPROP_ATTR(atomic);
6092 SET_CXOBJCPROP_ATTR(weak);
6093 SET_CXOBJCPROP_ATTR(strong);
6094 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6095#undef SET_CXOBJCPROP_ATTR
6096
6097 return Result;
6098}
6099
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006100unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6101 if (!clang_isDeclaration(C.kind))
6102 return CXObjCDeclQualifier_None;
6103
6104 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6105 const Decl *D = getCursorDecl(C);
6106 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6107 QT = MD->getObjCDeclQualifier();
6108 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6109 QT = PD->getObjCDeclQualifier();
6110 if (QT == Decl::OBJC_TQ_None)
6111 return CXObjCDeclQualifier_None;
6112
6113 unsigned Result = CXObjCDeclQualifier_None;
6114 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6115 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6116 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6117 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6118 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6119 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6120
6121 return Result;
6122}
6123
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006124unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6125 if (!clang_isDeclaration(C.kind))
6126 return 0;
6127
6128 const Decl *D = getCursorDecl(C);
6129 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6130 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6131 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6132 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6133
6134 return 0;
6135}
6136
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006137unsigned clang_Cursor_isVariadic(CXCursor C) {
6138 if (!clang_isDeclaration(C.kind))
6139 return 0;
6140
6141 const Decl *D = getCursorDecl(C);
6142 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6143 return FD->isVariadic();
6144 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6145 return MD->isVariadic();
6146
6147 return 0;
6148}
6149
Guy Benyei11169dd2012-12-18 14:30:41 +00006150CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6151 if (!clang_isDeclaration(C.kind))
6152 return clang_getNullRange();
6153
6154 const Decl *D = getCursorDecl(C);
6155 ASTContext &Context = getCursorContext(C);
6156 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6157 if (!RC)
6158 return clang_getNullRange();
6159
6160 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6161}
6162
6163CXString clang_Cursor_getRawCommentText(CXCursor C) {
6164 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006165 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006166
6167 const Decl *D = getCursorDecl(C);
6168 ASTContext &Context = getCursorContext(C);
6169 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6170 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6171 StringRef();
6172
6173 // Don't duplicate the string because RawText points directly into source
6174 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006175 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006176}
6177
6178CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6179 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006180 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006181
6182 const Decl *D = getCursorDecl(C);
6183 const ASTContext &Context = getCursorContext(C);
6184 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6185
6186 if (RC) {
6187 StringRef BriefText = RC->getBriefText(Context);
6188
6189 // Don't duplicate the string because RawComment ensures that this memory
6190 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006191 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 }
6193
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006194 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006195}
6196
6197CXComment clang_Cursor_getParsedComment(CXCursor C) {
6198 if (!clang_isDeclaration(C.kind))
6199 return cxcomment::createCXComment(NULL, NULL);
6200
6201 const Decl *D = getCursorDecl(C);
6202 const ASTContext &Context = getCursorContext(C);
6203 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6204
6205 return cxcomment::createCXComment(FC, getCursorTU(C));
6206}
6207
6208CXModule clang_Cursor_getModule(CXCursor C) {
6209 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006210 if (const ImportDecl *ImportD =
6211 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006212 return ImportD->getImportedModule();
6213 }
6214
6215 return 0;
6216}
6217
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006218CXFile clang_Module_getASTFile(CXModule CXMod) {
6219 if (!CXMod)
6220 return 0;
6221 Module *Mod = static_cast<Module*>(CXMod);
6222 return const_cast<FileEntry *>(Mod->getASTFile());
6223}
6224
Guy Benyei11169dd2012-12-18 14:30:41 +00006225CXModule clang_Module_getParent(CXModule CXMod) {
6226 if (!CXMod)
6227 return 0;
6228 Module *Mod = static_cast<Module*>(CXMod);
6229 return Mod->Parent;
6230}
6231
6232CXString clang_Module_getName(CXModule CXMod) {
6233 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006234 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006235 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006236 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006237}
6238
6239CXString clang_Module_getFullName(CXModule CXMod) {
6240 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006241 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006243 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006244}
6245
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006246unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6247 CXModule CXMod) {
6248 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 return 0;
6250 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006251 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6252 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6253 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006254}
6255
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006256CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6257 CXModule CXMod, unsigned Index) {
6258 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006259 return 0;
6260 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006261 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006262
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006263 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6264 if (Index < TopHeaders.size())
6265 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006266
6267 return 0;
6268}
6269
6270} // end: extern "C"
6271
6272//===----------------------------------------------------------------------===//
6273// C++ AST instrospection.
6274//===----------------------------------------------------------------------===//
6275
6276extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006277unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6278 if (!clang_isDeclaration(C.kind))
6279 return 0;
6280
6281 const CXXMethodDecl *Method = 0;
6282 const Decl *D = cxcursor::getCursorDecl(C);
6283 if (const FunctionTemplateDecl *FunTmpl =
6284 dyn_cast_or_null<FunctionTemplateDecl>(D))
6285 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6286 else
6287 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6288 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6289}
6290
Guy Benyei11169dd2012-12-18 14:30:41 +00006291unsigned clang_CXXMethod_isStatic(CXCursor C) {
6292 if (!clang_isDeclaration(C.kind))
6293 return 0;
6294
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006295 const CXXMethodDecl *Method = 0;
6296 const Decl *D = cxcursor::getCursorDecl(C);
6297 if (const FunctionTemplateDecl *FunTmpl =
6298 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6300 else
6301 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6302 return (Method && Method->isStatic()) ? 1 : 0;
6303}
6304
6305unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6306 if (!clang_isDeclaration(C.kind))
6307 return 0;
6308
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006309 const CXXMethodDecl *Method = 0;
6310 const Decl *D = cxcursor::getCursorDecl(C);
6311 if (const FunctionTemplateDecl *FunTmpl =
6312 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6314 else
6315 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6316 return (Method && Method->isVirtual()) ? 1 : 0;
6317}
6318} // end: extern "C"
6319
6320//===----------------------------------------------------------------------===//
6321// Attribute introspection.
6322//===----------------------------------------------------------------------===//
6323
6324extern "C" {
6325CXType clang_getIBOutletCollectionType(CXCursor C) {
6326 if (C.kind != CXCursor_IBOutletCollectionAttr)
6327 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6328
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006329 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006330 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6331
6332 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6333}
6334} // end: extern "C"
6335
6336//===----------------------------------------------------------------------===//
6337// Inspecting memory usage.
6338//===----------------------------------------------------------------------===//
6339
6340typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6341
6342static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6343 enum CXTUResourceUsageKind k,
6344 unsigned long amount) {
6345 CXTUResourceUsageEntry entry = { k, amount };
6346 entries.push_back(entry);
6347}
6348
6349extern "C" {
6350
6351const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6352 const char *str = "";
6353 switch (kind) {
6354 case CXTUResourceUsage_AST:
6355 str = "ASTContext: expressions, declarations, and types";
6356 break;
6357 case CXTUResourceUsage_Identifiers:
6358 str = "ASTContext: identifiers";
6359 break;
6360 case CXTUResourceUsage_Selectors:
6361 str = "ASTContext: selectors";
6362 break;
6363 case CXTUResourceUsage_GlobalCompletionResults:
6364 str = "Code completion: cached global results";
6365 break;
6366 case CXTUResourceUsage_SourceManagerContentCache:
6367 str = "SourceManager: content cache allocator";
6368 break;
6369 case CXTUResourceUsage_AST_SideTables:
6370 str = "ASTContext: side tables";
6371 break;
6372 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6373 str = "SourceManager: malloc'ed memory buffers";
6374 break;
6375 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6376 str = "SourceManager: mmap'ed memory buffers";
6377 break;
6378 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6379 str = "ExternalASTSource: malloc'ed memory buffers";
6380 break;
6381 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6382 str = "ExternalASTSource: mmap'ed memory buffers";
6383 break;
6384 case CXTUResourceUsage_Preprocessor:
6385 str = "Preprocessor: malloc'ed memory";
6386 break;
6387 case CXTUResourceUsage_PreprocessingRecord:
6388 str = "Preprocessor: PreprocessingRecord";
6389 break;
6390 case CXTUResourceUsage_SourceManager_DataStructures:
6391 str = "SourceManager: data structures and tables";
6392 break;
6393 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6394 str = "Preprocessor: header search tables";
6395 break;
6396 }
6397 return str;
6398}
6399
6400CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6401 if (!TU) {
6402 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6403 return usage;
6404 }
6405
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006406 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6408 ASTContext &astContext = astUnit->getASTContext();
6409
6410 // How much memory is used by AST nodes and types?
6411 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6412 (unsigned long) astContext.getASTAllocatedMemory());
6413
6414 // How much memory is used by identifiers?
6415 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6416 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6417
6418 // How much memory is used for selectors?
6419 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6420 (unsigned long) astContext.Selectors.getTotalMemory());
6421
6422 // How much memory is used by ASTContext's side tables?
6423 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6424 (unsigned long) astContext.getSideTableAllocatedMemory());
6425
6426 // How much memory is used for caching global code completion results?
6427 unsigned long completionBytes = 0;
6428 if (GlobalCodeCompletionAllocator *completionAllocator =
6429 astUnit->getCachedCompletionAllocator().getPtr()) {
6430 completionBytes = completionAllocator->getTotalMemory();
6431 }
6432 createCXTUResourceUsageEntry(*entries,
6433 CXTUResourceUsage_GlobalCompletionResults,
6434 completionBytes);
6435
6436 // How much memory is being used by SourceManager's content cache?
6437 createCXTUResourceUsageEntry(*entries,
6438 CXTUResourceUsage_SourceManagerContentCache,
6439 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6440
6441 // How much memory is being used by the MemoryBuffer's in SourceManager?
6442 const SourceManager::MemoryBufferSizes &srcBufs =
6443 astUnit->getSourceManager().getMemoryBufferSizes();
6444
6445 createCXTUResourceUsageEntry(*entries,
6446 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6447 (unsigned long) srcBufs.malloc_bytes);
6448 createCXTUResourceUsageEntry(*entries,
6449 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6450 (unsigned long) srcBufs.mmap_bytes);
6451 createCXTUResourceUsageEntry(*entries,
6452 CXTUResourceUsage_SourceManager_DataStructures,
6453 (unsigned long) astContext.getSourceManager()
6454 .getDataStructureSizes());
6455
6456 // How much memory is being used by the ExternalASTSource?
6457 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6458 const ExternalASTSource::MemoryBufferSizes &sizes =
6459 esrc->getMemoryBufferSizes();
6460
6461 createCXTUResourceUsageEntry(*entries,
6462 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6463 (unsigned long) sizes.malloc_bytes);
6464 createCXTUResourceUsageEntry(*entries,
6465 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6466 (unsigned long) sizes.mmap_bytes);
6467 }
6468
6469 // How much memory is being used by the Preprocessor?
6470 Preprocessor &pp = astUnit->getPreprocessor();
6471 createCXTUResourceUsageEntry(*entries,
6472 CXTUResourceUsage_Preprocessor,
6473 pp.getTotalMemory());
6474
6475 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6476 createCXTUResourceUsageEntry(*entries,
6477 CXTUResourceUsage_PreprocessingRecord,
6478 pRec->getTotalMemory());
6479 }
6480
6481 createCXTUResourceUsageEntry(*entries,
6482 CXTUResourceUsage_Preprocessor_HeaderSearch,
6483 pp.getHeaderSearchInfo().getTotalMemory());
6484
6485 CXTUResourceUsage usage = { (void*) entries.get(),
6486 (unsigned) entries->size(),
6487 entries->size() ? &(*entries)[0] : 0 };
6488 entries.take();
6489 return usage;
6490}
6491
6492void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6493 if (usage.data)
6494 delete (MemUsageEntries*) usage.data;
6495}
6496
6497} // end extern "C"
6498
6499void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6500 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6501 for (unsigned I = 0; I != Usage.numEntries; ++I)
6502 fprintf(stderr, " %s: %lu\n",
6503 clang_getTUResourceUsageName(Usage.entries[I].kind),
6504 Usage.entries[I].amount);
6505
6506 clang_disposeCXTUResourceUsage(Usage);
6507}
6508
6509//===----------------------------------------------------------------------===//
6510// Misc. utility functions.
6511//===----------------------------------------------------------------------===//
6512
6513/// Default to using an 8 MB stack size on "safety" threads.
6514static unsigned SafetyStackThreadSize = 8 << 20;
6515
6516namespace clang {
6517
6518bool RunSafely(llvm::CrashRecoveryContext &CRC,
6519 void (*Fn)(void*), void *UserData,
6520 unsigned Size) {
6521 if (!Size)
6522 Size = GetSafetyThreadStackSize();
6523 if (Size)
6524 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6525 return CRC.RunSafely(Fn, UserData);
6526}
6527
6528unsigned GetSafetyThreadStackSize() {
6529 return SafetyStackThreadSize;
6530}
6531
6532void SetSafetyThreadStackSize(unsigned Value) {
6533 SafetyStackThreadSize = Value;
6534}
6535
6536}
6537
6538void clang::setThreadBackgroundPriority() {
6539 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6540 return;
6541
6542 // FIXME: Move to llvm/Support and make it cross-platform.
6543#ifdef __APPLE__
6544 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6545#endif
6546}
6547
6548void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6549 if (!Unit)
6550 return;
6551
6552 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6553 DEnd = Unit->stored_diag_end();
6554 D != DEnd; ++D) {
6555 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6556 CXString Msg = clang_formatDiagnostic(&Diag,
6557 clang_defaultDiagnosticDisplayOptions());
6558 fprintf(stderr, "%s\n", clang_getCString(Msg));
6559 clang_disposeString(Msg);
6560 }
6561#ifdef LLVM_ON_WIN32
6562 // On Windows, force a flush, since there may be multiple copies of
6563 // stderr and stdout in the file system, all with different buffers
6564 // but writing to the same device.
6565 fflush(stderr);
6566#endif
6567}
6568
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006569MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6570 SourceLocation MacroDefLoc,
6571 CXTranslationUnit TU){
6572 if (MacroDefLoc.isInvalid() || !TU)
6573 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006574 if (!II.hadMacroDefinition())
6575 return 0;
6576
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006577 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006578 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006579 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006580 if (MD) {
6581 for (MacroDirective::DefInfo
6582 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6583 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6584 return Def.getMacroInfo();
6585 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006586 }
6587
6588 return 0;
6589}
6590
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006591const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6592 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006593 if (!MacroDef || !TU)
6594 return 0;
6595 const IdentifierInfo *II = MacroDef->getName();
6596 if (!II)
6597 return 0;
6598
6599 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6600}
6601
6602MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6603 const Token &Tok,
6604 CXTranslationUnit TU) {
6605 if (!MI || !TU)
6606 return 0;
6607 if (Tok.isNot(tok::raw_identifier))
6608 return 0;
6609
6610 if (MI->getNumTokens() == 0)
6611 return 0;
6612 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6613 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006614 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006615
6616 // Check that the token is inside the definition and not its argument list.
6617 SourceManager &SM = Unit->getSourceManager();
6618 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6619 return 0;
6620 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6621 return 0;
6622
6623 Preprocessor &PP = Unit->getPreprocessor();
6624 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6625 if (!PPRec)
6626 return 0;
6627
6628 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6629 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6630 if (!II.hadMacroDefinition())
6631 return 0;
6632
6633 // Check that the identifier is not one of the macro arguments.
6634 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6635 return 0;
6636
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006637 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6638 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006639 return 0;
6640
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006641 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006642}
6643
6644MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6645 SourceLocation Loc,
6646 CXTranslationUnit TU) {
6647 if (Loc.isInvalid() || !MI || !TU)
6648 return 0;
6649
6650 if (MI->getNumTokens() == 0)
6651 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006652 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006653 Preprocessor &PP = Unit->getPreprocessor();
6654 if (!PP.getPreprocessingRecord())
6655 return 0;
6656 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6657 Token Tok;
6658 if (PP.getRawToken(Loc, Tok))
6659 return 0;
6660
6661 return checkForMacroInMacroDefinition(MI, Tok, TU);
6662}
6663
Guy Benyei11169dd2012-12-18 14:30:41 +00006664extern "C" {
6665
6666CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006667 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006668}
6669
6670} // end: extern "C"
6671
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006672Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6673 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006674 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006675 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006676 if (Unit->isMainFileAST())
6677 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006678 return *this;
6679 }
6680 }
6681
6682 LogOS << "<NULL TU>";
6683 return *this;
6684}
6685
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006686Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6687 *this << FE->getName();
6688 return *this;
6689}
6690
6691Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6692 CXString cursorName = clang_getCursorDisplayName(cursor);
6693 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6694 clang_disposeString(cursorName);
6695 return *this;
6696}
6697
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006698Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6699 CXFile File;
6700 unsigned Line, Column;
6701 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6702 CXString FileName = clang_getFileName(File);
6703 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6704 clang_disposeString(FileName);
6705 return *this;
6706}
6707
6708Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6709 CXSourceLocation BLoc = clang_getRangeStart(range);
6710 CXSourceLocation ELoc = clang_getRangeEnd(range);
6711
6712 CXFile BFile;
6713 unsigned BLine, BColumn;
6714 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6715
6716 CXFile EFile;
6717 unsigned ELine, EColumn;
6718 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6719
6720 CXString BFileName = clang_getFileName(BFile);
6721 if (BFile == EFile) {
6722 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6723 BLine, BColumn, ELine, EColumn);
6724 } else {
6725 CXString EFileName = clang_getFileName(EFile);
6726 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6727 BLine, BColumn)
6728 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6729 ELine, EColumn);
6730 clang_disposeString(EFileName);
6731 }
6732 clang_disposeString(BFileName);
6733 return *this;
6734}
6735
6736Logger &cxindex::Logger::operator<<(CXString Str) {
6737 *this << clang_getCString(Str);
6738 return *this;
6739}
6740
6741Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6742 LogOS << Fmt;
6743 return *this;
6744}
6745
6746cxindex::Logger::~Logger() {
6747 LogOS.flush();
6748
6749 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6750
6751 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6752
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006753 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006754 OS << "[libclang:" << Name << ':';
6755
6756 // FIXME: Portability.
6757#if HAVE_PTHREAD_H && __APPLE__
6758 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6759 OS << tid << ':';
6760#endif
6761
6762 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6763 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6764 OS << Msg.str() << '\n';
6765
6766 if (Trace) {
6767 llvm::sys::PrintStackTrace(stderr);
6768 OS << "--------------------------------------------------\n";
6769 }
6770}