blob: 255b74b472e6e7dcbc014467dbe36cb5752880f7 [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
Guy Benyei11169dd2012-12-18 14:30:41 +00001545bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1546 TemplateSpecializationTypeLoc TL) {
1547 // Visit the template name.
1548 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1549 TL.getTemplateNameLoc()))
1550 return true;
1551
1552 // Visit the template arguments.
1553 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1554 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1555 return true;
1556
1557 return false;
1558}
1559
1560bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1561 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1562}
1563
1564bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1565 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1566 return Visit(TSInfo->getTypeLoc());
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1579 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1580 return true;
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1586 DependentTemplateSpecializationTypeLoc TL) {
1587 // Visit the nested-name-specifier, if there is one.
1588 if (TL.getQualifierLoc() &&
1589 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1590 return true;
1591
1592 // Visit the template arguments.
1593 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1594 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1601 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1602 return true;
1603
1604 return Visit(TL.getNamedTypeLoc());
1605}
1606
1607bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1608 return Visit(TL.getPatternLoc());
1609}
1610
1611bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1612 if (Expr *E = TL.getUnderlyingExpr())
1613 return Visit(MakeCXCursor(E, StmtParent, TU));
1614
1615 return false;
1616}
1617
1618bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1619 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1620}
1621
1622bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1623 return Visit(TL.getValueLoc());
1624}
1625
1626#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1627bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1628 return Visit##PARENT##Loc(TL); \
1629}
1630
1631DEFAULT_TYPELOC_IMPL(Complex, Type)
1632DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1633DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1634DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1635DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1636DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1637DEFAULT_TYPELOC_IMPL(Vector, Type)
1638DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1639DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1640DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1641DEFAULT_TYPELOC_IMPL(Record, TagType)
1642DEFAULT_TYPELOC_IMPL(Enum, TagType)
1643DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1644DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1645DEFAULT_TYPELOC_IMPL(Auto, Type)
1646
1647bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1648 // Visit the nested-name-specifier, if present.
1649 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1650 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1651 return true;
1652
1653 if (D->isCompleteDefinition()) {
1654 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1655 E = D->bases_end(); I != E; ++I) {
1656 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1657 return true;
1658 }
1659 }
1660
1661 return VisitTagDecl(D);
1662}
1663
1664bool CursorVisitor::VisitAttributes(Decl *D) {
1665 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1666 i != e; ++i)
1667 if (Visit(MakeCXCursor(*i, D, TU)))
1668 return true;
1669
1670 return false;
1671}
1672
1673//===----------------------------------------------------------------------===//
1674// Data-recursive visitor methods.
1675//===----------------------------------------------------------------------===//
1676
1677namespace {
1678#define DEF_JOB(NAME, DATA, KIND)\
1679class NAME : public VisitorJob {\
1680public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001681 NAME(const DATA *d, CXCursor parent) : \
1682 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001683 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001684 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001685};
1686
1687DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1688DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1689DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1690DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1691DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1692 ExplicitTemplateArgsVisitKind)
1693DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1694DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1695DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1696#undef DEF_JOB
1697
1698class DeclVisit : public VisitorJob {
1699public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001700 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001701 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001702 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001703 static bool classof(const VisitorJob *VJ) {
1704 return VJ->getKind() == DeclVisitKind;
1705 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001706 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 bool isFirst() const { return data[1] ? true : false; }
1708};
1709class TypeLocVisit : public VisitorJob {
1710public:
1711 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1712 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1713 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1714
1715 static bool classof(const VisitorJob *VJ) {
1716 return VJ->getKind() == TypeLocVisitKind;
1717 }
1718
1719 TypeLoc get() const {
1720 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 }
1723};
1724
1725class LabelRefVisit : public VisitorJob {
1726public:
1727 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1728 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1729 labelLoc.getPtrEncoding()) {}
1730
1731 static bool classof(const VisitorJob *VJ) {
1732 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1733 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 const LabelDecl *get() const {
1735 return static_cast<const LabelDecl *>(data[0]);
1736 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001737 SourceLocation getLoc() const {
1738 return SourceLocation::getFromPtrEncoding(data[1]); }
1739};
1740
1741class NestedNameSpecifierLocVisit : public VisitorJob {
1742public:
1743 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1744 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1745 Qualifier.getNestedNameSpecifier(),
1746 Qualifier.getOpaqueData()) { }
1747
1748 static bool classof(const VisitorJob *VJ) {
1749 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1750 }
1751
1752 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001753 return NestedNameSpecifierLoc(
1754 const_cast<NestedNameSpecifier *>(
1755 static_cast<const NestedNameSpecifier *>(data[0])),
1756 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 }
1758};
1759
1760class DeclarationNameInfoVisit : public VisitorJob {
1761public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001763 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001764 static bool classof(const VisitorJob *VJ) {
1765 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1766 }
1767 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001768 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 switch (S->getStmtClass()) {
1770 default:
1771 llvm_unreachable("Unhandled Stmt");
1772 case clang::Stmt::MSDependentExistsStmtClass:
1773 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1774 case Stmt::CXXDependentScopeMemberExprClass:
1775 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1776 case Stmt::DependentScopeDeclRefExprClass:
1777 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1778 }
1779 }
1780};
1781class MemberRefVisit : public VisitorJob {
1782public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001784 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1785 L.getPtrEncoding()) {}
1786 static bool classof(const VisitorJob *VJ) {
1787 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1788 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001789 const FieldDecl *get() const {
1790 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001791 }
1792 SourceLocation getLoc() const {
1793 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1794 }
1795};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001796class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001797 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001798 VisitorWorkList &WL;
1799 CXCursor Parent;
1800public:
1801 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1802 : WL(wl), Parent(parent) {}
1803
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1805 void VisitBlockExpr(const BlockExpr *B);
1806 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1807 void VisitCompoundStmt(const CompoundStmt *S);
1808 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1809 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1810 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1811 void VisitCXXNewExpr(const CXXNewExpr *E);
1812 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1813 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1814 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1815 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1816 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1817 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1818 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1819 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1820 void VisitDeclRefExpr(const DeclRefExpr *D);
1821 void VisitDeclStmt(const DeclStmt *S);
1822 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1823 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1824 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1825 void VisitForStmt(const ForStmt *FS);
1826 void VisitGotoStmt(const GotoStmt *GS);
1827 void VisitIfStmt(const IfStmt *If);
1828 void VisitInitListExpr(const InitListExpr *IE);
1829 void VisitMemberExpr(const MemberExpr *M);
1830 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1831 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1832 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1833 void VisitOverloadExpr(const OverloadExpr *E);
1834 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1835 void VisitStmt(const Stmt *S);
1836 void VisitSwitchStmt(const SwitchStmt *S);
1837 void VisitWhileStmt(const WhileStmt *W);
1838 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1839 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1840 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1841 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1842 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1843 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1844 void VisitVAArgExpr(const VAArgExpr *E);
1845 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1846 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1847 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1848 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001849 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1850 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851
Guy Benyei11169dd2012-12-18 14:30:41 +00001852private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001854 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1855 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1857 void AddStmt(const Stmt *S);
1858 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001861 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862};
1863} // end anonyous namespace
1864
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 // 'S' should always be non-null, since it comes from the
1867 // statement we are visiting.
1868 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1869}
1870
1871void
1872EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1873 if (Qualifier)
1874 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1875}
1876
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 if (S)
1879 WL.push_back(StmtVisit(S, Parent));
1880}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (D)
1883 WL.push_back(DeclVisit(D, Parent, isFirst));
1884}
1885void EnqueueVisitor::
1886 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1887 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001889}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 if (D)
1892 WL.push_back(MemberRefVisit(D, L, Parent));
1893}
1894void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1895 if (TI)
1896 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1897 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 AddStmt(*Child);
1902 }
1903 if (size == WL.size())
1904 return;
1905 // Now reverse the entries we just added. This will match the DFS
1906 // ordering performed by the worklist.
1907 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1908 std::reverse(I, E);
1909}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001910namespace {
1911class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1912 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001913 /// \brief Process clauses with list of variables.
1914 template <typename T>
1915 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001916public:
1917 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1918#define OPENMP_CLAUSE(Name, Class) \
1919 void Visit##Class(const Class *C);
1920#include "clang/Basic/OpenMPKinds.def"
1921};
1922
1923void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001924
1925template<typename T>
1926void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1927 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1928 E = Node->varlist_end();
1929 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001930 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001931}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932
1933void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001934 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001936void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1937 const OMPFirstprivateClause *C) {
1938 VisitOMPClauseList(C);
1939}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001940void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001941 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001942}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001943}
Alexey Bataev756c1962013-09-24 03:17:45 +00001944
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1946 unsigned size = WL.size();
1947 OMPClauseEnqueue Visitor(this);
1948 Visitor.Visit(S);
1949 if (size == WL.size())
1950 return;
1951 // Now reverse the entries we just added. This will match the DFS
1952 // ordering performed by the worklist.
1953 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1954 std::reverse(I, E);
1955}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001956void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001957 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1958}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001959void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 AddDecl(B->getBlockDecl());
1961}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 EnqueueChildren(E);
1964 AddTypeLoc(E->getTypeSourceInfo());
1965}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001966void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1967 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001968 E = S->body_rend(); I != E; ++I) {
1969 AddStmt(*I);
1970 }
1971}
1972void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 AddStmt(S->getSubStmt());
1975 AddDeclarationNameInfo(S);
1976 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1977 AddNestedNameSpecifierLoc(QualifierLoc);
1978}
1979
1980void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1983 AddDeclarationNameInfo(E);
1984 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1985 AddNestedNameSpecifierLoc(QualifierLoc);
1986 if (!E->isImplicitAccess())
1987 AddStmt(E->getBase());
1988}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 // Enqueue the initializer , if any.
1991 AddStmt(E->getInitializer());
1992 // Enqueue the array size, if any.
1993 AddStmt(E->getArraySize());
1994 // Enqueue the allocated type.
1995 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1996 // Enqueue the placement arguments.
1997 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1998 AddStmt(E->getPlacementArg(I-1));
1999}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002001 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2002 AddStmt(CE->getArg(I-1));
2003 AddStmt(CE->getCallee());
2004 AddStmt(CE->getArg(0));
2005}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002006void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2007 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 // Visit the name of the type being destroyed.
2009 AddTypeLoc(E->getDestroyedTypeInfo());
2010 // Visit the scope type that looks disturbingly like the nested-name-specifier
2011 // but isn't.
2012 AddTypeLoc(E->getScopeTypeInfo());
2013 // Visit the nested-name-specifier.
2014 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2015 AddNestedNameSpecifierLoc(QualifierLoc);
2016 // Visit base expression.
2017 AddStmt(E->getBase());
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2020 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 AddTypeLoc(E->getTypeSourceInfo());
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2024 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 EnqueueChildren(E);
2026 AddTypeLoc(E->getTypeSourceInfo());
2027}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 EnqueueChildren(E);
2030 if (E->isTypeOperand())
2031 AddTypeLoc(E->getTypeOperandSourceInfo());
2032}
2033
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2035 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 EnqueueChildren(E);
2037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 EnqueueChildren(E);
2041 if (E->isTypeOperand())
2042 AddTypeLoc(E->getTypeOperandSourceInfo());
2043}
2044
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 EnqueueChildren(S);
2047 AddDecl(S->getExceptionDecl());
2048}
2049
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 if (DR->hasExplicitTemplateArgs()) {
2052 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2053 }
2054 WL.push_back(DeclRefExprParts(DR, Parent));
2055}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2057 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2059 AddDeclarationNameInfo(E);
2060 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 unsigned size = WL.size();
2064 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 D != DEnd; ++D) {
2067 AddDecl(*D, isFirst);
2068 isFirst = false;
2069 }
2070 if (size == WL.size())
2071 return;
2072 // Now reverse the entries we just added. This will match the DFS
2073 // ordering performed by the worklist.
2074 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2075 std::reverse(I, E);
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 D = E->designators_rbegin(), DEnd = E->designators_rend();
2081 D != DEnd; ++D) {
2082 if (D->isFieldDesignator()) {
2083 if (FieldDecl *Field = D->getField())
2084 AddMemberRef(Field, D->getFieldLoc());
2085 continue;
2086 }
2087 if (D->isArrayDesignator()) {
2088 AddStmt(E->getArrayIndex(*D));
2089 continue;
2090 }
2091 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2092 AddStmt(E->getArrayRangeEnd(*D));
2093 AddStmt(E->getArrayRangeStart(*D));
2094 }
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 AddTypeLoc(E->getTypeInfoAsWritten());
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 AddStmt(FS->getBody());
2102 AddStmt(FS->getInc());
2103 AddStmt(FS->getCond());
2104 AddDecl(FS->getConditionVariable());
2105 AddStmt(FS->getInit());
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddStmt(If->getElse());
2112 AddStmt(If->getThen());
2113 AddStmt(If->getCond());
2114 AddDecl(If->getConditionVariable());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 // We care about the syntactic form of the initializer list, only.
2118 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2119 IE = Syntactic;
2120 EnqueueChildren(IE);
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 WL.push_back(MemberExprParts(M, Parent));
2124
2125 // If the base of the member access expression is an implicit 'this', don't
2126 // visit it.
2127 // FIXME: If we ever want to show these implicit accesses, this will be
2128 // unfortunate. However, clang_getCursor() relies on this behavior.
2129 if (!M->isImplicitAccess())
2130 AddStmt(M->getBase());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 AddTypeLoc(E->getEncodedTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(M);
2137 AddTypeLoc(M->getClassReceiverTypeInfo());
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 // Visit the components of the offsetof expression.
2141 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2142 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2143 const OffsetOfNode &Node = E->getComponent(I-1);
2144 switch (Node.getKind()) {
2145 case OffsetOfNode::Array:
2146 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2147 break;
2148 case OffsetOfNode::Field:
2149 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2150 break;
2151 case OffsetOfNode::Identifier:
2152 case OffsetOfNode::Base:
2153 continue;
2154 }
2155 }
2156 // Visit the type into which we're computing the offset.
2157 AddTypeLoc(E->getTypeSourceInfo());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2161 WL.push_back(OverloadExprParts(E, Parent));
2162}
2163void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 EnqueueChildren(E);
2166 if (E->isArgumentType())
2167 AddTypeLoc(E->getArgumentTypeInfo());
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 EnqueueChildren(S);
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 AddStmt(S->getBody());
2174 AddStmt(S->getCond());
2175 AddDecl(S->getConditionVariable());
2176}
2177
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddStmt(W->getBody());
2180 AddStmt(W->getCond());
2181 AddDecl(W->getConditionVariable());
2182}
2183
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 AddTypeLoc(E->getQueriedTypeSourceInfo());
2186}
2187
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddTypeLoc(E->getRhsTypeSourceInfo());
2190 AddTypeLoc(E->getLhsTypeSourceInfo());
2191}
2192
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 for (unsigned I = E->getNumArgs(); I > 0; --I)
2195 AddTypeLoc(E->getArg(I-1));
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddTypeLoc(E->getQueriedTypeSourceInfo());
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(E);
2204}
2205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 VisitOverloadExpr(U);
2208 if (!U->isImplicitAccess())
2209 AddStmt(U->getBase());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddStmt(E->getSubExpr());
2213 AddTypeLoc(E->getWrittenTypeInfo());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 WL.push_back(SizeOfPackExprParts(E, Parent));
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // If the opaque value has a source expression, just transparently
2220 // visit that. This is useful for (e.g.) pseudo-object expressions.
2221 if (Expr *SourceExpr = E->getSourceExpr())
2222 return Visit(SourceExpr);
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddStmt(E->getBody());
2226 WL.push_back(LambdaExprParts(E, Parent));
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // Treat the expression like its syntactic form.
2230 Visit(E->getSyntacticForm());
2231}
2232
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002233void EnqueueVisitor::VisitOMPExecutableDirective(
2234 const OMPExecutableDirective *D) {
2235 EnqueueChildren(D);
2236 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2237 E = D->clauses().end();
2238 I != E; ++I)
2239 EnqueueChildren(*I);
2240}
2241
2242void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2243 VisitOMPExecutableDirective(D);
2244}
2245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2248}
2249
2250bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2251 if (RegionOfInterest.isValid()) {
2252 SourceRange Range = getRawCursorExtent(C);
2253 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2254 return false;
2255 }
2256 return true;
2257}
2258
2259bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2260 while (!WL.empty()) {
2261 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002262 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002263
2264 // Set the Parent field, then back to its old value once we're done.
2265 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2266
2267 switch (LI.getKind()) {
2268 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 if (!D)
2271 continue;
2272
2273 // For now, perform default visitation for Decls.
2274 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2275 cast<DeclVisit>(&LI)->isFirst())))
2276 return true;
2277
2278 continue;
2279 }
2280 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2281 const ASTTemplateArgumentListInfo *ArgList =
2282 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2283 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2284 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2285 Arg != ArgEnd; ++Arg) {
2286 if (VisitTemplateArgumentLoc(*Arg))
2287 return true;
2288 }
2289 continue;
2290 }
2291 case VisitorJob::TypeLocVisitKind: {
2292 // Perform default visitation for TypeLocs.
2293 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2294 return true;
2295 continue;
2296 }
2297 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 if (LabelStmt *stmt = LS->getStmt()) {
2300 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2301 TU))) {
2302 return true;
2303 }
2304 }
2305 continue;
2306 }
2307
2308 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2309 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2310 if (VisitNestedNameSpecifierLoc(V->get()))
2311 return true;
2312 continue;
2313 }
2314
2315 case VisitorJob::DeclarationNameInfoVisitKind: {
2316 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2317 ->get()))
2318 return true;
2319 continue;
2320 }
2321 case VisitorJob::MemberRefVisitKind: {
2322 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2323 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2324 return true;
2325 continue;
2326 }
2327 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 if (!S)
2330 continue;
2331
2332 // Update the current cursor.
2333 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2334 if (!IsInRegionOfInterest(Cursor))
2335 continue;
2336 switch (Visitor(Cursor, Parent, ClientData)) {
2337 case CXChildVisit_Break: return true;
2338 case CXChildVisit_Continue: break;
2339 case CXChildVisit_Recurse:
2340 if (PostChildrenVisitor)
2341 WL.push_back(PostChildrenVisit(0, Cursor));
2342 EnqueueWorkList(WL, S);
2343 break;
2344 }
2345 continue;
2346 }
2347 case VisitorJob::MemberExprPartsKind: {
2348 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002349 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002350
2351 // Visit the nested-name-specifier
2352 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2353 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2354 return true;
2355
2356 // Visit the declaration name.
2357 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2358 return true;
2359
2360 // Visit the explicitly-specified template arguments, if any.
2361 if (M->hasExplicitTemplateArgs()) {
2362 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2363 *ArgEnd = Arg + M->getNumTemplateArgs();
2364 Arg != ArgEnd; ++Arg) {
2365 if (VisitTemplateArgumentLoc(*Arg))
2366 return true;
2367 }
2368 }
2369 continue;
2370 }
2371 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 // Visit nested-name-specifier, if present.
2374 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2375 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2376 return true;
2377 // Visit declaration name.
2378 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2379 return true;
2380 continue;
2381 }
2382 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit the nested-name-specifier.
2385 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit the declaration name.
2389 if (VisitDeclarationNameInfo(O->getNameInfo()))
2390 return true;
2391 // Visit the overloaded declaration reference.
2392 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2393 return true;
2394 continue;
2395 }
2396 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 NamedDecl *Pack = E->getPack();
2399 if (isa<TemplateTypeParmDecl>(Pack)) {
2400 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2401 E->getPackLoc(), TU)))
2402 return true;
2403
2404 continue;
2405 }
2406
2407 if (isa<TemplateTemplateParmDecl>(Pack)) {
2408 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2409 E->getPackLoc(), TU)))
2410 return true;
2411
2412 continue;
2413 }
2414
2415 // Non-type template parameter packs and function parameter packs are
2416 // treated like DeclRefExpr cursors.
2417 continue;
2418 }
2419
2420 case VisitorJob::LambdaExprPartsKind: {
2421 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2424 CEnd = E->explicit_capture_end();
2425 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002426 // FIXME: Lambda init-captures.
2427 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002429
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2431 C->getLocation(),
2432 TU)))
2433 return true;
2434 }
2435
2436 // Visit parameters and return type, if present.
2437 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2438 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2439 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2440 // Visit the whole type.
2441 if (Visit(TL))
2442 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002443 } else if (FunctionProtoTypeLoc Proto =
2444 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 if (E->hasExplicitParameters()) {
2446 // Visit parameters.
2447 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2448 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2449 return true;
2450 } else {
2451 // Visit result type.
2452 if (Visit(Proto.getResultLoc()))
2453 return true;
2454 }
2455 }
2456 }
2457 break;
2458 }
2459
2460 case VisitorJob::PostChildrenVisitKind:
2461 if (PostChildrenVisitor(Parent, ClientData))
2462 return true;
2463 break;
2464 }
2465 }
2466 return false;
2467}
2468
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 VisitorWorkList *WL = 0;
2471 if (!WorkListFreeList.empty()) {
2472 WL = WorkListFreeList.back();
2473 WL->clear();
2474 WorkListFreeList.pop_back();
2475 }
2476 else {
2477 WL = new VisitorWorkList();
2478 WorkListCache.push_back(WL);
2479 }
2480 EnqueueWorkList(*WL, S);
2481 bool result = RunVisitorWorkList(*WL);
2482 WorkListFreeList.push_back(WL);
2483 return result;
2484}
2485
2486namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002487typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002488RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2489 const DeclarationNameInfo &NI,
2490 const SourceRange &QLoc,
2491 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2492 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2493 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2494 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2495
2496 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2497
2498 RefNamePieces Pieces;
2499
2500 if (WantQualifier && QLoc.isValid())
2501 Pieces.push_back(QLoc);
2502
2503 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2504 Pieces.push_back(NI.getLoc());
2505
2506 if (WantTemplateArgs && TemplateArgs)
2507 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2508 TemplateArgs->RAngleLoc));
2509
2510 if (Kind == DeclarationName::CXXOperatorName) {
2511 Pieces.push_back(SourceLocation::getFromRawEncoding(
2512 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2513 Pieces.push_back(SourceLocation::getFromRawEncoding(
2514 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2515 }
2516
2517 if (WantSinglePiece) {
2518 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2519 Pieces.clear();
2520 Pieces.push_back(R);
2521 }
2522
2523 return Pieces;
2524}
2525}
2526
2527//===----------------------------------------------------------------------===//
2528// Misc. API hooks.
2529//===----------------------------------------------------------------------===//
2530
2531static llvm::sys::Mutex EnableMultithreadingMutex;
2532static bool EnabledMultithreading;
2533
Chad Rosier05c71aa2013-03-27 18:28:23 +00002534static void fatal_error_handler(void *user_data, const std::string& reason,
2535 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 // Write the result out to stderr avoiding errs() because raw_ostreams can
2537 // call report_fatal_error.
2538 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2539 ::abort();
2540}
2541
2542extern "C" {
2543CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2544 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 // We use crash recovery to make some of our APIs more reliable, implicitly
2546 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002547 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2548 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002549
2550 // Enable support for multithreading in LLVM.
2551 {
2552 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2553 if (!EnabledMultithreading) {
2554 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2555 llvm::llvm_start_multithreaded();
2556 EnabledMultithreading = true;
2557 }
2558 }
2559
2560 CIndexer *CIdxr = new CIndexer();
2561 if (excludeDeclarationsFromPCH)
2562 CIdxr->setOnlyLocalDecls();
2563 if (displayDiagnostics)
2564 CIdxr->setDisplayDiagnostics();
2565
2566 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2567 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2568 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2569 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2570 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2571 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2572
2573 return CIdxr;
2574}
2575
2576void clang_disposeIndex(CXIndex CIdx) {
2577 if (CIdx)
2578 delete static_cast<CIndexer *>(CIdx);
2579}
2580
2581void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2582 if (CIdx)
2583 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2584}
2585
2586unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2587 if (CIdx)
2588 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2589 return 0;
2590}
2591
2592void clang_toggleCrashRecovery(unsigned isEnabled) {
2593 if (isEnabled)
2594 llvm::CrashRecoveryContext::Enable();
2595 else
2596 llvm::CrashRecoveryContext::Disable();
2597}
2598
2599CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2600 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002601 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002602 return 0;
2603
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002604 LOG_FUNC_SECTION {
2605 *Log << ast_filename;
2606 }
2607
Guy Benyei11169dd2012-12-18 14:30:41 +00002608 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2609 FileSystemOptions FileSystemOpts;
2610
2611 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2612 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2613 CXXIdx->getOnlyLocalDecls(),
2614 0, 0,
2615 /*CaptureDiagnostics=*/true,
2616 /*AllowPCHWithCompilerErrors=*/true,
2617 /*UserFilesAreVolatile=*/true);
2618 return MakeCXTranslationUnit(CXXIdx, TU);
2619}
2620
2621unsigned clang_defaultEditingTranslationUnitOptions() {
2622 return CXTranslationUnit_PrecompiledPreamble |
2623 CXTranslationUnit_CacheCompletionResults;
2624}
2625
2626CXTranslationUnit
2627clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2628 const char *source_filename,
2629 int num_command_line_args,
2630 const char * const *command_line_args,
2631 unsigned num_unsaved_files,
2632 struct CXUnsavedFile *unsaved_files) {
2633 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2634 return clang_parseTranslationUnit(CIdx, source_filename,
2635 command_line_args, num_command_line_args,
2636 unsaved_files, num_unsaved_files,
2637 Options);
2638}
2639
2640struct ParseTranslationUnitInfo {
2641 CXIndex CIdx;
2642 const char *source_filename;
2643 const char *const *command_line_args;
2644 int num_command_line_args;
2645 struct CXUnsavedFile *unsaved_files;
2646 unsigned num_unsaved_files;
2647 unsigned options;
2648 CXTranslationUnit result;
2649};
2650static void clang_parseTranslationUnit_Impl(void *UserData) {
2651 ParseTranslationUnitInfo *PTUI =
2652 static_cast<ParseTranslationUnitInfo*>(UserData);
2653 CXIndex CIdx = PTUI->CIdx;
2654 const char *source_filename = PTUI->source_filename;
2655 const char * const *command_line_args = PTUI->command_line_args;
2656 int num_command_line_args = PTUI->num_command_line_args;
2657 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2658 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2659 unsigned options = PTUI->options;
2660 PTUI->result = 0;
2661
2662 if (!CIdx)
2663 return;
2664
2665 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2666
2667 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2668 setThreadBackgroundPriority();
2669
2670 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2671 // FIXME: Add a flag for modules.
2672 TranslationUnitKind TUKind
2673 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2674 bool CacheCodeCompetionResults
2675 = options & CXTranslationUnit_CacheCompletionResults;
2676 bool IncludeBriefCommentsInCodeCompletion
2677 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2678 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2679 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2680
2681 // Configure the diagnostics.
2682 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002683 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002684
2685 // Recover resources if we crash before exiting this function.
2686 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2687 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2688 DiagCleanup(Diags.getPtr());
2689
2690 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2691 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2692
2693 // Recover resources if we crash before exiting this function.
2694 llvm::CrashRecoveryContextCleanupRegistrar<
2695 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2696
2697 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2698 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2699 const llvm::MemoryBuffer *Buffer
2700 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2701 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2702 Buffer));
2703 }
2704
2705 OwningPtr<std::vector<const char *> >
2706 Args(new std::vector<const char*>());
2707
2708 // Recover resources if we crash before exiting this method.
2709 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2710 ArgsCleanup(Args.get());
2711
2712 // Since the Clang C library is primarily used by batch tools dealing with
2713 // (often very broken) source code, where spell-checking can have a
2714 // significant negative impact on performance (particularly when
2715 // precompiled headers are involved), we disable it by default.
2716 // Only do this if we haven't found a spell-checking-related argument.
2717 bool FoundSpellCheckingArgument = false;
2718 for (int I = 0; I != num_command_line_args; ++I) {
2719 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2720 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2721 FoundSpellCheckingArgument = true;
2722 break;
2723 }
2724 }
2725 if (!FoundSpellCheckingArgument)
2726 Args->push_back("-fno-spell-checking");
2727
2728 Args->insert(Args->end(), command_line_args,
2729 command_line_args + num_command_line_args);
2730
2731 // The 'source_filename' argument is optional. If the caller does not
2732 // specify it then it is assumed that the source file is specified
2733 // in the actual argument list.
2734 // Put the source file after command_line_args otherwise if '-x' flag is
2735 // present it will be unused.
2736 if (source_filename)
2737 Args->push_back(source_filename);
2738
2739 // Do we need the detailed preprocessing record?
2740 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2741 Args->push_back("-Xclang");
2742 Args->push_back("-detailed-preprocessing-record");
2743 }
2744
2745 unsigned NumErrors = Diags->getClient()->getNumErrors();
2746 OwningPtr<ASTUnit> ErrUnit;
2747 OwningPtr<ASTUnit> Unit(
2748 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2749 /* vector::data() not portable */,
2750 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2751 Diags,
2752 CXXIdx->getClangResourcesPath(),
2753 CXXIdx->getOnlyLocalDecls(),
2754 /*CaptureDiagnostics=*/true,
2755 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2756 RemappedFiles->size(),
2757 /*RemappedFilesKeepOriginalName=*/true,
2758 PrecompilePreamble,
2759 TUKind,
2760 CacheCodeCompetionResults,
2761 IncludeBriefCommentsInCodeCompletion,
2762 /*AllowPCHWithCompilerErrors=*/true,
2763 SkipFunctionBodies,
2764 /*UserFilesAreVolatile=*/true,
2765 ForSerialization,
2766 &ErrUnit));
2767
2768 if (NumErrors != Diags->getClient()->getNumErrors()) {
2769 // Make sure to check that 'Unit' is non-NULL.
2770 if (CXXIdx->getDisplayDiagnostics())
2771 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2772 }
2773
2774 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2775}
2776CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2777 const char *source_filename,
2778 const char * const *command_line_args,
2779 int num_command_line_args,
2780 struct CXUnsavedFile *unsaved_files,
2781 unsigned num_unsaved_files,
2782 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002783 LOG_FUNC_SECTION {
2784 *Log << source_filename << ": ";
2785 for (int i = 0; i != num_command_line_args; ++i)
2786 *Log << command_line_args[i] << " ";
2787 }
2788
Guy Benyei11169dd2012-12-18 14:30:41 +00002789 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2790 num_command_line_args, unsaved_files,
2791 num_unsaved_files, options, 0 };
2792 llvm::CrashRecoveryContext CRC;
2793
2794 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2795 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2796 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2797 fprintf(stderr, " 'command_line_args' : [");
2798 for (int i = 0; i != num_command_line_args; ++i) {
2799 if (i)
2800 fprintf(stderr, ", ");
2801 fprintf(stderr, "'%s'", command_line_args[i]);
2802 }
2803 fprintf(stderr, "],\n");
2804 fprintf(stderr, " 'unsaved_files' : [");
2805 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2806 if (i)
2807 fprintf(stderr, ", ");
2808 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2809 unsaved_files[i].Length);
2810 }
2811 fprintf(stderr, "],\n");
2812 fprintf(stderr, " 'options' : %d,\n", options);
2813 fprintf(stderr, "}\n");
2814
2815 return 0;
2816 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2817 PrintLibclangResourceUsage(PTUI.result);
2818 }
2819
2820 return PTUI.result;
2821}
2822
2823unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2824 return CXSaveTranslationUnit_None;
2825}
2826
2827namespace {
2828
2829struct SaveTranslationUnitInfo {
2830 CXTranslationUnit TU;
2831 const char *FileName;
2832 unsigned options;
2833 CXSaveError result;
2834};
2835
2836}
2837
2838static void clang_saveTranslationUnit_Impl(void *UserData) {
2839 SaveTranslationUnitInfo *STUI =
2840 static_cast<SaveTranslationUnitInfo*>(UserData);
2841
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002842 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2844 setThreadBackgroundPriority();
2845
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002846 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002847 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2848}
2849
2850int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2851 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002852 LOG_FUNC_SECTION {
2853 *Log << TU << ' ' << FileName;
2854 }
2855
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 if (!TU)
2857 return CXSaveError_InvalidTU;
2858
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2861 if (!CXXUnit->hasSema())
2862 return CXSaveError_InvalidTU;
2863
2864 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2865
2866 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2867 getenv("LIBCLANG_NOTHREADS")) {
2868 clang_saveTranslationUnit_Impl(&STUI);
2869
2870 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2871 PrintLibclangResourceUsage(TU);
2872
2873 return STUI.result;
2874 }
2875
2876 // We have an AST that has invalid nodes due to compiler errors.
2877 // Use a crash recovery thread for protection.
2878
2879 llvm::CrashRecoveryContext CRC;
2880
2881 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2882 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2883 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2884 fprintf(stderr, " 'options' : %d,\n", options);
2885 fprintf(stderr, "}\n");
2886
2887 return CXSaveError_Unknown;
2888
2889 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2890 PrintLibclangResourceUsage(TU);
2891 }
2892
2893 return STUI.result;
2894}
2895
2896void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2897 if (CTUnit) {
2898 // If the translation unit has been marked as unsafe to free, just discard
2899 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002900 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 return;
2902
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002903 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002904 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2906 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002907 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 delete CTUnit;
2909 }
2910}
2911
2912unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2913 return CXReparse_None;
2914}
2915
2916struct ReparseTranslationUnitInfo {
2917 CXTranslationUnit TU;
2918 unsigned num_unsaved_files;
2919 struct CXUnsavedFile *unsaved_files;
2920 unsigned options;
2921 int result;
2922};
2923
2924static void clang_reparseTranslationUnit_Impl(void *UserData) {
2925 ReparseTranslationUnitInfo *RTUI =
2926 static_cast<ReparseTranslationUnitInfo*>(UserData);
2927 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002928 if (!TU)
2929 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002930
2931 // Reset the associated diagnostics.
2932 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2933 TU->Diagnostics = 0;
2934
2935 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2936 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2937 unsigned options = RTUI->options;
2938 (void) options;
2939 RTUI->result = 1;
2940
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002941 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002942 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2943 setThreadBackgroundPriority();
2944
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002946 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2947
2948 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2949 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2950
2951 // Recover resources if we crash before exiting this function.
2952 llvm::CrashRecoveryContextCleanupRegistrar<
2953 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2954
2955 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2956 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2957 const llvm::MemoryBuffer *Buffer
2958 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2959 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2960 Buffer));
2961 }
2962
2963 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2964 RemappedFiles->size()))
2965 RTUI->result = 0;
2966}
2967
2968int clang_reparseTranslationUnit(CXTranslationUnit TU,
2969 unsigned num_unsaved_files,
2970 struct CXUnsavedFile *unsaved_files,
2971 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002972 LOG_FUNC_SECTION {
2973 *Log << TU;
2974 }
2975
Guy Benyei11169dd2012-12-18 14:30:41 +00002976 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2977 options, 0 };
2978
2979 if (getenv("LIBCLANG_NOTHREADS")) {
2980 clang_reparseTranslationUnit_Impl(&RTUI);
2981 return RTUI.result;
2982 }
2983
2984 llvm::CrashRecoveryContext CRC;
2985
2986 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2987 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002988 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 return 1;
2990 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2991 PrintLibclangResourceUsage(TU);
2992
2993 return RTUI.result;
2994}
2995
2996
2997CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2998 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002999 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003000
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003001 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003002 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003003}
3004
3005CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003006 if (!TU)
3007 return clang_getNullCursor();
3008
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3011}
3012
3013} // end: extern "C"
3014
3015//===----------------------------------------------------------------------===//
3016// CXFile Operations.
3017//===----------------------------------------------------------------------===//
3018
3019extern "C" {
3020CXString clang_getFileName(CXFile SFile) {
3021 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003022 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003023
3024 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003025 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003026}
3027
3028time_t clang_getFileTime(CXFile SFile) {
3029 if (!SFile)
3030 return 0;
3031
3032 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3033 return FEnt->getModificationTime();
3034}
3035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003036CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3037 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 return 0;
3039
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003041
3042 FileManager &FMgr = CXXUnit->getFileManager();
3043 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3044}
3045
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003046unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3047 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003048 return 0;
3049
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003050 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 FileEntry *FEnt = static_cast<FileEntry *>(file);
3052 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3053 .isFileMultipleIncludeGuarded(FEnt);
3054}
3055
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003056int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3057 if (!file || !outID)
3058 return 1;
3059
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003060 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003061 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3062 outID->data[0] = ID.getDevice();
3063 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003064 outID->data[2] = FEnt->getModificationTime();
3065 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003066}
3067
Guy Benyei11169dd2012-12-18 14:30:41 +00003068} // end: extern "C"
3069
3070//===----------------------------------------------------------------------===//
3071// CXCursor Operations.
3072//===----------------------------------------------------------------------===//
3073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003074static const Decl *getDeclFromExpr(const Stmt *E) {
3075 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 return getDeclFromExpr(CE->getSubExpr());
3077
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003078 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003080 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003082 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003084 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 if (PRE->isExplicitProperty())
3086 return PRE->getExplicitProperty();
3087 // It could be messaging both getter and setter as in:
3088 // ++myobj.myprop;
3089 // in which case prefer to associate the setter since it is less obvious
3090 // from inspecting the source that the setter is going to get called.
3091 if (PRE->isMessagingSetter())
3092 return PRE->getImplicitPropertySetter();
3093 return PRE->getImplicitPropertyGetter();
3094 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003095 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003097 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 if (Expr *Src = OVE->getSourceExpr())
3099 return getDeclFromExpr(Src);
3100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003101 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003103 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 if (!CE->isElidable())
3105 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003106 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 return OME->getMethodDecl();
3108
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003109 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003111 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3113 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003114 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3116 isa<ParmVarDecl>(SizeOfPack->getPack()))
3117 return SizeOfPack->getPack();
3118
3119 return 0;
3120}
3121
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003122static SourceLocation getLocationFromExpr(const Expr *E) {
3123 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 return getLocationFromExpr(CE->getSubExpr());
3125
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003126 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003128 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003130 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003132 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003134 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003136 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 return PropRef->getLocation();
3138
3139 return E->getLocStart();
3140}
3141
3142extern "C" {
3143
3144unsigned clang_visitChildren(CXCursor parent,
3145 CXCursorVisitor visitor,
3146 CXClientData client_data) {
3147 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3148 /*VisitPreprocessorLast=*/false);
3149 return CursorVis.VisitChildren(parent);
3150}
3151
3152#ifndef __has_feature
3153#define __has_feature(x) 0
3154#endif
3155#if __has_feature(blocks)
3156typedef enum CXChildVisitResult
3157 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3158
3159static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3160 CXClientData client_data) {
3161 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3162 return block(cursor, parent);
3163}
3164#else
3165// If we are compiled with a compiler that doesn't have native blocks support,
3166// define and call the block manually, so the
3167typedef struct _CXChildVisitResult
3168{
3169 void *isa;
3170 int flags;
3171 int reserved;
3172 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3173 CXCursor);
3174} *CXCursorVisitorBlock;
3175
3176static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3177 CXClientData client_data) {
3178 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3179 return block->invoke(block, cursor, parent);
3180}
3181#endif
3182
3183
3184unsigned clang_visitChildrenWithBlock(CXCursor parent,
3185 CXCursorVisitorBlock block) {
3186 return clang_visitChildren(parent, visitWithBlock, block);
3187}
3188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003191 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003195 if (const ObjCPropertyImplDecl *PropImpl =
3196 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003198 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003199
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003202 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003203
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003204 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 }
3206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003207 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003208 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003209
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003210 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3212 // and returns different names. NamedDecl returns the class name and
3213 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003214 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003215
3216 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003217 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003218
3219 SmallString<1024> S;
3220 llvm::raw_svector_ostream os(S);
3221 ND->printName(os);
3222
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003223 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003224}
3225
3226CXString clang_getCursorSpelling(CXCursor C) {
3227 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003228 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003229
3230 if (clang_isReference(C.kind)) {
3231 switch (C.kind) {
3232 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003233 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003234 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 }
3236 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003237 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003238 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 }
3240 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003241 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003243 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 }
3245 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003246 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003247 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 }
3249 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003250 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 assert(Type && "Missing type decl");
3252
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003253 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 getAsString());
3255 }
3256 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003257 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 assert(Template && "Missing template decl");
3259
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003260 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 }
3262
3263 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003264 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 assert(NS && "Missing namespace decl");
3266
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003267 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 }
3269
3270 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003271 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 assert(Field && "Missing member decl");
3273
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003274 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 }
3276
3277 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003278 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 assert(Label && "Missing label");
3280
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003281 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 }
3283
3284 case CXCursor_OverloadedDeclRef: {
3285 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3287 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003288 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003289 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003291 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003292 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 OverloadedTemplateStorage *Ovl
3294 = Storage.get<OverloadedTemplateStorage*>();
3295 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003297 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 }
3299
3300 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003301 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 assert(Var && "Missing variable decl");
3303
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003304 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 }
3306
3307 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003308 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 }
3310 }
3311
3312 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 if (D)
3315 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003316 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 }
3318
3319 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003320 const Stmt *S = getCursorStmt(C);
3321 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003322 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003323
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326
3327 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003328 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 ->getNameStart());
3330
3331 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003332 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 ->getNameStart());
3334
3335 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003336 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003337
3338 if (clang_isDeclaration(C.kind))
3339 return getDeclSpelling(getCursorDecl(C));
3340
3341 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003342 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 }
3345
3346 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003347 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003348 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003351 if (C.kind == CXCursor_PackedAttr) {
3352 return cxstring::createRef("packed");
3353 }
3354
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003355 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003356}
3357
3358CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3359 unsigned pieceIndex,
3360 unsigned options) {
3361 if (clang_Cursor_isNull(C))
3362 return clang_getNullRange();
3363
3364 ASTContext &Ctx = getCursorContext(C);
3365
3366 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003367 const Stmt *S = getCursorStmt(C);
3368 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 if (pieceIndex > 0)
3370 return clang_getNullRange();
3371 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3372 }
3373
3374 return clang_getNullRange();
3375 }
3376
3377 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003378 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3380 if (pieceIndex >= ME->getNumSelectorLocs())
3381 return clang_getNullRange();
3382 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3383 }
3384 }
3385
3386 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3387 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003388 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3390 if (pieceIndex >= MD->getNumSelectorLocs())
3391 return clang_getNullRange();
3392 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3393 }
3394 }
3395
3396 if (C.kind == CXCursor_ObjCCategoryDecl ||
3397 C.kind == CXCursor_ObjCCategoryImplDecl) {
3398 if (pieceIndex > 0)
3399 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003400 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3402 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003403 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3405 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3406 }
3407
3408 if (C.kind == CXCursor_ModuleImportDecl) {
3409 if (pieceIndex > 0)
3410 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const ImportDecl *ImportD =
3412 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3414 if (!Locs.empty())
3415 return cxloc::translateSourceRange(Ctx,
3416 SourceRange(Locs.front(), Locs.back()));
3417 }
3418 return clang_getNullRange();
3419 }
3420
3421 // FIXME: A CXCursor_InclusionDirective should give the location of the
3422 // filename, but we don't keep track of this.
3423
3424 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3425 // but we don't keep track of this.
3426
3427 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3428 // but we don't keep track of this.
3429
3430 // Default handling, give the location of the cursor.
3431
3432 if (pieceIndex > 0)
3433 return clang_getNullRange();
3434
3435 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3436 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3437 return cxloc::translateSourceRange(Ctx, Loc);
3438}
3439
3440CXString clang_getCursorDisplayName(CXCursor C) {
3441 if (!clang_isDeclaration(C.kind))
3442 return clang_getCursorSpelling(C);
3443
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003444 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003446 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003447
3448 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003449 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 D = FunTmpl->getTemplatedDecl();
3451
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003452 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 SmallString<64> Str;
3454 llvm::raw_svector_ostream OS(Str);
3455 OS << *Function;
3456 if (Function->getPrimaryTemplate())
3457 OS << "<>";
3458 OS << "(";
3459 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3460 if (I)
3461 OS << ", ";
3462 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3463 }
3464
3465 if (Function->isVariadic()) {
3466 if (Function->getNumParams())
3467 OS << ", ";
3468 OS << "...";
3469 }
3470 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 }
3473
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003474 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 SmallString<64> Str;
3476 llvm::raw_svector_ostream OS(Str);
3477 OS << *ClassTemplate;
3478 OS << "<";
3479 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3480 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3481 if (I)
3482 OS << ", ";
3483
3484 NamedDecl *Param = Params->getParam(I);
3485 if (Param->getIdentifier()) {
3486 OS << Param->getIdentifier()->getName();
3487 continue;
3488 }
3489
3490 // There is no parameter name, which makes this tricky. Try to come up
3491 // with something useful that isn't too long.
3492 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3493 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3494 else if (NonTypeTemplateParmDecl *NTTP
3495 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3496 OS << NTTP->getType().getAsString(Policy);
3497 else
3498 OS << "template<...> class";
3499 }
3500
3501 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003502 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 }
3504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3507 // If the type was explicitly written, use that.
3508 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003509 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003510
Benjamin Kramer9170e912013-02-22 15:46:01 +00003511 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 llvm::raw_svector_ostream OS(Str);
3513 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003514 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 ClassSpec->getTemplateArgs().data(),
3516 ClassSpec->getTemplateArgs().size(),
3517 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003518 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 }
3520
3521 return clang_getCursorSpelling(C);
3522}
3523
3524CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3525 switch (Kind) {
3526 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003527 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003529 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003531 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003533 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003535 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003537 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003539 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003541 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003543 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003545 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003547 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003549 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003565 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003567 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003569 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003571 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003573 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003575 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003579 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003581 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003583 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003585 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003587 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003589 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003593 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003595 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003597 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003599 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003603 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003605 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003609 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003654 case CXCursor_ObjCSelfExpr:
3655 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003772 case CXCursor_PackedAttr:
3773 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003822 case CXCursor_OMPParallelDirective:
3823 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 }
3825
3826 llvm_unreachable("Unhandled CXCursorKind");
3827}
3828
3829struct GetCursorData {
3830 SourceLocation TokenBeginLoc;
3831 bool PointsAtMacroArgExpansion;
3832 bool VisitedObjCPropertyImplDecl;
3833 SourceLocation VisitedDeclaratorDeclStartLoc;
3834 CXCursor &BestCursor;
3835
3836 GetCursorData(SourceManager &SM,
3837 SourceLocation tokenBegin, CXCursor &outputCursor)
3838 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3839 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3840 VisitedObjCPropertyImplDecl = false;
3841 }
3842};
3843
3844static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3845 CXCursor parent,
3846 CXClientData client_data) {
3847 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3848 CXCursor *BestCursor = &Data->BestCursor;
3849
3850 // If we point inside a macro argument we should provide info of what the
3851 // token is so use the actual cursor, don't replace it with a macro expansion
3852 // cursor.
3853 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3854 return CXChildVisit_Recurse;
3855
3856 if (clang_isDeclaration(cursor.kind)) {
3857 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003858 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3860 if (MD->isImplicit())
3861 return CXChildVisit_Break;
3862
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003863 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3865 // Check that when we have multiple @class references in the same line,
3866 // that later ones do not override the previous ones.
3867 // If we have:
3868 // @class Foo, Bar;
3869 // source ranges for both start at '@', so 'Bar' will end up overriding
3870 // 'Foo' even though the cursor location was at 'Foo'.
3871 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3872 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003873 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3875 if (PrevID != ID &&
3876 !PrevID->isThisDeclarationADefinition() &&
3877 !ID->isThisDeclarationADefinition())
3878 return CXChildVisit_Break;
3879 }
3880
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003881 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3883 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3884 // Check that when we have multiple declarators in the same line,
3885 // that later ones do not override the previous ones.
3886 // If we have:
3887 // int Foo, Bar;
3888 // source ranges for both start at 'int', so 'Bar' will end up overriding
3889 // 'Foo' even though the cursor location was at 'Foo'.
3890 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3891 return CXChildVisit_Break;
3892 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3893
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003894 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3896 (void)PropImp;
3897 // Check that when we have multiple @synthesize in the same line,
3898 // that later ones do not override the previous ones.
3899 // If we have:
3900 // @synthesize Foo, Bar;
3901 // source ranges for both start at '@', so 'Bar' will end up overriding
3902 // 'Foo' even though the cursor location was at 'Foo'.
3903 if (Data->VisitedObjCPropertyImplDecl)
3904 return CXChildVisit_Break;
3905 Data->VisitedObjCPropertyImplDecl = true;
3906 }
3907 }
3908
3909 if (clang_isExpression(cursor.kind) &&
3910 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003911 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 // Avoid having the cursor of an expression replace the declaration cursor
3913 // when the expression source range overlaps the declaration range.
3914 // This can happen for C++ constructor expressions whose range generally
3915 // include the variable declaration, e.g.:
3916 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3917 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3918 D->getLocation() == Data->TokenBeginLoc)
3919 return CXChildVisit_Break;
3920 }
3921 }
3922
3923 // If our current best cursor is the construction of a temporary object,
3924 // don't replace that cursor with a type reference, because we want
3925 // clang_getCursor() to point at the constructor.
3926 if (clang_isExpression(BestCursor->kind) &&
3927 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3928 cursor.kind == CXCursor_TypeRef) {
3929 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3930 // as having the actual point on the type reference.
3931 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3932 return CXChildVisit_Recurse;
3933 }
3934
3935 *BestCursor = cursor;
3936 return CXChildVisit_Recurse;
3937}
3938
3939CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3940 if (!TU)
3941 return clang_getNullCursor();
3942
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003943 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3945
3946 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3947 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3948
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003949 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 CXFile SearchFile;
3951 unsigned SearchLine, SearchColumn;
3952 CXFile ResultFile;
3953 unsigned ResultLine, ResultColumn;
3954 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3955 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3956 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3957
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003958 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3959 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 &ResultColumn, 0);
3961 SearchFileName = clang_getFileName(SearchFile);
3962 ResultFileName = clang_getFileName(ResultFile);
3963 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3964 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003965 *Log << llvm::format("(%s:%d:%d) = %s",
3966 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3967 clang_getCString(KindSpelling))
3968 << llvm::format("(%s:%d:%d):%s%s",
3969 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3970 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 clang_disposeString(SearchFileName);
3972 clang_disposeString(ResultFileName);
3973 clang_disposeString(KindSpelling);
3974 clang_disposeString(USR);
3975
3976 CXCursor Definition = clang_getCursorDefinition(Result);
3977 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3978 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3979 CXString DefinitionKindSpelling
3980 = clang_getCursorKindSpelling(Definition.kind);
3981 CXFile DefinitionFile;
3982 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003983 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 &DefinitionLine, &DefinitionColumn, 0);
3985 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003986 *Log << llvm::format(" -> %s(%s:%d:%d)",
3987 clang_getCString(DefinitionKindSpelling),
3988 clang_getCString(DefinitionFileName),
3989 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 clang_disposeString(DefinitionFileName);
3991 clang_disposeString(DefinitionKindSpelling);
3992 }
3993 }
3994
3995 return Result;
3996}
3997
3998CXCursor clang_getNullCursor(void) {
3999 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4000}
4001
4002unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004003 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4004 // can't set consistently. For example, when visiting a DeclStmt we will set
4005 // it but we don't set it on the result of clang_getCursorDefinition for
4006 // a reference of the same declaration.
4007 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4008 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4009 // to provide that kind of info.
4010 if (clang_isDeclaration(X.kind))
4011 X.data[1] = 0;
4012 if (clang_isDeclaration(Y.kind))
4013 Y.data[1] = 0;
4014
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 return X == Y;
4016}
4017
4018unsigned clang_hashCursor(CXCursor C) {
4019 unsigned Index = 0;
4020 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4021 Index = 1;
4022
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004023 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 std::make_pair(C.kind, C.data[Index]));
4025}
4026
4027unsigned clang_isInvalid(enum CXCursorKind K) {
4028 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4029}
4030
4031unsigned clang_isDeclaration(enum CXCursorKind K) {
4032 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4033 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4034}
4035
4036unsigned clang_isReference(enum CXCursorKind K) {
4037 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4038}
4039
4040unsigned clang_isExpression(enum CXCursorKind K) {
4041 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4042}
4043
4044unsigned clang_isStatement(enum CXCursorKind K) {
4045 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4046}
4047
4048unsigned clang_isAttribute(enum CXCursorKind K) {
4049 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4050}
4051
4052unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4053 return K == CXCursor_TranslationUnit;
4054}
4055
4056unsigned clang_isPreprocessing(enum CXCursorKind K) {
4057 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4058}
4059
4060unsigned clang_isUnexposed(enum CXCursorKind K) {
4061 switch (K) {
4062 case CXCursor_UnexposedDecl:
4063 case CXCursor_UnexposedExpr:
4064 case CXCursor_UnexposedStmt:
4065 case CXCursor_UnexposedAttr:
4066 return true;
4067 default:
4068 return false;
4069 }
4070}
4071
4072CXCursorKind clang_getCursorKind(CXCursor C) {
4073 return C.kind;
4074}
4075
4076CXSourceLocation clang_getCursorLocation(CXCursor C) {
4077 if (clang_isReference(C.kind)) {
4078 switch (C.kind) {
4079 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004080 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 = getCursorObjCSuperClassRef(C);
4082 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4083 }
4084
4085 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004086 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 = getCursorObjCProtocolRef(C);
4088 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4089 }
4090
4091 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004092 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 = getCursorObjCClassRef(C);
4094 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4095 }
4096
4097 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004098 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4100 }
4101
4102 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004103 std::pair<const TemplateDecl *, SourceLocation> P =
4104 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4106 }
4107
4108 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004109 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4111 }
4112
4113 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004114 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4116 }
4117
4118 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004119 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4121 }
4122
4123 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004124 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 if (!BaseSpec)
4126 return clang_getNullLocation();
4127
4128 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4129 return cxloc::translateSourceLocation(getCursorContext(C),
4130 TSInfo->getTypeLoc().getBeginLoc());
4131
4132 return cxloc::translateSourceLocation(getCursorContext(C),
4133 BaseSpec->getLocStart());
4134 }
4135
4136 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004137 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4139 }
4140
4141 case CXCursor_OverloadedDeclRef:
4142 return cxloc::translateSourceLocation(getCursorContext(C),
4143 getCursorOverloadedDeclRef(C).second);
4144
4145 default:
4146 // FIXME: Need a way to enumerate all non-reference cases.
4147 llvm_unreachable("Missed a reference kind");
4148 }
4149 }
4150
4151 if (clang_isExpression(C.kind))
4152 return cxloc::translateSourceLocation(getCursorContext(C),
4153 getLocationFromExpr(getCursorExpr(C)));
4154
4155 if (clang_isStatement(C.kind))
4156 return cxloc::translateSourceLocation(getCursorContext(C),
4157 getCursorStmt(C)->getLocStart());
4158
4159 if (C.kind == CXCursor_PreprocessingDirective) {
4160 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4161 return cxloc::translateSourceLocation(getCursorContext(C), L);
4162 }
4163
4164 if (C.kind == CXCursor_MacroExpansion) {
4165 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004166 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 return cxloc::translateSourceLocation(getCursorContext(C), L);
4168 }
4169
4170 if (C.kind == CXCursor_MacroDefinition) {
4171 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4172 return cxloc::translateSourceLocation(getCursorContext(C), L);
4173 }
4174
4175 if (C.kind == CXCursor_InclusionDirective) {
4176 SourceLocation L
4177 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4178 return cxloc::translateSourceLocation(getCursorContext(C), L);
4179 }
4180
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004181 if (clang_isAttribute(C.kind)) {
4182 SourceLocation L
4183 = cxcursor::getCursorAttr(C)->getLocation();
4184 return cxloc::translateSourceLocation(getCursorContext(C), L);
4185 }
4186
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 if (!clang_isDeclaration(C.kind))
4188 return clang_getNullLocation();
4189
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004190 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 if (!D)
4192 return clang_getNullLocation();
4193
4194 SourceLocation Loc = D->getLocation();
4195 // FIXME: Multiple variables declared in a single declaration
4196 // currently lack the information needed to correctly determine their
4197 // ranges when accounting for the type-specifier. We use context
4198 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4199 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004200 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 if (!cxcursor::isFirstInDeclGroup(C))
4202 Loc = VD->getLocation();
4203 }
4204
4205 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004206 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 Loc = MD->getSelectorStartLoc();
4208
4209 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4210}
4211
4212} // end extern "C"
4213
4214CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4215 assert(TU);
4216
4217 // Guard against an invalid SourceLocation, or we may assert in one
4218 // of the following calls.
4219 if (SLoc.isInvalid())
4220 return clang_getNullCursor();
4221
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004222 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223
4224 // Translate the given source location to make it point at the beginning of
4225 // the token under the cursor.
4226 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4227 CXXUnit->getASTContext().getLangOpts());
4228
4229 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4230 if (SLoc.isValid()) {
4231 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4232 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4233 /*VisitPreprocessorLast=*/true,
4234 /*VisitIncludedEntities=*/false,
4235 SourceLocation(SLoc));
4236 CursorVis.visitFileRegion();
4237 }
4238
4239 return Result;
4240}
4241
4242static SourceRange getRawCursorExtent(CXCursor C) {
4243 if (clang_isReference(C.kind)) {
4244 switch (C.kind) {
4245 case CXCursor_ObjCSuperClassRef:
4246 return getCursorObjCSuperClassRef(C).second;
4247
4248 case CXCursor_ObjCProtocolRef:
4249 return getCursorObjCProtocolRef(C).second;
4250
4251 case CXCursor_ObjCClassRef:
4252 return getCursorObjCClassRef(C).second;
4253
4254 case CXCursor_TypeRef:
4255 return getCursorTypeRef(C).second;
4256
4257 case CXCursor_TemplateRef:
4258 return getCursorTemplateRef(C).second;
4259
4260 case CXCursor_NamespaceRef:
4261 return getCursorNamespaceRef(C).second;
4262
4263 case CXCursor_MemberRef:
4264 return getCursorMemberRef(C).second;
4265
4266 case CXCursor_CXXBaseSpecifier:
4267 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4268
4269 case CXCursor_LabelRef:
4270 return getCursorLabelRef(C).second;
4271
4272 case CXCursor_OverloadedDeclRef:
4273 return getCursorOverloadedDeclRef(C).second;
4274
4275 case CXCursor_VariableRef:
4276 return getCursorVariableRef(C).second;
4277
4278 default:
4279 // FIXME: Need a way to enumerate all non-reference cases.
4280 llvm_unreachable("Missed a reference kind");
4281 }
4282 }
4283
4284 if (clang_isExpression(C.kind))
4285 return getCursorExpr(C)->getSourceRange();
4286
4287 if (clang_isStatement(C.kind))
4288 return getCursorStmt(C)->getSourceRange();
4289
4290 if (clang_isAttribute(C.kind))
4291 return getCursorAttr(C)->getRange();
4292
4293 if (C.kind == CXCursor_PreprocessingDirective)
4294 return cxcursor::getCursorPreprocessingDirective(C);
4295
4296 if (C.kind == CXCursor_MacroExpansion) {
4297 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004298 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 return TU->mapRangeFromPreamble(Range);
4300 }
4301
4302 if (C.kind == CXCursor_MacroDefinition) {
4303 ASTUnit *TU = getCursorASTUnit(C);
4304 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4305 return TU->mapRangeFromPreamble(Range);
4306 }
4307
4308 if (C.kind == CXCursor_InclusionDirective) {
4309 ASTUnit *TU = getCursorASTUnit(C);
4310 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4311 return TU->mapRangeFromPreamble(Range);
4312 }
4313
4314 if (C.kind == CXCursor_TranslationUnit) {
4315 ASTUnit *TU = getCursorASTUnit(C);
4316 FileID MainID = TU->getSourceManager().getMainFileID();
4317 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4318 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4319 return SourceRange(Start, End);
4320 }
4321
4322 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004323 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 if (!D)
4325 return SourceRange();
4326
4327 SourceRange R = D->getSourceRange();
4328 // FIXME: Multiple variables declared in a single declaration
4329 // currently lack the information needed to correctly determine their
4330 // ranges when accounting for the type-specifier. We use context
4331 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4332 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004333 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 if (!cxcursor::isFirstInDeclGroup(C))
4335 R.setBegin(VD->getLocation());
4336 }
4337 return R;
4338 }
4339 return SourceRange();
4340}
4341
4342/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4343/// the decl-specifier-seq for declarations.
4344static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4345 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004346 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 if (!D)
4348 return SourceRange();
4349
4350 SourceRange R = D->getSourceRange();
4351
4352 // Adjust the start of the location for declarations preceded by
4353 // declaration specifiers.
4354 SourceLocation StartLoc;
4355 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4356 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4357 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004358 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4360 StartLoc = TI->getTypeLoc().getLocStart();
4361 }
4362
4363 if (StartLoc.isValid() && R.getBegin().isValid() &&
4364 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4365 R.setBegin(StartLoc);
4366
4367 // FIXME: Multiple variables declared in a single declaration
4368 // currently lack the information needed to correctly determine their
4369 // ranges when accounting for the type-specifier. We use context
4370 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4371 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004372 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 if (!cxcursor::isFirstInDeclGroup(C))
4374 R.setBegin(VD->getLocation());
4375 }
4376
4377 return R;
4378 }
4379
4380 return getRawCursorExtent(C);
4381}
4382
4383extern "C" {
4384
4385CXSourceRange clang_getCursorExtent(CXCursor C) {
4386 SourceRange R = getRawCursorExtent(C);
4387 if (R.isInvalid())
4388 return clang_getNullRange();
4389
4390 return cxloc::translateSourceRange(getCursorContext(C), R);
4391}
4392
4393CXCursor clang_getCursorReferenced(CXCursor C) {
4394 if (clang_isInvalid(C.kind))
4395 return clang_getNullCursor();
4396
4397 CXTranslationUnit tu = getCursorTU(C);
4398 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004399 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 if (!D)
4401 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004402 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004404 if (const ObjCPropertyImplDecl *PropImpl =
4405 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4407 return MakeCXCursor(Property, tu);
4408
4409 return C;
4410 }
4411
4412 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004413 const Expr *E = getCursorExpr(C);
4414 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 if (D) {
4416 CXCursor declCursor = MakeCXCursor(D, tu);
4417 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4418 declCursor);
4419 return declCursor;
4420 }
4421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004422 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 return MakeCursorOverloadedDeclRef(Ovl, tu);
4424
4425 return clang_getNullCursor();
4426 }
4427
4428 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004429 const Stmt *S = getCursorStmt(C);
4430 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 if (LabelDecl *label = Goto->getLabel())
4432 if (LabelStmt *labelS = label->getStmt())
4433 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4434
4435 return clang_getNullCursor();
4436 }
4437
4438 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004439 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 return MakeMacroDefinitionCursor(Def, tu);
4441 }
4442
4443 if (!clang_isReference(C.kind))
4444 return clang_getNullCursor();
4445
4446 switch (C.kind) {
4447 case CXCursor_ObjCSuperClassRef:
4448 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4449
4450 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004451 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4452 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 return MakeCXCursor(Def, tu);
4454
4455 return MakeCXCursor(Prot, tu);
4456 }
4457
4458 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004459 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4460 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 return MakeCXCursor(Def, tu);
4462
4463 return MakeCXCursor(Class, tu);
4464 }
4465
4466 case CXCursor_TypeRef:
4467 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4468
4469 case CXCursor_TemplateRef:
4470 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4471
4472 case CXCursor_NamespaceRef:
4473 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4474
4475 case CXCursor_MemberRef:
4476 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4477
4478 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004479 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4481 tu ));
4482 }
4483
4484 case CXCursor_LabelRef:
4485 // FIXME: We end up faking the "parent" declaration here because we
4486 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004487 return MakeCXCursor(getCursorLabelRef(C).first,
4488 cxtu::getASTUnit(tu)->getASTContext()
4489 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 tu);
4491
4492 case CXCursor_OverloadedDeclRef:
4493 return C;
4494
4495 case CXCursor_VariableRef:
4496 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4497
4498 default:
4499 // We would prefer to enumerate all non-reference cursor kinds here.
4500 llvm_unreachable("Unhandled reference cursor kind");
4501 }
4502}
4503
4504CXCursor clang_getCursorDefinition(CXCursor C) {
4505 if (clang_isInvalid(C.kind))
4506 return clang_getNullCursor();
4507
4508 CXTranslationUnit TU = getCursorTU(C);
4509
4510 bool WasReference = false;
4511 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4512 C = clang_getCursorReferenced(C);
4513 WasReference = true;
4514 }
4515
4516 if (C.kind == CXCursor_MacroExpansion)
4517 return clang_getCursorReferenced(C);
4518
4519 if (!clang_isDeclaration(C.kind))
4520 return clang_getNullCursor();
4521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004522 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 if (!D)
4524 return clang_getNullCursor();
4525
4526 switch (D->getKind()) {
4527 // Declaration kinds that don't really separate the notions of
4528 // declaration and definition.
4529 case Decl::Namespace:
4530 case Decl::Typedef:
4531 case Decl::TypeAlias:
4532 case Decl::TypeAliasTemplate:
4533 case Decl::TemplateTypeParm:
4534 case Decl::EnumConstant:
4535 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004536 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case Decl::IndirectField:
4538 case Decl::ObjCIvar:
4539 case Decl::ObjCAtDefsField:
4540 case Decl::ImplicitParam:
4541 case Decl::ParmVar:
4542 case Decl::NonTypeTemplateParm:
4543 case Decl::TemplateTemplateParm:
4544 case Decl::ObjCCategoryImpl:
4545 case Decl::ObjCImplementation:
4546 case Decl::AccessSpec:
4547 case Decl::LinkageSpec:
4548 case Decl::ObjCPropertyImpl:
4549 case Decl::FileScopeAsm:
4550 case Decl::StaticAssert:
4551 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004552 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case Decl::Label: // FIXME: Is this right??
4554 case Decl::ClassScopeFunctionSpecialization:
4555 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004556 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 return C;
4558
4559 // Declaration kinds that don't make any sense here, but are
4560 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004561 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 case Decl::TranslationUnit:
4563 break;
4564
4565 // Declaration kinds for which the definition is not resolvable.
4566 case Decl::UnresolvedUsingTypename:
4567 case Decl::UnresolvedUsingValue:
4568 break;
4569
4570 case Decl::UsingDirective:
4571 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4572 TU);
4573
4574 case Decl::NamespaceAlias:
4575 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4576
4577 case Decl::Enum:
4578 case Decl::Record:
4579 case Decl::CXXRecord:
4580 case Decl::ClassTemplateSpecialization:
4581 case Decl::ClassTemplatePartialSpecialization:
4582 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4583 return MakeCXCursor(Def, TU);
4584 return clang_getNullCursor();
4585
4586 case Decl::Function:
4587 case Decl::CXXMethod:
4588 case Decl::CXXConstructor:
4589 case Decl::CXXDestructor:
4590 case Decl::CXXConversion: {
4591 const FunctionDecl *Def = 0;
4592 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004593 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 return clang_getNullCursor();
4595 }
4596
Larisse Voufo39a1e502013-08-06 01:03:05 +00004597 case Decl::Var:
4598 case Decl::VarTemplateSpecialization:
4599 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004601 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 return MakeCXCursor(Def, TU);
4603 return clang_getNullCursor();
4604 }
4605
4606 case Decl::FunctionTemplate: {
4607 const FunctionDecl *Def = 0;
4608 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4609 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4610 return clang_getNullCursor();
4611 }
4612
4613 case Decl::ClassTemplate: {
4614 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4615 ->getDefinition())
4616 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4617 TU);
4618 return clang_getNullCursor();
4619 }
4620
Larisse Voufo39a1e502013-08-06 01:03:05 +00004621 case Decl::VarTemplate: {
4622 if (VarDecl *Def =
4623 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4624 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4625 return clang_getNullCursor();
4626 }
4627
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 case Decl::Using:
4629 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4630 D->getLocation(), TU);
4631
4632 case Decl::UsingShadow:
4633 return clang_getCursorDefinition(
4634 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4635 TU));
4636
4637 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004638 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 if (Method->isThisDeclarationADefinition())
4640 return C;
4641
4642 // Dig out the method definition in the associated
4643 // @implementation, if we have it.
4644 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004645 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4647 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4648 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4649 Method->isInstanceMethod()))
4650 if (Def->isThisDeclarationADefinition())
4651 return MakeCXCursor(Def, TU);
4652
4653 return clang_getNullCursor();
4654 }
4655
4656 case Decl::ObjCCategory:
4657 if (ObjCCategoryImplDecl *Impl
4658 = cast<ObjCCategoryDecl>(D)->getImplementation())
4659 return MakeCXCursor(Impl, TU);
4660 return clang_getNullCursor();
4661
4662 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004663 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 return MakeCXCursor(Def, TU);
4665 return clang_getNullCursor();
4666
4667 case Decl::ObjCInterface: {
4668 // There are two notions of a "definition" for an Objective-C
4669 // class: the interface and its implementation. When we resolved a
4670 // reference to an Objective-C class, produce the @interface as
4671 // the definition; when we were provided with the interface,
4672 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004673 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004675 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 return MakeCXCursor(Def, TU);
4677 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4678 return MakeCXCursor(Impl, TU);
4679 return clang_getNullCursor();
4680 }
4681
4682 case Decl::ObjCProperty:
4683 // FIXME: We don't really know where to find the
4684 // ObjCPropertyImplDecls that implement this property.
4685 return clang_getNullCursor();
4686
4687 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004688 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004690 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return MakeCXCursor(Def, TU);
4692
4693 return clang_getNullCursor();
4694
4695 case Decl::Friend:
4696 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4697 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4698 return clang_getNullCursor();
4699
4700 case Decl::FriendTemplate:
4701 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4702 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4703 return clang_getNullCursor();
4704 }
4705
4706 return clang_getNullCursor();
4707}
4708
4709unsigned clang_isCursorDefinition(CXCursor C) {
4710 if (!clang_isDeclaration(C.kind))
4711 return 0;
4712
4713 return clang_getCursorDefinition(C) == C;
4714}
4715
4716CXCursor clang_getCanonicalCursor(CXCursor C) {
4717 if (!clang_isDeclaration(C.kind))
4718 return C;
4719
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004720 if (const Decl *D = getCursorDecl(C)) {
4721 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4723 return MakeCXCursor(CatD, getCursorTU(C));
4724
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004725 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4726 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 return MakeCXCursor(IFD, getCursorTU(C));
4728
4729 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4730 }
4731
4732 return C;
4733}
4734
4735int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4736 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4737}
4738
4739unsigned clang_getNumOverloadedDecls(CXCursor C) {
4740 if (C.kind != CXCursor_OverloadedDeclRef)
4741 return 0;
4742
4743 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 return E->getNumDecls();
4746
4747 if (OverloadedTemplateStorage *S
4748 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4749 return S->size();
4750
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004751 const Decl *D = Storage.get<const Decl *>();
4752 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return Using->shadow_size();
4754
4755 return 0;
4756}
4757
4758CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4759 if (cursor.kind != CXCursor_OverloadedDeclRef)
4760 return clang_getNullCursor();
4761
4762 if (index >= clang_getNumOverloadedDecls(cursor))
4763 return clang_getNullCursor();
4764
4765 CXTranslationUnit TU = getCursorTU(cursor);
4766 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004767 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 return MakeCXCursor(E->decls_begin()[index], TU);
4769
4770 if (OverloadedTemplateStorage *S
4771 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4772 return MakeCXCursor(S->begin()[index], TU);
4773
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 const Decl *D = Storage.get<const Decl *>();
4775 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 // FIXME: This is, unfortunately, linear time.
4777 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4778 std::advance(Pos, index);
4779 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4780 }
4781
4782 return clang_getNullCursor();
4783}
4784
4785void clang_getDefinitionSpellingAndExtent(CXCursor C,
4786 const char **startBuf,
4787 const char **endBuf,
4788 unsigned *startLine,
4789 unsigned *startColumn,
4790 unsigned *endLine,
4791 unsigned *endColumn) {
4792 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004793 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4795
4796 SourceManager &SM = FD->getASTContext().getSourceManager();
4797 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4798 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4799 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4800 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4801 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4802 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4803}
4804
4805
4806CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4807 unsigned PieceIndex) {
4808 RefNamePieces Pieces;
4809
4810 switch (C.kind) {
4811 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004812 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4814 E->getQualifierLoc().getSourceRange());
4815 break;
4816
4817 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004818 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4820 E->getQualifierLoc().getSourceRange(),
4821 E->getOptionalExplicitTemplateArgs());
4822 break;
4823
4824 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004825 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004827 const Expr *Callee = OCE->getCallee();
4828 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 Callee = ICE->getSubExpr();
4830
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004831 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4833 DRE->getQualifierLoc().getSourceRange());
4834 }
4835 break;
4836
4837 default:
4838 break;
4839 }
4840
4841 if (Pieces.empty()) {
4842 if (PieceIndex == 0)
4843 return clang_getCursorExtent(C);
4844 } else if (PieceIndex < Pieces.size()) {
4845 SourceRange R = Pieces[PieceIndex];
4846 if (R.isValid())
4847 return cxloc::translateSourceRange(getCursorContext(C), R);
4848 }
4849
4850 return clang_getNullRange();
4851}
4852
4853void clang_enableStackTraces(void) {
4854 llvm::sys::PrintStackTraceOnErrorSignal();
4855}
4856
4857void clang_executeOnThread(void (*fn)(void*), void *user_data,
4858 unsigned stack_size) {
4859 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4860}
4861
4862} // end: extern "C"
4863
4864//===----------------------------------------------------------------------===//
4865// Token-based Operations.
4866//===----------------------------------------------------------------------===//
4867
4868/* CXToken layout:
4869 * int_data[0]: a CXTokenKind
4870 * int_data[1]: starting token location
4871 * int_data[2]: token length
4872 * int_data[3]: reserved
4873 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4874 * otherwise unused.
4875 */
4876extern "C" {
4877
4878CXTokenKind clang_getTokenKind(CXToken CXTok) {
4879 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4880}
4881
4882CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4883 switch (clang_getTokenKind(CXTok)) {
4884 case CXToken_Identifier:
4885 case CXToken_Keyword:
4886 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004887 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004888 ->getNameStart());
4889
4890 case CXToken_Literal: {
4891 // We have stashed the starting pointer in the ptr_data field. Use it.
4892 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004893 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 }
4895
4896 case CXToken_Punctuation:
4897 case CXToken_Comment:
4898 break;
4899 }
4900
4901 // We have to find the starting buffer pointer the hard way, by
4902 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004903 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004905 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004906
4907 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4908 std::pair<FileID, unsigned> LocInfo
4909 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4910 bool Invalid = false;
4911 StringRef Buffer
4912 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4913 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004914 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004915
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004916 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004917}
4918
4919CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004920 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 if (!CXXUnit)
4922 return clang_getNullLocation();
4923
4924 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4925 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4926}
4927
4928CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004929 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 if (!CXXUnit)
4931 return clang_getNullRange();
4932
4933 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4934 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4935}
4936
4937static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4938 SmallVectorImpl<CXToken> &CXTokens) {
4939 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4940 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004941 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004943 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004944
4945 // Cannot tokenize across files.
4946 if (BeginLocInfo.first != EndLocInfo.first)
4947 return;
4948
4949 // Create a lexer
4950 bool Invalid = false;
4951 StringRef Buffer
4952 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4953 if (Invalid)
4954 return;
4955
4956 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4957 CXXUnit->getASTContext().getLangOpts(),
4958 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4959 Lex.SetCommentRetentionState(true);
4960
4961 // Lex tokens until we hit the end of the range.
4962 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4963 Token Tok;
4964 bool previousWasAt = false;
4965 do {
4966 // Lex the next token
4967 Lex.LexFromRawLexer(Tok);
4968 if (Tok.is(tok::eof))
4969 break;
4970
4971 // Initialize the CXToken.
4972 CXToken CXTok;
4973
4974 // - Common fields
4975 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4976 CXTok.int_data[2] = Tok.getLength();
4977 CXTok.int_data[3] = 0;
4978
4979 // - Kind-specific fields
4980 if (Tok.isLiteral()) {
4981 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004982 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 } else if (Tok.is(tok::raw_identifier)) {
4984 // Lookup the identifier to determine whether we have a keyword.
4985 IdentifierInfo *II
4986 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4987
4988 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4989 CXTok.int_data[0] = CXToken_Keyword;
4990 }
4991 else {
4992 CXTok.int_data[0] = Tok.is(tok::identifier)
4993 ? CXToken_Identifier
4994 : CXToken_Keyword;
4995 }
4996 CXTok.ptr_data = II;
4997 } else if (Tok.is(tok::comment)) {
4998 CXTok.int_data[0] = CXToken_Comment;
4999 CXTok.ptr_data = 0;
5000 } else {
5001 CXTok.int_data[0] = CXToken_Punctuation;
5002 CXTok.ptr_data = 0;
5003 }
5004 CXTokens.push_back(CXTok);
5005 previousWasAt = Tok.is(tok::at);
5006 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5007}
5008
5009void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5010 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005011 LOG_FUNC_SECTION {
5012 *Log << TU << ' ' << Range;
5013 }
5014
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 if (Tokens)
5016 *Tokens = 0;
5017 if (NumTokens)
5018 *NumTokens = 0;
5019
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005020 if (!TU)
5021 return;
5022
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005023 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 if (!CXXUnit || !Tokens || !NumTokens)
5025 return;
5026
5027 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5028
5029 SourceRange R = cxloc::translateCXSourceRange(Range);
5030 if (R.isInvalid())
5031 return;
5032
5033 SmallVector<CXToken, 32> CXTokens;
5034 getTokens(CXXUnit, R, CXTokens);
5035
5036 if (CXTokens.empty())
5037 return;
5038
5039 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5040 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5041 *NumTokens = CXTokens.size();
5042}
5043
5044void clang_disposeTokens(CXTranslationUnit TU,
5045 CXToken *Tokens, unsigned NumTokens) {
5046 free(Tokens);
5047}
5048
5049} // end: extern "C"
5050
5051//===----------------------------------------------------------------------===//
5052// Token annotation APIs.
5053//===----------------------------------------------------------------------===//
5054
Guy Benyei11169dd2012-12-18 14:30:41 +00005055static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5056 CXCursor parent,
5057 CXClientData client_data);
5058static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5059 CXClientData client_data);
5060
5061namespace {
5062class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 CXToken *Tokens;
5064 CXCursor *Cursors;
5065 unsigned NumTokens;
5066 unsigned TokIdx;
5067 unsigned PreprocessingTokIdx;
5068 CursorVisitor AnnotateVis;
5069 SourceManager &SrcMgr;
5070 bool HasContextSensitiveKeywords;
5071
5072 struct PostChildrenInfo {
5073 CXCursor Cursor;
5074 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005075 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 unsigned BeforeChildrenTokenIdx;
5077 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005078 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005079
5080 CXToken &getTok(unsigned Idx) {
5081 assert(Idx < NumTokens);
5082 return Tokens[Idx];
5083 }
5084 const CXToken &getTok(unsigned Idx) const {
5085 assert(Idx < NumTokens);
5086 return Tokens[Idx];
5087 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 bool MoreTokens() const { return TokIdx < NumTokens; }
5089 unsigned NextToken() const { return TokIdx; }
5090 void AdvanceToken() { ++TokIdx; }
5091 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005092 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 }
5094 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005095 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 }
5097 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005098 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 }
5100
5101 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005102 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 SourceRange);
5104
5105public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005106 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005107 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005108 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005110 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 AnnotateTokensVisitor, this,
5112 /*VisitPreprocessorLast=*/true,
5113 /*VisitIncludedEntities=*/false,
5114 RegionOfInterest,
5115 /*VisitDeclsOnly=*/false,
5116 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005117 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 HasContextSensitiveKeywords(false) { }
5119
5120 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5121 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5122 bool postVisitChildren(CXCursor cursor);
5123 void AnnotateTokens();
5124
5125 /// \brief Determine whether the annotator saw any cursors that have
5126 /// context-sensitive keywords.
5127 bool hasContextSensitiveKeywords() const {
5128 return HasContextSensitiveKeywords;
5129 }
5130
5131 ~AnnotateTokensWorker() {
5132 assert(PostChildrenInfos.empty());
5133 }
5134};
5135}
5136
5137void AnnotateTokensWorker::AnnotateTokens() {
5138 // Walk the AST within the region of interest, annotating tokens
5139 // along the way.
5140 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005141}
Guy Benyei11169dd2012-12-18 14:30:41 +00005142
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005143static inline void updateCursorAnnotation(CXCursor &Cursor,
5144 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005145 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005147 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005148}
5149
5150/// \brief It annotates and advances tokens with a cursor until the comparison
5151//// between the cursor location and the source range is the same as
5152/// \arg compResult.
5153///
5154/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5155/// Pass RangeOverlap to annotate tokens inside a range.
5156void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5157 RangeComparisonResult compResult,
5158 SourceRange range) {
5159 while (MoreTokens()) {
5160 const unsigned I = NextToken();
5161 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005162 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5163 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005164
5165 SourceLocation TokLoc = GetTokenLoc(I);
5166 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005167 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 AdvanceToken();
5169 continue;
5170 }
5171 break;
5172 }
5173}
5174
5175/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005176/// \returns true if it advanced beyond all macro tokens, false otherwise.
5177bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 CXCursor updateC,
5179 RangeComparisonResult compResult,
5180 SourceRange range) {
5181 assert(MoreTokens());
5182 assert(isFunctionMacroToken(NextToken()) &&
5183 "Should be called only for macro arg tokens");
5184
5185 // This works differently than annotateAndAdvanceTokens; because expanded
5186 // macro arguments can have arbitrary translation-unit source order, we do not
5187 // advance the token index one by one until a token fails the range test.
5188 // We only advance once past all of the macro arg tokens if all of them
5189 // pass the range test. If one of them fails we keep the token index pointing
5190 // at the start of the macro arg tokens so that the failing token will be
5191 // annotated by a subsequent annotation try.
5192
5193 bool atLeastOneCompFail = false;
5194
5195 unsigned I = NextToken();
5196 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5197 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5198 if (TokLoc.isFileID())
5199 continue; // not macro arg token, it's parens or comma.
5200 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5201 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5202 Cursors[I] = updateC;
5203 } else
5204 atLeastOneCompFail = true;
5205 }
5206
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005207 if (atLeastOneCompFail)
5208 return false;
5209
5210 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5211 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005212}
5213
5214enum CXChildVisitResult
5215AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 SourceRange cursorRange = getRawCursorExtent(cursor);
5217 if (cursorRange.isInvalid())
5218 return CXChildVisit_Recurse;
5219
5220 if (!HasContextSensitiveKeywords) {
5221 // Objective-C properties can have context-sensitive keywords.
5222 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005223 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5225 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5226 }
5227 // Objective-C methods can have context-sensitive keywords.
5228 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5229 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005230 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5232 if (Method->getObjCDeclQualifier())
5233 HasContextSensitiveKeywords = true;
5234 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005235 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5236 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 P != PEnd; ++P) {
5238 if ((*P)->getObjCDeclQualifier()) {
5239 HasContextSensitiveKeywords = true;
5240 break;
5241 }
5242 }
5243 }
5244 }
5245 }
5246 // C++ methods can have context-sensitive keywords.
5247 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005248 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5250 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5251 HasContextSensitiveKeywords = true;
5252 }
5253 }
5254 // C++ classes can have context-sensitive keywords.
5255 else if (cursor.kind == CXCursor_StructDecl ||
5256 cursor.kind == CXCursor_ClassDecl ||
5257 cursor.kind == CXCursor_ClassTemplate ||
5258 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005259 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 if (D->hasAttr<FinalAttr>())
5261 HasContextSensitiveKeywords = true;
5262 }
5263 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005264
5265 // Don't override a property annotation with its getter/setter method.
5266 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5267 parent.kind == CXCursor_ObjCPropertyDecl)
5268 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005269
5270 if (clang_isPreprocessing(cursor.kind)) {
5271 // Items in the preprocessing record are kept separate from items in
5272 // declarations, so we keep a separate token index.
5273 unsigned SavedTokIdx = TokIdx;
5274 TokIdx = PreprocessingTokIdx;
5275
5276 // Skip tokens up until we catch up to the beginning of the preprocessing
5277 // entry.
5278 while (MoreTokens()) {
5279 const unsigned I = NextToken();
5280 SourceLocation TokLoc = GetTokenLoc(I);
5281 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5282 case RangeBefore:
5283 AdvanceToken();
5284 continue;
5285 case RangeAfter:
5286 case RangeOverlap:
5287 break;
5288 }
5289 break;
5290 }
5291
5292 // Look at all of the tokens within this range.
5293 while (MoreTokens()) {
5294 const unsigned I = NextToken();
5295 SourceLocation TokLoc = GetTokenLoc(I);
5296 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5297 case RangeBefore:
5298 llvm_unreachable("Infeasible");
5299 case RangeAfter:
5300 break;
5301 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005302 // For macro expansions, just note where the beginning of the macro
5303 // expansion occurs.
5304 if (cursor.kind == CXCursor_MacroExpansion) {
5305 if (TokLoc == cursorRange.getBegin())
5306 Cursors[I] = cursor;
5307 AdvanceToken();
5308 break;
5309 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005310 // We may have already annotated macro names inside macro definitions.
5311 if (Cursors[I].kind != CXCursor_MacroExpansion)
5312 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 continue;
5315 }
5316 break;
5317 }
5318
5319 // Save the preprocessing token index; restore the non-preprocessing
5320 // token index.
5321 PreprocessingTokIdx = TokIdx;
5322 TokIdx = SavedTokIdx;
5323 return CXChildVisit_Recurse;
5324 }
5325
5326 if (cursorRange.isInvalid())
5327 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005328
5329 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 const enum CXCursorKind K = clang_getCursorKind(parent);
5332 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005333 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5334 // Attributes are annotated out-of-order, skip tokens until we reach it.
5335 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 ? clang_getNullCursor() : parent;
5337
5338 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5339
5340 // Avoid having the cursor of an expression "overwrite" the annotation of the
5341 // variable declaration that it belongs to.
5342 // This can happen for C++ constructor expressions whose range generally
5343 // include the variable declaration, e.g.:
5344 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005345 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005346 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005347 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 const unsigned I = NextToken();
5349 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5350 E->getLocStart() == D->getLocation() &&
5351 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005352 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 AdvanceToken();
5354 }
5355 }
5356 }
5357
5358 // Before recursing into the children keep some state that we are going
5359 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5360 // extra work after the child nodes are visited.
5361 // Note that we don't call VisitChildren here to avoid traversing statements
5362 // code-recursively which can blow the stack.
5363
5364 PostChildrenInfo Info;
5365 Info.Cursor = cursor;
5366 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005367 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 Info.BeforeChildrenTokenIdx = NextToken();
5369 PostChildrenInfos.push_back(Info);
5370
5371 return CXChildVisit_Recurse;
5372}
5373
5374bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5375 if (PostChildrenInfos.empty())
5376 return false;
5377 const PostChildrenInfo &Info = PostChildrenInfos.back();
5378 if (!clang_equalCursors(Info.Cursor, cursor))
5379 return false;
5380
5381 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5382 const unsigned AfterChildren = NextToken();
5383 SourceRange cursorRange = Info.CursorRange;
5384
5385 // Scan the tokens that are at the end of the cursor, but are not captured
5386 // but the child cursors.
5387 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5388
5389 // Scan the tokens that are at the beginning of the cursor, but are not
5390 // capture by the child cursors.
5391 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5392 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5393 break;
5394
5395 Cursors[I] = cursor;
5396 }
5397
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005398 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5399 // encountered the attribute cursor.
5400 if (clang_isAttribute(cursor.kind))
5401 TokIdx = Info.BeforeReachingCursorIdx;
5402
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 PostChildrenInfos.pop_back();
5404 return false;
5405}
5406
5407static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5408 CXCursor parent,
5409 CXClientData client_data) {
5410 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5411}
5412
5413static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5414 CXClientData client_data) {
5415 return static_cast<AnnotateTokensWorker*>(client_data)->
5416 postVisitChildren(cursor);
5417}
5418
5419namespace {
5420
5421/// \brief Uses the macro expansions in the preprocessing record to find
5422/// and mark tokens that are macro arguments. This info is used by the
5423/// AnnotateTokensWorker.
5424class MarkMacroArgTokensVisitor {
5425 SourceManager &SM;
5426 CXToken *Tokens;
5427 unsigned NumTokens;
5428 unsigned CurIdx;
5429
5430public:
5431 MarkMacroArgTokensVisitor(SourceManager &SM,
5432 CXToken *tokens, unsigned numTokens)
5433 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5434
5435 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5436 if (cursor.kind != CXCursor_MacroExpansion)
5437 return CXChildVisit_Continue;
5438
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005439 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 if (macroRange.getBegin() == macroRange.getEnd())
5441 return CXChildVisit_Continue; // it's not a function macro.
5442
5443 for (; CurIdx < NumTokens; ++CurIdx) {
5444 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5445 macroRange.getBegin()))
5446 break;
5447 }
5448
5449 if (CurIdx == NumTokens)
5450 return CXChildVisit_Break;
5451
5452 for (; CurIdx < NumTokens; ++CurIdx) {
5453 SourceLocation tokLoc = getTokenLoc(CurIdx);
5454 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5455 break;
5456
5457 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5458 }
5459
5460 if (CurIdx == NumTokens)
5461 return CXChildVisit_Break;
5462
5463 return CXChildVisit_Continue;
5464 }
5465
5466private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005467 CXToken &getTok(unsigned Idx) {
5468 assert(Idx < NumTokens);
5469 return Tokens[Idx];
5470 }
5471 const CXToken &getTok(unsigned Idx) const {
5472 assert(Idx < NumTokens);
5473 return Tokens[Idx];
5474 }
5475
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005477 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 }
5479
5480 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5481 // The third field is reserved and currently not used. Use it here
5482 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005483 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 }
5485};
5486
5487} // end anonymous namespace
5488
5489static CXChildVisitResult
5490MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5491 CXClientData client_data) {
5492 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5493 parent);
5494}
5495
5496namespace {
5497 struct clang_annotateTokens_Data {
5498 CXTranslationUnit TU;
5499 ASTUnit *CXXUnit;
5500 CXToken *Tokens;
5501 unsigned NumTokens;
5502 CXCursor *Cursors;
5503 };
5504}
5505
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005506/// \brief Used by \c annotatePreprocessorTokens.
5507/// \returns true if lexing was finished, false otherwise.
5508static bool lexNext(Lexer &Lex, Token &Tok,
5509 unsigned &NextIdx, unsigned NumTokens) {
5510 if (NextIdx >= NumTokens)
5511 return true;
5512
5513 ++NextIdx;
5514 Lex.LexFromRawLexer(Tok);
5515 if (Tok.is(tok::eof))
5516 return true;
5517
5518 return false;
5519}
5520
Guy Benyei11169dd2012-12-18 14:30:41 +00005521static void annotatePreprocessorTokens(CXTranslationUnit TU,
5522 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005523 CXCursor *Cursors,
5524 CXToken *Tokens,
5525 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005526 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005527
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005528 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5530 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005531 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005533 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005534
5535 if (BeginLocInfo.first != EndLocInfo.first)
5536 return;
5537
5538 StringRef Buffer;
5539 bool Invalid = false;
5540 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5541 if (Buffer.empty() || Invalid)
5542 return;
5543
5544 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5545 CXXUnit->getASTContext().getLangOpts(),
5546 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5547 Buffer.end());
5548 Lex.SetCommentRetentionState(true);
5549
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005550 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005551 // Lex tokens in raw mode until we hit the end of the range, to avoid
5552 // entering #includes or expanding macros.
5553 while (true) {
5554 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005555 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5556 break;
5557 unsigned TokIdx = NextIdx-1;
5558 assert(Tok.getLocation() ==
5559 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005560
5561 reprocess:
5562 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005563 // We have found a preprocessing directive. Annotate the tokens
5564 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 //
5566 // FIXME: Some simple tests here could identify macro definitions and
5567 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005568
5569 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005570 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5571 break;
5572
5573 MacroInfo *MI = 0;
5574 if (Tok.is(tok::raw_identifier) &&
5575 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5576 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5577 break;
5578
5579 if (Tok.is(tok::raw_identifier)) {
5580 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5581 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5582 SourceLocation MappedTokLoc =
5583 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5584 MI = getMacroInfo(II, MappedTokLoc, TU);
5585 }
5586 }
5587
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005588 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005590 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5591 finished = true;
5592 break;
5593 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005594 // If we are in a macro definition, check if the token was ever a
5595 // macro name and annotate it if that's the case.
5596 if (MI) {
5597 SourceLocation SaveLoc = Tok.getLocation();
5598 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5599 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5600 Tok.setLocation(SaveLoc);
5601 if (MacroDef)
5602 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5603 Tok.getLocation(), TU);
5604 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005605 } while (!Tok.isAtStartOfLine());
5606
5607 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5608 assert(TokIdx <= LastIdx);
5609 SourceLocation EndLoc =
5610 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5611 CXCursor Cursor =
5612 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5613
5614 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005615 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005616
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005617 if (finished)
5618 break;
5619 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 }
5622}
5623
5624// This gets run a separate thread to avoid stack blowout.
5625static void clang_annotateTokensImpl(void *UserData) {
5626 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5627 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5628 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5629 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5630 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5631
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005632 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5634 setThreadBackgroundPriority();
5635
5636 // Determine the region of interest, which contains all of the tokens.
5637 SourceRange RegionOfInterest;
5638 RegionOfInterest.setBegin(
5639 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5640 RegionOfInterest.setEnd(
5641 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5642 Tokens[NumTokens-1])));
5643
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 // Relex the tokens within the source range to look for preprocessing
5645 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005646 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005647
5648 // If begin location points inside a macro argument, set it to the expansion
5649 // location so we can have the full context when annotating semantically.
5650 {
5651 SourceManager &SM = CXXUnit->getSourceManager();
5652 SourceLocation Loc =
5653 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5654 if (Loc.isMacroID())
5655 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5656 }
5657
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5659 // Search and mark tokens that are macro argument expansions.
5660 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5661 Tokens, NumTokens);
5662 CursorVisitor MacroArgMarker(TU,
5663 MarkMacroArgTokensVisitorDelegate, &Visitor,
5664 /*VisitPreprocessorLast=*/true,
5665 /*VisitIncludedEntities=*/false,
5666 RegionOfInterest);
5667 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5668 }
5669
5670 // Annotate all of the source locations in the region of interest that map to
5671 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005672 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005673
5674 // FIXME: We use a ridiculous stack size here because the data-recursion
5675 // algorithm uses a large stack frame than the non-data recursive version,
5676 // and AnnotationTokensWorker currently transforms the data-recursion
5677 // algorithm back into a traditional recursion by explicitly calling
5678 // VisitChildren(). We will need to remove this explicit recursive call.
5679 W.AnnotateTokens();
5680
5681 // If we ran into any entities that involve context-sensitive keywords,
5682 // take another pass through the tokens to mark them as such.
5683 if (W.hasContextSensitiveKeywords()) {
5684 for (unsigned I = 0; I != NumTokens; ++I) {
5685 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5686 continue;
5687
5688 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5689 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005690 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5692 if (Property->getPropertyAttributesAsWritten() != 0 &&
5693 llvm::StringSwitch<bool>(II->getName())
5694 .Case("readonly", true)
5695 .Case("assign", true)
5696 .Case("unsafe_unretained", true)
5697 .Case("readwrite", true)
5698 .Case("retain", true)
5699 .Case("copy", true)
5700 .Case("nonatomic", true)
5701 .Case("atomic", true)
5702 .Case("getter", true)
5703 .Case("setter", true)
5704 .Case("strong", true)
5705 .Case("weak", true)
5706 .Default(false))
5707 Tokens[I].int_data[0] = CXToken_Keyword;
5708 }
5709 continue;
5710 }
5711
5712 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5713 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5714 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5715 if (llvm::StringSwitch<bool>(II->getName())
5716 .Case("in", true)
5717 .Case("out", true)
5718 .Case("inout", true)
5719 .Case("oneway", true)
5720 .Case("bycopy", true)
5721 .Case("byref", true)
5722 .Default(false))
5723 Tokens[I].int_data[0] = CXToken_Keyword;
5724 continue;
5725 }
5726
5727 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5728 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5729 Tokens[I].int_data[0] = CXToken_Keyword;
5730 continue;
5731 }
5732 }
5733 }
5734}
5735
5736extern "C" {
5737
5738void clang_annotateTokens(CXTranslationUnit TU,
5739 CXToken *Tokens, unsigned NumTokens,
5740 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005741 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005742 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005744 }
5745
5746 LOG_FUNC_SECTION {
5747 *Log << TU << ' ';
5748 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5749 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5750 *Log << clang_getRange(bloc, eloc);
5751 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005752
5753 // Any token we don't specifically annotate will have a NULL cursor.
5754 CXCursor C = clang_getNullCursor();
5755 for (unsigned I = 0; I != NumTokens; ++I)
5756 Cursors[I] = C;
5757
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005758 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 if (!CXXUnit)
5760 return;
5761
5762 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5763
5764 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5765 llvm::CrashRecoveryContext CRC;
5766 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5767 GetSafetyThreadStackSize() * 2)) {
5768 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5769 }
5770}
5771
5772} // end: extern "C"
5773
5774//===----------------------------------------------------------------------===//
5775// Operations for querying linkage of a cursor.
5776//===----------------------------------------------------------------------===//
5777
5778extern "C" {
5779CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5780 if (!clang_isDeclaration(cursor.kind))
5781 return CXLinkage_Invalid;
5782
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005783 const Decl *D = cxcursor::getCursorDecl(cursor);
5784 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005785 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005786 case NoLinkage:
5787 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 case InternalLinkage: return CXLinkage_Internal;
5789 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5790 case ExternalLinkage: return CXLinkage_External;
5791 };
5792
5793 return CXLinkage_Invalid;
5794}
5795} // end: extern "C"
5796
5797//===----------------------------------------------------------------------===//
5798// Operations for querying language of a cursor.
5799//===----------------------------------------------------------------------===//
5800
5801static CXLanguageKind getDeclLanguage(const Decl *D) {
5802 if (!D)
5803 return CXLanguage_C;
5804
5805 switch (D->getKind()) {
5806 default:
5807 break;
5808 case Decl::ImplicitParam:
5809 case Decl::ObjCAtDefsField:
5810 case Decl::ObjCCategory:
5811 case Decl::ObjCCategoryImpl:
5812 case Decl::ObjCCompatibleAlias:
5813 case Decl::ObjCImplementation:
5814 case Decl::ObjCInterface:
5815 case Decl::ObjCIvar:
5816 case Decl::ObjCMethod:
5817 case Decl::ObjCProperty:
5818 case Decl::ObjCPropertyImpl:
5819 case Decl::ObjCProtocol:
5820 return CXLanguage_ObjC;
5821 case Decl::CXXConstructor:
5822 case Decl::CXXConversion:
5823 case Decl::CXXDestructor:
5824 case Decl::CXXMethod:
5825 case Decl::CXXRecord:
5826 case Decl::ClassTemplate:
5827 case Decl::ClassTemplatePartialSpecialization:
5828 case Decl::ClassTemplateSpecialization:
5829 case Decl::Friend:
5830 case Decl::FriendTemplate:
5831 case Decl::FunctionTemplate:
5832 case Decl::LinkageSpec:
5833 case Decl::Namespace:
5834 case Decl::NamespaceAlias:
5835 case Decl::NonTypeTemplateParm:
5836 case Decl::StaticAssert:
5837 case Decl::TemplateTemplateParm:
5838 case Decl::TemplateTypeParm:
5839 case Decl::UnresolvedUsingTypename:
5840 case Decl::UnresolvedUsingValue:
5841 case Decl::Using:
5842 case Decl::UsingDirective:
5843 case Decl::UsingShadow:
5844 return CXLanguage_CPlusPlus;
5845 }
5846
5847 return CXLanguage_C;
5848}
5849
5850extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005851
5852static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5853 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5854 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005855
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005856 switch (D->getAvailability()) {
5857 case AR_Available:
5858 case AR_NotYetIntroduced:
5859 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005860 return getCursorAvailabilityForDecl(
5861 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005862 return CXAvailability_Available;
5863
5864 case AR_Deprecated:
5865 return CXAvailability_Deprecated;
5866
5867 case AR_Unavailable:
5868 return CXAvailability_NotAvailable;
5869 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005870
5871 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005872}
5873
Guy Benyei11169dd2012-12-18 14:30:41 +00005874enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5875 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005876 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5877 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005878
5879 return CXAvailability_Available;
5880}
5881
5882static CXVersion convertVersion(VersionTuple In) {
5883 CXVersion Out = { -1, -1, -1 };
5884 if (In.empty())
5885 return Out;
5886
5887 Out.Major = In.getMajor();
5888
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005889 Optional<unsigned> Minor = In.getMinor();
5890 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 Out.Minor = *Minor;
5892 else
5893 return Out;
5894
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005895 Optional<unsigned> Subminor = In.getSubminor();
5896 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005897 Out.Subminor = *Subminor;
5898
5899 return Out;
5900}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005901
5902static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5903 int *always_deprecated,
5904 CXString *deprecated_message,
5905 int *always_unavailable,
5906 CXString *unavailable_message,
5907 CXPlatformAvailability *availability,
5908 int availability_size) {
5909 bool HadAvailAttr = false;
5910 int N = 0;
5911 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5912 ++A) {
5913 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5914 HadAvailAttr = true;
5915 if (always_deprecated)
5916 *always_deprecated = 1;
5917 if (deprecated_message)
5918 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5919 continue;
5920 }
5921
5922 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5923 HadAvailAttr = true;
5924 if (always_unavailable)
5925 *always_unavailable = 1;
5926 if (unavailable_message) {
5927 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5928 }
5929 continue;
5930 }
5931
5932 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5933 HadAvailAttr = true;
5934 if (N < availability_size) {
5935 availability[N].Platform
5936 = cxstring::createDup(Avail->getPlatform()->getName());
5937 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5938 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5939 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5940 availability[N].Unavailable = Avail->getUnavailable();
5941 availability[N].Message = cxstring::createDup(Avail->getMessage());
5942 }
5943 ++N;
5944 }
5945 }
5946
5947 if (!HadAvailAttr)
5948 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5949 return getCursorPlatformAvailabilityForDecl(
5950 cast<Decl>(EnumConst->getDeclContext()),
5951 always_deprecated,
5952 deprecated_message,
5953 always_unavailable,
5954 unavailable_message,
5955 availability,
5956 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005957
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005958 return N;
5959}
5960
Guy Benyei11169dd2012-12-18 14:30:41 +00005961int clang_getCursorPlatformAvailability(CXCursor cursor,
5962 int *always_deprecated,
5963 CXString *deprecated_message,
5964 int *always_unavailable,
5965 CXString *unavailable_message,
5966 CXPlatformAvailability *availability,
5967 int availability_size) {
5968 if (always_deprecated)
5969 *always_deprecated = 0;
5970 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005971 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 if (always_unavailable)
5973 *always_unavailable = 0;
5974 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005975 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005976
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 if (!clang_isDeclaration(cursor.kind))
5978 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005979
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005980 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 if (!D)
5982 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005983
5984 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5985 deprecated_message,
5986 always_unavailable,
5987 unavailable_message,
5988 availability,
5989 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005990}
5991
5992void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5993 clang_disposeString(availability->Platform);
5994 clang_disposeString(availability->Message);
5995}
5996
5997CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5998 if (clang_isDeclaration(cursor.kind))
5999 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6000
6001 return CXLanguage_Invalid;
6002}
6003
6004 /// \brief If the given cursor is the "templated" declaration
6005 /// descibing a class or function template, return the class or
6006 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006007static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 if (!D)
6009 return 0;
6010
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006011 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6013 return FunTmpl;
6014
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006015 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6017 return ClassTmpl;
6018
6019 return D;
6020}
6021
6022CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6023 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006024 if (const Decl *D = getCursorDecl(cursor)) {
6025 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 if (!DC)
6027 return clang_getNullCursor();
6028
6029 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6030 getCursorTU(cursor));
6031 }
6032 }
6033
6034 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006035 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 return MakeCXCursor(D, getCursorTU(cursor));
6037 }
6038
6039 return clang_getNullCursor();
6040}
6041
6042CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6043 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006044 if (const Decl *D = getCursorDecl(cursor)) {
6045 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006046 if (!DC)
6047 return clang_getNullCursor();
6048
6049 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6050 getCursorTU(cursor));
6051 }
6052 }
6053
6054 // FIXME: Note that we can't easily compute the lexical context of a
6055 // statement or expression, so we return nothing.
6056 return clang_getNullCursor();
6057}
6058
6059CXFile clang_getIncludedFile(CXCursor cursor) {
6060 if (cursor.kind != CXCursor_InclusionDirective)
6061 return 0;
6062
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006063 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006064 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006065}
6066
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006067unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6068 if (C.kind != CXCursor_ObjCPropertyDecl)
6069 return CXObjCPropertyAttr_noattr;
6070
6071 unsigned Result = CXObjCPropertyAttr_noattr;
6072 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6073 ObjCPropertyDecl::PropertyAttributeKind Attr =
6074 PD->getPropertyAttributesAsWritten();
6075
6076#define SET_CXOBJCPROP_ATTR(A) \
6077 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6078 Result |= CXObjCPropertyAttr_##A
6079 SET_CXOBJCPROP_ATTR(readonly);
6080 SET_CXOBJCPROP_ATTR(getter);
6081 SET_CXOBJCPROP_ATTR(assign);
6082 SET_CXOBJCPROP_ATTR(readwrite);
6083 SET_CXOBJCPROP_ATTR(retain);
6084 SET_CXOBJCPROP_ATTR(copy);
6085 SET_CXOBJCPROP_ATTR(nonatomic);
6086 SET_CXOBJCPROP_ATTR(setter);
6087 SET_CXOBJCPROP_ATTR(atomic);
6088 SET_CXOBJCPROP_ATTR(weak);
6089 SET_CXOBJCPROP_ATTR(strong);
6090 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6091#undef SET_CXOBJCPROP_ATTR
6092
6093 return Result;
6094}
6095
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006096unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6097 if (!clang_isDeclaration(C.kind))
6098 return CXObjCDeclQualifier_None;
6099
6100 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6101 const Decl *D = getCursorDecl(C);
6102 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6103 QT = MD->getObjCDeclQualifier();
6104 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6105 QT = PD->getObjCDeclQualifier();
6106 if (QT == Decl::OBJC_TQ_None)
6107 return CXObjCDeclQualifier_None;
6108
6109 unsigned Result = CXObjCDeclQualifier_None;
6110 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6111 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6112 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6113 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6114 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6115 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6116
6117 return Result;
6118}
6119
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006120unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6121 if (!clang_isDeclaration(C.kind))
6122 return 0;
6123
6124 const Decl *D = getCursorDecl(C);
6125 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6126 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6127 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6128 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6129
6130 return 0;
6131}
6132
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006133unsigned clang_Cursor_isVariadic(CXCursor C) {
6134 if (!clang_isDeclaration(C.kind))
6135 return 0;
6136
6137 const Decl *D = getCursorDecl(C);
6138 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6139 return FD->isVariadic();
6140 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6141 return MD->isVariadic();
6142
6143 return 0;
6144}
6145
Guy Benyei11169dd2012-12-18 14:30:41 +00006146CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6147 if (!clang_isDeclaration(C.kind))
6148 return clang_getNullRange();
6149
6150 const Decl *D = getCursorDecl(C);
6151 ASTContext &Context = getCursorContext(C);
6152 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6153 if (!RC)
6154 return clang_getNullRange();
6155
6156 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6157}
6158
6159CXString clang_Cursor_getRawCommentText(CXCursor C) {
6160 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006161 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006162
6163 const Decl *D = getCursorDecl(C);
6164 ASTContext &Context = getCursorContext(C);
6165 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6166 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6167 StringRef();
6168
6169 // Don't duplicate the string because RawText points directly into source
6170 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006171 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006172}
6173
6174CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6175 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006176 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006177
6178 const Decl *D = getCursorDecl(C);
6179 const ASTContext &Context = getCursorContext(C);
6180 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6181
6182 if (RC) {
6183 StringRef BriefText = RC->getBriefText(Context);
6184
6185 // Don't duplicate the string because RawComment ensures that this memory
6186 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006187 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 }
6189
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006190 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006191}
6192
6193CXComment clang_Cursor_getParsedComment(CXCursor C) {
6194 if (!clang_isDeclaration(C.kind))
6195 return cxcomment::createCXComment(NULL, NULL);
6196
6197 const Decl *D = getCursorDecl(C);
6198 const ASTContext &Context = getCursorContext(C);
6199 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6200
6201 return cxcomment::createCXComment(FC, getCursorTU(C));
6202}
6203
6204CXModule clang_Cursor_getModule(CXCursor C) {
6205 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006206 if (const ImportDecl *ImportD =
6207 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006208 return ImportD->getImportedModule();
6209 }
6210
6211 return 0;
6212}
6213
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006214CXFile clang_Module_getASTFile(CXModule CXMod) {
6215 if (!CXMod)
6216 return 0;
6217 Module *Mod = static_cast<Module*>(CXMod);
6218 return const_cast<FileEntry *>(Mod->getASTFile());
6219}
6220
Guy Benyei11169dd2012-12-18 14:30:41 +00006221CXModule clang_Module_getParent(CXModule CXMod) {
6222 if (!CXMod)
6223 return 0;
6224 Module *Mod = static_cast<Module*>(CXMod);
6225 return Mod->Parent;
6226}
6227
6228CXString clang_Module_getName(CXModule CXMod) {
6229 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006230 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006232 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006233}
6234
6235CXString clang_Module_getFullName(CXModule CXMod) {
6236 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006237 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006238 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006239 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006240}
6241
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006242unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6243 CXModule CXMod) {
6244 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 return 0;
6246 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006247 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6248 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6249 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006250}
6251
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006252CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6253 CXModule CXMod, unsigned Index) {
6254 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006255 return 0;
6256 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006257 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006258
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006259 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6260 if (Index < TopHeaders.size())
6261 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006262
6263 return 0;
6264}
6265
6266} // end: extern "C"
6267
6268//===----------------------------------------------------------------------===//
6269// C++ AST instrospection.
6270//===----------------------------------------------------------------------===//
6271
6272extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006273unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6274 if (!clang_isDeclaration(C.kind))
6275 return 0;
6276
6277 const CXXMethodDecl *Method = 0;
6278 const Decl *D = cxcursor::getCursorDecl(C);
6279 if (const FunctionTemplateDecl *FunTmpl =
6280 dyn_cast_or_null<FunctionTemplateDecl>(D))
6281 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6282 else
6283 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6284 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6285}
6286
Guy Benyei11169dd2012-12-18 14:30:41 +00006287unsigned clang_CXXMethod_isStatic(CXCursor C) {
6288 if (!clang_isDeclaration(C.kind))
6289 return 0;
6290
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006291 const CXXMethodDecl *Method = 0;
6292 const Decl *D = cxcursor::getCursorDecl(C);
6293 if (const FunctionTemplateDecl *FunTmpl =
6294 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006295 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6296 else
6297 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6298 return (Method && Method->isStatic()) ? 1 : 0;
6299}
6300
6301unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6302 if (!clang_isDeclaration(C.kind))
6303 return 0;
6304
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006305 const CXXMethodDecl *Method = 0;
6306 const Decl *D = cxcursor::getCursorDecl(C);
6307 if (const FunctionTemplateDecl *FunTmpl =
6308 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6310 else
6311 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6312 return (Method && Method->isVirtual()) ? 1 : 0;
6313}
6314} // end: extern "C"
6315
6316//===----------------------------------------------------------------------===//
6317// Attribute introspection.
6318//===----------------------------------------------------------------------===//
6319
6320extern "C" {
6321CXType clang_getIBOutletCollectionType(CXCursor C) {
6322 if (C.kind != CXCursor_IBOutletCollectionAttr)
6323 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6324
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006325 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006326 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6327
6328 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6329}
6330} // end: extern "C"
6331
6332//===----------------------------------------------------------------------===//
6333// Inspecting memory usage.
6334//===----------------------------------------------------------------------===//
6335
6336typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6337
6338static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6339 enum CXTUResourceUsageKind k,
6340 unsigned long amount) {
6341 CXTUResourceUsageEntry entry = { k, amount };
6342 entries.push_back(entry);
6343}
6344
6345extern "C" {
6346
6347const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6348 const char *str = "";
6349 switch (kind) {
6350 case CXTUResourceUsage_AST:
6351 str = "ASTContext: expressions, declarations, and types";
6352 break;
6353 case CXTUResourceUsage_Identifiers:
6354 str = "ASTContext: identifiers";
6355 break;
6356 case CXTUResourceUsage_Selectors:
6357 str = "ASTContext: selectors";
6358 break;
6359 case CXTUResourceUsage_GlobalCompletionResults:
6360 str = "Code completion: cached global results";
6361 break;
6362 case CXTUResourceUsage_SourceManagerContentCache:
6363 str = "SourceManager: content cache allocator";
6364 break;
6365 case CXTUResourceUsage_AST_SideTables:
6366 str = "ASTContext: side tables";
6367 break;
6368 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6369 str = "SourceManager: malloc'ed memory buffers";
6370 break;
6371 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6372 str = "SourceManager: mmap'ed memory buffers";
6373 break;
6374 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6375 str = "ExternalASTSource: malloc'ed memory buffers";
6376 break;
6377 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6378 str = "ExternalASTSource: mmap'ed memory buffers";
6379 break;
6380 case CXTUResourceUsage_Preprocessor:
6381 str = "Preprocessor: malloc'ed memory";
6382 break;
6383 case CXTUResourceUsage_PreprocessingRecord:
6384 str = "Preprocessor: PreprocessingRecord";
6385 break;
6386 case CXTUResourceUsage_SourceManager_DataStructures:
6387 str = "SourceManager: data structures and tables";
6388 break;
6389 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6390 str = "Preprocessor: header search tables";
6391 break;
6392 }
6393 return str;
6394}
6395
6396CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6397 if (!TU) {
6398 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6399 return usage;
6400 }
6401
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006402 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6404 ASTContext &astContext = astUnit->getASTContext();
6405
6406 // How much memory is used by AST nodes and types?
6407 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6408 (unsigned long) astContext.getASTAllocatedMemory());
6409
6410 // How much memory is used by identifiers?
6411 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6412 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6413
6414 // How much memory is used for selectors?
6415 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6416 (unsigned long) astContext.Selectors.getTotalMemory());
6417
6418 // How much memory is used by ASTContext's side tables?
6419 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6420 (unsigned long) astContext.getSideTableAllocatedMemory());
6421
6422 // How much memory is used for caching global code completion results?
6423 unsigned long completionBytes = 0;
6424 if (GlobalCodeCompletionAllocator *completionAllocator =
6425 astUnit->getCachedCompletionAllocator().getPtr()) {
6426 completionBytes = completionAllocator->getTotalMemory();
6427 }
6428 createCXTUResourceUsageEntry(*entries,
6429 CXTUResourceUsage_GlobalCompletionResults,
6430 completionBytes);
6431
6432 // How much memory is being used by SourceManager's content cache?
6433 createCXTUResourceUsageEntry(*entries,
6434 CXTUResourceUsage_SourceManagerContentCache,
6435 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6436
6437 // How much memory is being used by the MemoryBuffer's in SourceManager?
6438 const SourceManager::MemoryBufferSizes &srcBufs =
6439 astUnit->getSourceManager().getMemoryBufferSizes();
6440
6441 createCXTUResourceUsageEntry(*entries,
6442 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6443 (unsigned long) srcBufs.malloc_bytes);
6444 createCXTUResourceUsageEntry(*entries,
6445 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6446 (unsigned long) srcBufs.mmap_bytes);
6447 createCXTUResourceUsageEntry(*entries,
6448 CXTUResourceUsage_SourceManager_DataStructures,
6449 (unsigned long) astContext.getSourceManager()
6450 .getDataStructureSizes());
6451
6452 // How much memory is being used by the ExternalASTSource?
6453 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6454 const ExternalASTSource::MemoryBufferSizes &sizes =
6455 esrc->getMemoryBufferSizes();
6456
6457 createCXTUResourceUsageEntry(*entries,
6458 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6459 (unsigned long) sizes.malloc_bytes);
6460 createCXTUResourceUsageEntry(*entries,
6461 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6462 (unsigned long) sizes.mmap_bytes);
6463 }
6464
6465 // How much memory is being used by the Preprocessor?
6466 Preprocessor &pp = astUnit->getPreprocessor();
6467 createCXTUResourceUsageEntry(*entries,
6468 CXTUResourceUsage_Preprocessor,
6469 pp.getTotalMemory());
6470
6471 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6472 createCXTUResourceUsageEntry(*entries,
6473 CXTUResourceUsage_PreprocessingRecord,
6474 pRec->getTotalMemory());
6475 }
6476
6477 createCXTUResourceUsageEntry(*entries,
6478 CXTUResourceUsage_Preprocessor_HeaderSearch,
6479 pp.getHeaderSearchInfo().getTotalMemory());
6480
6481 CXTUResourceUsage usage = { (void*) entries.get(),
6482 (unsigned) entries->size(),
6483 entries->size() ? &(*entries)[0] : 0 };
6484 entries.take();
6485 return usage;
6486}
6487
6488void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6489 if (usage.data)
6490 delete (MemUsageEntries*) usage.data;
6491}
6492
6493} // end extern "C"
6494
6495void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6496 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6497 for (unsigned I = 0; I != Usage.numEntries; ++I)
6498 fprintf(stderr, " %s: %lu\n",
6499 clang_getTUResourceUsageName(Usage.entries[I].kind),
6500 Usage.entries[I].amount);
6501
6502 clang_disposeCXTUResourceUsage(Usage);
6503}
6504
6505//===----------------------------------------------------------------------===//
6506// Misc. utility functions.
6507//===----------------------------------------------------------------------===//
6508
6509/// Default to using an 8 MB stack size on "safety" threads.
6510static unsigned SafetyStackThreadSize = 8 << 20;
6511
6512namespace clang {
6513
6514bool RunSafely(llvm::CrashRecoveryContext &CRC,
6515 void (*Fn)(void*), void *UserData,
6516 unsigned Size) {
6517 if (!Size)
6518 Size = GetSafetyThreadStackSize();
6519 if (Size)
6520 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6521 return CRC.RunSafely(Fn, UserData);
6522}
6523
6524unsigned GetSafetyThreadStackSize() {
6525 return SafetyStackThreadSize;
6526}
6527
6528void SetSafetyThreadStackSize(unsigned Value) {
6529 SafetyStackThreadSize = Value;
6530}
6531
6532}
6533
6534void clang::setThreadBackgroundPriority() {
6535 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6536 return;
6537
6538 // FIXME: Move to llvm/Support and make it cross-platform.
6539#ifdef __APPLE__
6540 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6541#endif
6542}
6543
6544void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6545 if (!Unit)
6546 return;
6547
6548 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6549 DEnd = Unit->stored_diag_end();
6550 D != DEnd; ++D) {
6551 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6552 CXString Msg = clang_formatDiagnostic(&Diag,
6553 clang_defaultDiagnosticDisplayOptions());
6554 fprintf(stderr, "%s\n", clang_getCString(Msg));
6555 clang_disposeString(Msg);
6556 }
6557#ifdef LLVM_ON_WIN32
6558 // On Windows, force a flush, since there may be multiple copies of
6559 // stderr and stdout in the file system, all with different buffers
6560 // but writing to the same device.
6561 fflush(stderr);
6562#endif
6563}
6564
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006565MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6566 SourceLocation MacroDefLoc,
6567 CXTranslationUnit TU){
6568 if (MacroDefLoc.isInvalid() || !TU)
6569 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006570 if (!II.hadMacroDefinition())
6571 return 0;
6572
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006573 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006574 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006575 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006576 if (MD) {
6577 for (MacroDirective::DefInfo
6578 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6579 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6580 return Def.getMacroInfo();
6581 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006582 }
6583
6584 return 0;
6585}
6586
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006587const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6588 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006589 if (!MacroDef || !TU)
6590 return 0;
6591 const IdentifierInfo *II = MacroDef->getName();
6592 if (!II)
6593 return 0;
6594
6595 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6596}
6597
6598MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6599 const Token &Tok,
6600 CXTranslationUnit TU) {
6601 if (!MI || !TU)
6602 return 0;
6603 if (Tok.isNot(tok::raw_identifier))
6604 return 0;
6605
6606 if (MI->getNumTokens() == 0)
6607 return 0;
6608 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6609 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006610 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006611
6612 // Check that the token is inside the definition and not its argument list.
6613 SourceManager &SM = Unit->getSourceManager();
6614 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6615 return 0;
6616 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6617 return 0;
6618
6619 Preprocessor &PP = Unit->getPreprocessor();
6620 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6621 if (!PPRec)
6622 return 0;
6623
6624 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6625 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6626 if (!II.hadMacroDefinition())
6627 return 0;
6628
6629 // Check that the identifier is not one of the macro arguments.
6630 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6631 return 0;
6632
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006633 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6634 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006635 return 0;
6636
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006637 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006638}
6639
6640MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6641 SourceLocation Loc,
6642 CXTranslationUnit TU) {
6643 if (Loc.isInvalid() || !MI || !TU)
6644 return 0;
6645
6646 if (MI->getNumTokens() == 0)
6647 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006648 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006649 Preprocessor &PP = Unit->getPreprocessor();
6650 if (!PP.getPreprocessingRecord())
6651 return 0;
6652 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6653 Token Tok;
6654 if (PP.getRawToken(Loc, Tok))
6655 return 0;
6656
6657 return checkForMacroInMacroDefinition(MI, Tok, TU);
6658}
6659
Guy Benyei11169dd2012-12-18 14:30:41 +00006660extern "C" {
6661
6662CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006663 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006664}
6665
6666} // end: extern "C"
6667
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006668Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6669 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006670 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006671 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006672 if (Unit->isMainFileAST())
6673 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006674 return *this;
6675 }
6676 }
6677
6678 LogOS << "<NULL TU>";
6679 return *this;
6680}
6681
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006682Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6683 *this << FE->getName();
6684 return *this;
6685}
6686
6687Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6688 CXString cursorName = clang_getCursorDisplayName(cursor);
6689 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6690 clang_disposeString(cursorName);
6691 return *this;
6692}
6693
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006694Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6695 CXFile File;
6696 unsigned Line, Column;
6697 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6698 CXString FileName = clang_getFileName(File);
6699 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6700 clang_disposeString(FileName);
6701 return *this;
6702}
6703
6704Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6705 CXSourceLocation BLoc = clang_getRangeStart(range);
6706 CXSourceLocation ELoc = clang_getRangeEnd(range);
6707
6708 CXFile BFile;
6709 unsigned BLine, BColumn;
6710 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6711
6712 CXFile EFile;
6713 unsigned ELine, EColumn;
6714 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6715
6716 CXString BFileName = clang_getFileName(BFile);
6717 if (BFile == EFile) {
6718 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6719 BLine, BColumn, ELine, EColumn);
6720 } else {
6721 CXString EFileName = clang_getFileName(EFile);
6722 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6723 BLine, BColumn)
6724 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6725 ELine, EColumn);
6726 clang_disposeString(EFileName);
6727 }
6728 clang_disposeString(BFileName);
6729 return *this;
6730}
6731
6732Logger &cxindex::Logger::operator<<(CXString Str) {
6733 *this << clang_getCString(Str);
6734 return *this;
6735}
6736
6737Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6738 LogOS << Fmt;
6739 return *this;
6740}
6741
6742cxindex::Logger::~Logger() {
6743 LogOS.flush();
6744
6745 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6746
6747 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6748
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006749 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006750 OS << "[libclang:" << Name << ':';
6751
6752 // FIXME: Portability.
6753#if HAVE_PTHREAD_H && __APPLE__
6754 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6755 OS << tid << ':';
6756#endif
6757
6758 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6759 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6760 OS << Msg.str() << '\n';
6761
6762 if (Trace) {
6763 llvm::sys::PrintStackTrace(stderr);
6764 OS << "--------------------------------------------------\n";
6765 }
6766}