blob: f53e5c1c4951e61036f02125bc5be3384b56eea0 [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.
2547 llvm::CrashRecoveryContext::Enable();
2548
2549 // Enable support for multithreading in LLVM.
2550 {
2551 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2552 if (!EnabledMultithreading) {
2553 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2554 llvm::llvm_start_multithreaded();
2555 EnabledMultithreading = true;
2556 }
2557 }
2558
2559 CIndexer *CIdxr = new CIndexer();
2560 if (excludeDeclarationsFromPCH)
2561 CIdxr->setOnlyLocalDecls();
2562 if (displayDiagnostics)
2563 CIdxr->setDisplayDiagnostics();
2564
2565 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2566 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2567 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2568 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2569 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2570 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2571
2572 return CIdxr;
2573}
2574
2575void clang_disposeIndex(CXIndex CIdx) {
2576 if (CIdx)
2577 delete static_cast<CIndexer *>(CIdx);
2578}
2579
2580void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2581 if (CIdx)
2582 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2583}
2584
2585unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2586 if (CIdx)
2587 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2588 return 0;
2589}
2590
2591void clang_toggleCrashRecovery(unsigned isEnabled) {
2592 if (isEnabled)
2593 llvm::CrashRecoveryContext::Enable();
2594 else
2595 llvm::CrashRecoveryContext::Disable();
2596}
2597
2598CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2599 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002600 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 return 0;
2602
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002603 LOG_FUNC_SECTION {
2604 *Log << ast_filename;
2605 }
2606
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2608 FileSystemOptions FileSystemOpts;
2609
2610 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2611 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2612 CXXIdx->getOnlyLocalDecls(),
2613 0, 0,
2614 /*CaptureDiagnostics=*/true,
2615 /*AllowPCHWithCompilerErrors=*/true,
2616 /*UserFilesAreVolatile=*/true);
2617 return MakeCXTranslationUnit(CXXIdx, TU);
2618}
2619
2620unsigned clang_defaultEditingTranslationUnitOptions() {
2621 return CXTranslationUnit_PrecompiledPreamble |
2622 CXTranslationUnit_CacheCompletionResults;
2623}
2624
2625CXTranslationUnit
2626clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2627 const char *source_filename,
2628 int num_command_line_args,
2629 const char * const *command_line_args,
2630 unsigned num_unsaved_files,
2631 struct CXUnsavedFile *unsaved_files) {
2632 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2633 return clang_parseTranslationUnit(CIdx, source_filename,
2634 command_line_args, num_command_line_args,
2635 unsaved_files, num_unsaved_files,
2636 Options);
2637}
2638
2639struct ParseTranslationUnitInfo {
2640 CXIndex CIdx;
2641 const char *source_filename;
2642 const char *const *command_line_args;
2643 int num_command_line_args;
2644 struct CXUnsavedFile *unsaved_files;
2645 unsigned num_unsaved_files;
2646 unsigned options;
2647 CXTranslationUnit result;
2648};
2649static void clang_parseTranslationUnit_Impl(void *UserData) {
2650 ParseTranslationUnitInfo *PTUI =
2651 static_cast<ParseTranslationUnitInfo*>(UserData);
2652 CXIndex CIdx = PTUI->CIdx;
2653 const char *source_filename = PTUI->source_filename;
2654 const char * const *command_line_args = PTUI->command_line_args;
2655 int num_command_line_args = PTUI->num_command_line_args;
2656 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2657 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2658 unsigned options = PTUI->options;
2659 PTUI->result = 0;
2660
2661 if (!CIdx)
2662 return;
2663
2664 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2665
2666 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2667 setThreadBackgroundPriority();
2668
2669 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2670 // FIXME: Add a flag for modules.
2671 TranslationUnitKind TUKind
2672 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2673 bool CacheCodeCompetionResults
2674 = options & CXTranslationUnit_CacheCompletionResults;
2675 bool IncludeBriefCommentsInCodeCompletion
2676 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2677 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2678 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2679
2680 // Configure the diagnostics.
2681 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002682 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002683
2684 // Recover resources if we crash before exiting this function.
2685 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2686 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2687 DiagCleanup(Diags.getPtr());
2688
2689 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2690 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2691
2692 // Recover resources if we crash before exiting this function.
2693 llvm::CrashRecoveryContextCleanupRegistrar<
2694 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2695
2696 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2697 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2698 const llvm::MemoryBuffer *Buffer
2699 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2700 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2701 Buffer));
2702 }
2703
2704 OwningPtr<std::vector<const char *> >
2705 Args(new std::vector<const char*>());
2706
2707 // Recover resources if we crash before exiting this method.
2708 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2709 ArgsCleanup(Args.get());
2710
2711 // Since the Clang C library is primarily used by batch tools dealing with
2712 // (often very broken) source code, where spell-checking can have a
2713 // significant negative impact on performance (particularly when
2714 // precompiled headers are involved), we disable it by default.
2715 // Only do this if we haven't found a spell-checking-related argument.
2716 bool FoundSpellCheckingArgument = false;
2717 for (int I = 0; I != num_command_line_args; ++I) {
2718 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2719 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2720 FoundSpellCheckingArgument = true;
2721 break;
2722 }
2723 }
2724 if (!FoundSpellCheckingArgument)
2725 Args->push_back("-fno-spell-checking");
2726
2727 Args->insert(Args->end(), command_line_args,
2728 command_line_args + num_command_line_args);
2729
2730 // The 'source_filename' argument is optional. If the caller does not
2731 // specify it then it is assumed that the source file is specified
2732 // in the actual argument list.
2733 // Put the source file after command_line_args otherwise if '-x' flag is
2734 // present it will be unused.
2735 if (source_filename)
2736 Args->push_back(source_filename);
2737
2738 // Do we need the detailed preprocessing record?
2739 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2740 Args->push_back("-Xclang");
2741 Args->push_back("-detailed-preprocessing-record");
2742 }
2743
2744 unsigned NumErrors = Diags->getClient()->getNumErrors();
2745 OwningPtr<ASTUnit> ErrUnit;
2746 OwningPtr<ASTUnit> Unit(
2747 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2748 /* vector::data() not portable */,
2749 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2750 Diags,
2751 CXXIdx->getClangResourcesPath(),
2752 CXXIdx->getOnlyLocalDecls(),
2753 /*CaptureDiagnostics=*/true,
2754 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2755 RemappedFiles->size(),
2756 /*RemappedFilesKeepOriginalName=*/true,
2757 PrecompilePreamble,
2758 TUKind,
2759 CacheCodeCompetionResults,
2760 IncludeBriefCommentsInCodeCompletion,
2761 /*AllowPCHWithCompilerErrors=*/true,
2762 SkipFunctionBodies,
2763 /*UserFilesAreVolatile=*/true,
2764 ForSerialization,
2765 &ErrUnit));
2766
2767 if (NumErrors != Diags->getClient()->getNumErrors()) {
2768 // Make sure to check that 'Unit' is non-NULL.
2769 if (CXXIdx->getDisplayDiagnostics())
2770 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2771 }
2772
2773 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2774}
2775CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2776 const char *source_filename,
2777 const char * const *command_line_args,
2778 int num_command_line_args,
2779 struct CXUnsavedFile *unsaved_files,
2780 unsigned num_unsaved_files,
2781 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002782 LOG_FUNC_SECTION {
2783 *Log << source_filename << ": ";
2784 for (int i = 0; i != num_command_line_args; ++i)
2785 *Log << command_line_args[i] << " ";
2786 }
2787
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2789 num_command_line_args, unsaved_files,
2790 num_unsaved_files, options, 0 };
2791 llvm::CrashRecoveryContext CRC;
2792
2793 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2794 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2795 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2796 fprintf(stderr, " 'command_line_args' : [");
2797 for (int i = 0; i != num_command_line_args; ++i) {
2798 if (i)
2799 fprintf(stderr, ", ");
2800 fprintf(stderr, "'%s'", command_line_args[i]);
2801 }
2802 fprintf(stderr, "],\n");
2803 fprintf(stderr, " 'unsaved_files' : [");
2804 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2805 if (i)
2806 fprintf(stderr, ", ");
2807 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2808 unsaved_files[i].Length);
2809 }
2810 fprintf(stderr, "],\n");
2811 fprintf(stderr, " 'options' : %d,\n", options);
2812 fprintf(stderr, "}\n");
2813
2814 return 0;
2815 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2816 PrintLibclangResourceUsage(PTUI.result);
2817 }
2818
2819 return PTUI.result;
2820}
2821
2822unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2823 return CXSaveTranslationUnit_None;
2824}
2825
2826namespace {
2827
2828struct SaveTranslationUnitInfo {
2829 CXTranslationUnit TU;
2830 const char *FileName;
2831 unsigned options;
2832 CXSaveError result;
2833};
2834
2835}
2836
2837static void clang_saveTranslationUnit_Impl(void *UserData) {
2838 SaveTranslationUnitInfo *STUI =
2839 static_cast<SaveTranslationUnitInfo*>(UserData);
2840
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002841 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2843 setThreadBackgroundPriority();
2844
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002845 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2847}
2848
2849int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2850 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002851 LOG_FUNC_SECTION {
2852 *Log << TU << ' ' << FileName;
2853 }
2854
Guy Benyei11169dd2012-12-18 14:30:41 +00002855 if (!TU)
2856 return CXSaveError_InvalidTU;
2857
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002858 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002859 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2860 if (!CXXUnit->hasSema())
2861 return CXSaveError_InvalidTU;
2862
2863 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2864
2865 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2866 getenv("LIBCLANG_NOTHREADS")) {
2867 clang_saveTranslationUnit_Impl(&STUI);
2868
2869 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2870 PrintLibclangResourceUsage(TU);
2871
2872 return STUI.result;
2873 }
2874
2875 // We have an AST that has invalid nodes due to compiler errors.
2876 // Use a crash recovery thread for protection.
2877
2878 llvm::CrashRecoveryContext CRC;
2879
2880 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2881 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2882 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2883 fprintf(stderr, " 'options' : %d,\n", options);
2884 fprintf(stderr, "}\n");
2885
2886 return CXSaveError_Unknown;
2887
2888 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2889 PrintLibclangResourceUsage(TU);
2890 }
2891
2892 return STUI.result;
2893}
2894
2895void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2896 if (CTUnit) {
2897 // If the translation unit has been marked as unsafe to free, just discard
2898 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002899 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 return;
2901
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002902 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002903 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2905 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002906 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002907 delete CTUnit;
2908 }
2909}
2910
2911unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2912 return CXReparse_None;
2913}
2914
2915struct ReparseTranslationUnitInfo {
2916 CXTranslationUnit TU;
2917 unsigned num_unsaved_files;
2918 struct CXUnsavedFile *unsaved_files;
2919 unsigned options;
2920 int result;
2921};
2922
2923static void clang_reparseTranslationUnit_Impl(void *UserData) {
2924 ReparseTranslationUnitInfo *RTUI =
2925 static_cast<ReparseTranslationUnitInfo*>(UserData);
2926 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002927 if (!TU)
2928 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002929
2930 // Reset the associated diagnostics.
2931 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2932 TU->Diagnostics = 0;
2933
2934 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2935 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2936 unsigned options = RTUI->options;
2937 (void) options;
2938 RTUI->result = 1;
2939
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002940 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002941 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2942 setThreadBackgroundPriority();
2943
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002944 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002945 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2946
2947 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2948 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2949
2950 // Recover resources if we crash before exiting this function.
2951 llvm::CrashRecoveryContextCleanupRegistrar<
2952 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2953
2954 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2955 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2956 const llvm::MemoryBuffer *Buffer
2957 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2958 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2959 Buffer));
2960 }
2961
2962 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2963 RemappedFiles->size()))
2964 RTUI->result = 0;
2965}
2966
2967int clang_reparseTranslationUnit(CXTranslationUnit TU,
2968 unsigned num_unsaved_files,
2969 struct CXUnsavedFile *unsaved_files,
2970 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << TU;
2973 }
2974
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2976 options, 0 };
2977
2978 if (getenv("LIBCLANG_NOTHREADS")) {
2979 clang_reparseTranslationUnit_Impl(&RTUI);
2980 return RTUI.result;
2981 }
2982
2983 llvm::CrashRecoveryContext CRC;
2984
2985 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2986 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002987 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 return 1;
2989 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2990 PrintLibclangResourceUsage(TU);
2991
2992 return RTUI.result;
2993}
2994
2995
2996CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2997 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002998 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00002999
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003000 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003001 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003002}
3003
3004CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003005 if (!TU)
3006 return clang_getNullCursor();
3007
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3010}
3011
3012} // end: extern "C"
3013
3014//===----------------------------------------------------------------------===//
3015// CXFile Operations.
3016//===----------------------------------------------------------------------===//
3017
3018extern "C" {
3019CXString clang_getFileName(CXFile SFile) {
3020 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003021 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003022
3023 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003024 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003025}
3026
3027time_t clang_getFileTime(CXFile SFile) {
3028 if (!SFile)
3029 return 0;
3030
3031 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3032 return FEnt->getModificationTime();
3033}
3034
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003035CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3036 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 return 0;
3038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003039 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003040
3041 FileManager &FMgr = CXXUnit->getFileManager();
3042 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3043}
3044
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003045unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3046 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 return 0;
3048
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003049 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003050 FileEntry *FEnt = static_cast<FileEntry *>(file);
3051 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3052 .isFileMultipleIncludeGuarded(FEnt);
3053}
3054
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003055int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3056 if (!file || !outID)
3057 return 1;
3058
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003059 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003060 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3061 outID->data[0] = ID.getDevice();
3062 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003063 outID->data[2] = FEnt->getModificationTime();
3064 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003065}
3066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067} // end: extern "C"
3068
3069//===----------------------------------------------------------------------===//
3070// CXCursor Operations.
3071//===----------------------------------------------------------------------===//
3072
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003073static const Decl *getDeclFromExpr(const Stmt *E) {
3074 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 return getDeclFromExpr(CE->getSubExpr());
3076
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003077 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003079 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003081 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003083 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 if (PRE->isExplicitProperty())
3085 return PRE->getExplicitProperty();
3086 // It could be messaging both getter and setter as in:
3087 // ++myobj.myprop;
3088 // in which case prefer to associate the setter since it is less obvious
3089 // from inspecting the source that the setter is going to get called.
3090 if (PRE->isMessagingSetter())
3091 return PRE->getImplicitPropertySetter();
3092 return PRE->getImplicitPropertyGetter();
3093 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003094 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003096 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 if (Expr *Src = OVE->getSourceExpr())
3098 return getDeclFromExpr(Src);
3099
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003100 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003102 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 if (!CE->isElidable())
3104 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003105 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 return OME->getMethodDecl();
3107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003108 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003110 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3112 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003113 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3115 isa<ParmVarDecl>(SizeOfPack->getPack()))
3116 return SizeOfPack->getPack();
3117
3118 return 0;
3119}
3120
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003121static SourceLocation getLocationFromExpr(const Expr *E) {
3122 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 return getLocationFromExpr(CE->getSubExpr());
3124
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003125 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003127 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003129 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003131 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003133 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003135 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 return PropRef->getLocation();
3137
3138 return E->getLocStart();
3139}
3140
3141extern "C" {
3142
3143unsigned clang_visitChildren(CXCursor parent,
3144 CXCursorVisitor visitor,
3145 CXClientData client_data) {
3146 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3147 /*VisitPreprocessorLast=*/false);
3148 return CursorVis.VisitChildren(parent);
3149}
3150
3151#ifndef __has_feature
3152#define __has_feature(x) 0
3153#endif
3154#if __has_feature(blocks)
3155typedef enum CXChildVisitResult
3156 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3157
3158static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3159 CXClientData client_data) {
3160 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3161 return block(cursor, parent);
3162}
3163#else
3164// If we are compiled with a compiler that doesn't have native blocks support,
3165// define and call the block manually, so the
3166typedef struct _CXChildVisitResult
3167{
3168 void *isa;
3169 int flags;
3170 int reserved;
3171 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3172 CXCursor);
3173} *CXCursorVisitorBlock;
3174
3175static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3176 CXClientData client_data) {
3177 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3178 return block->invoke(block, cursor, parent);
3179}
3180#endif
3181
3182
3183unsigned clang_visitChildrenWithBlock(CXCursor parent,
3184 CXCursorVisitorBlock block) {
3185 return clang_visitChildren(parent, visitWithBlock, block);
3186}
3187
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003190 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const ObjCPropertyImplDecl *PropImpl =
3195 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003197 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003201 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003202
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003203 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 }
3205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003206 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003207 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003209 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3211 // and returns different names. NamedDecl returns the class name and
3212 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003213 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003214
3215 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003216 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003217
3218 SmallString<1024> S;
3219 llvm::raw_svector_ostream os(S);
3220 ND->printName(os);
3221
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003222 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003223}
3224
3225CXString clang_getCursorSpelling(CXCursor C) {
3226 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003227 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003228
3229 if (clang_isReference(C.kind)) {
3230 switch (C.kind) {
3231 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003232 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003233 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 }
3235 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003236 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003237 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 }
3239 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003240 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003242 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 }
3244 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003245 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003246 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 }
3248 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003249 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 assert(Type && "Missing type decl");
3251
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003252 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 getAsString());
3254 }
3255 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003256 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 assert(Template && "Missing template decl");
3258
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003259 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 }
3261
3262 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003263 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 assert(NS && "Missing namespace decl");
3265
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003266 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 }
3268
3269 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003270 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 assert(Field && "Missing member decl");
3272
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003273 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 }
3275
3276 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003277 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 assert(Label && "Missing label");
3279
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003280 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 }
3282
3283 case CXCursor_OverloadedDeclRef: {
3284 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3286 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003287 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003288 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003291 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 OverloadedTemplateStorage *Ovl
3293 = Storage.get<OverloadedTemplateStorage*>();
3294 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003295 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 }
3298
3299 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003300 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 assert(Var && "Missing variable decl");
3302
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003303 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 }
3305
3306 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003307 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 }
3309 }
3310
3311 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 if (D)
3314 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003315 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
3317
3318 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003319 const Stmt *S = getCursorStmt(C);
3320 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003323 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
3325
3326 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003327 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 ->getNameStart());
3329
3330 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003331 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 ->getNameStart());
3333
3334 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336
3337 if (clang_isDeclaration(C.kind))
3338 return getDeclSpelling(getCursorDecl(C));
3339
3340 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003341 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 }
3344
3345 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003346 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003350 if (C.kind == CXCursor_PackedAttr) {
3351 return cxstring::createRef("packed");
3352 }
3353
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003354 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003355}
3356
3357CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3358 unsigned pieceIndex,
3359 unsigned options) {
3360 if (clang_Cursor_isNull(C))
3361 return clang_getNullRange();
3362
3363 ASTContext &Ctx = getCursorContext(C);
3364
3365 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003366 const Stmt *S = getCursorStmt(C);
3367 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 if (pieceIndex > 0)
3369 return clang_getNullRange();
3370 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3371 }
3372
3373 return clang_getNullRange();
3374 }
3375
3376 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003377 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3379 if (pieceIndex >= ME->getNumSelectorLocs())
3380 return clang_getNullRange();
3381 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3382 }
3383 }
3384
3385 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3386 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003387 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3389 if (pieceIndex >= MD->getNumSelectorLocs())
3390 return clang_getNullRange();
3391 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3392 }
3393 }
3394
3395 if (C.kind == CXCursor_ObjCCategoryDecl ||
3396 C.kind == CXCursor_ObjCCategoryImplDecl) {
3397 if (pieceIndex > 0)
3398 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003399 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3401 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003402 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3404 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3405 }
3406
3407 if (C.kind == CXCursor_ModuleImportDecl) {
3408 if (pieceIndex > 0)
3409 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 if (const ImportDecl *ImportD =
3411 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3413 if (!Locs.empty())
3414 return cxloc::translateSourceRange(Ctx,
3415 SourceRange(Locs.front(), Locs.back()));
3416 }
3417 return clang_getNullRange();
3418 }
3419
3420 // FIXME: A CXCursor_InclusionDirective should give the location of the
3421 // filename, but we don't keep track of this.
3422
3423 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3424 // but we don't keep track of this.
3425
3426 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3427 // but we don't keep track of this.
3428
3429 // Default handling, give the location of the cursor.
3430
3431 if (pieceIndex > 0)
3432 return clang_getNullRange();
3433
3434 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3435 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3436 return cxloc::translateSourceRange(Ctx, Loc);
3437}
3438
3439CXString clang_getCursorDisplayName(CXCursor C) {
3440 if (!clang_isDeclaration(C.kind))
3441 return clang_getCursorSpelling(C);
3442
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003443 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003445 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003446
3447 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003448 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 D = FunTmpl->getTemplatedDecl();
3450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 SmallString<64> Str;
3453 llvm::raw_svector_ostream OS(Str);
3454 OS << *Function;
3455 if (Function->getPrimaryTemplate())
3456 OS << "<>";
3457 OS << "(";
3458 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3459 if (I)
3460 OS << ", ";
3461 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3462 }
3463
3464 if (Function->isVariadic()) {
3465 if (Function->getNumParams())
3466 OS << ", ";
3467 OS << "...";
3468 }
3469 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003470 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 }
3472
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 SmallString<64> Str;
3475 llvm::raw_svector_ostream OS(Str);
3476 OS << *ClassTemplate;
3477 OS << "<";
3478 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3479 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3480 if (I)
3481 OS << ", ";
3482
3483 NamedDecl *Param = Params->getParam(I);
3484 if (Param->getIdentifier()) {
3485 OS << Param->getIdentifier()->getName();
3486 continue;
3487 }
3488
3489 // There is no parameter name, which makes this tricky. Try to come up
3490 // with something useful that isn't too long.
3491 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3492 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3493 else if (NonTypeTemplateParmDecl *NTTP
3494 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3495 OS << NTTP->getType().getAsString(Policy);
3496 else
3497 OS << "template<...> class";
3498 }
3499
3500 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003501 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 }
3503
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3506 // If the type was explicitly written, use that.
3507 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003509
Benjamin Kramer9170e912013-02-22 15:46:01 +00003510 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 llvm::raw_svector_ostream OS(Str);
3512 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003513 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 ClassSpec->getTemplateArgs().data(),
3515 ClassSpec->getTemplateArgs().size(),
3516 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003517 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 }
3519
3520 return clang_getCursorSpelling(C);
3521}
3522
3523CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3524 switch (Kind) {
3525 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003528 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003530 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003536 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003540 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003546 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003564 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003568 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003572 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003576 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003580 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003586 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003588 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003592 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003596 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003598 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003600 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003604 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003606 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003608 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003653 case CXCursor_ObjCSelfExpr:
3654 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003771 case CXCursor_PackedAttr:
3772 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003821 case CXCursor_OMPParallelDirective:
3822 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 }
3824
3825 llvm_unreachable("Unhandled CXCursorKind");
3826}
3827
3828struct GetCursorData {
3829 SourceLocation TokenBeginLoc;
3830 bool PointsAtMacroArgExpansion;
3831 bool VisitedObjCPropertyImplDecl;
3832 SourceLocation VisitedDeclaratorDeclStartLoc;
3833 CXCursor &BestCursor;
3834
3835 GetCursorData(SourceManager &SM,
3836 SourceLocation tokenBegin, CXCursor &outputCursor)
3837 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3838 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3839 VisitedObjCPropertyImplDecl = false;
3840 }
3841};
3842
3843static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3844 CXCursor parent,
3845 CXClientData client_data) {
3846 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3847 CXCursor *BestCursor = &Data->BestCursor;
3848
3849 // If we point inside a macro argument we should provide info of what the
3850 // token is so use the actual cursor, don't replace it with a macro expansion
3851 // cursor.
3852 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3853 return CXChildVisit_Recurse;
3854
3855 if (clang_isDeclaration(cursor.kind)) {
3856 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003857 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3859 if (MD->isImplicit())
3860 return CXChildVisit_Break;
3861
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003862 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3864 // Check that when we have multiple @class references in the same line,
3865 // that later ones do not override the previous ones.
3866 // If we have:
3867 // @class Foo, Bar;
3868 // source ranges for both start at '@', so 'Bar' will end up overriding
3869 // 'Foo' even though the cursor location was at 'Foo'.
3870 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3871 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003872 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3874 if (PrevID != ID &&
3875 !PrevID->isThisDeclarationADefinition() &&
3876 !ID->isThisDeclarationADefinition())
3877 return CXChildVisit_Break;
3878 }
3879
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003880 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3882 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3883 // Check that when we have multiple declarators in the same line,
3884 // that later ones do not override the previous ones.
3885 // If we have:
3886 // int Foo, Bar;
3887 // source ranges for both start at 'int', so 'Bar' will end up overriding
3888 // 'Foo' even though the cursor location was at 'Foo'.
3889 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3890 return CXChildVisit_Break;
3891 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003893 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3895 (void)PropImp;
3896 // Check that when we have multiple @synthesize in the same line,
3897 // that later ones do not override the previous ones.
3898 // If we have:
3899 // @synthesize Foo, Bar;
3900 // source ranges for both start at '@', so 'Bar' will end up overriding
3901 // 'Foo' even though the cursor location was at 'Foo'.
3902 if (Data->VisitedObjCPropertyImplDecl)
3903 return CXChildVisit_Break;
3904 Data->VisitedObjCPropertyImplDecl = true;
3905 }
3906 }
3907
3908 if (clang_isExpression(cursor.kind) &&
3909 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003910 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 // Avoid having the cursor of an expression replace the declaration cursor
3912 // when the expression source range overlaps the declaration range.
3913 // This can happen for C++ constructor expressions whose range generally
3914 // include the variable declaration, e.g.:
3915 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3916 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3917 D->getLocation() == Data->TokenBeginLoc)
3918 return CXChildVisit_Break;
3919 }
3920 }
3921
3922 // If our current best cursor is the construction of a temporary object,
3923 // don't replace that cursor with a type reference, because we want
3924 // clang_getCursor() to point at the constructor.
3925 if (clang_isExpression(BestCursor->kind) &&
3926 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3927 cursor.kind == CXCursor_TypeRef) {
3928 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3929 // as having the actual point on the type reference.
3930 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3931 return CXChildVisit_Recurse;
3932 }
3933
3934 *BestCursor = cursor;
3935 return CXChildVisit_Recurse;
3936}
3937
3938CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3939 if (!TU)
3940 return clang_getNullCursor();
3941
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003942 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3944
3945 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3946 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3947
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003948 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 CXFile SearchFile;
3950 unsigned SearchLine, SearchColumn;
3951 CXFile ResultFile;
3952 unsigned ResultLine, ResultColumn;
3953 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3954 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3955 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3956
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003957 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3958 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 &ResultColumn, 0);
3960 SearchFileName = clang_getFileName(SearchFile);
3961 ResultFileName = clang_getFileName(ResultFile);
3962 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3963 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003964 *Log << llvm::format("(%s:%d:%d) = %s",
3965 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3966 clang_getCString(KindSpelling))
3967 << llvm::format("(%s:%d:%d):%s%s",
3968 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3969 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 clang_disposeString(SearchFileName);
3971 clang_disposeString(ResultFileName);
3972 clang_disposeString(KindSpelling);
3973 clang_disposeString(USR);
3974
3975 CXCursor Definition = clang_getCursorDefinition(Result);
3976 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3977 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3978 CXString DefinitionKindSpelling
3979 = clang_getCursorKindSpelling(Definition.kind);
3980 CXFile DefinitionFile;
3981 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003982 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 &DefinitionLine, &DefinitionColumn, 0);
3984 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003985 *Log << llvm::format(" -> %s(%s:%d:%d)",
3986 clang_getCString(DefinitionKindSpelling),
3987 clang_getCString(DefinitionFileName),
3988 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 clang_disposeString(DefinitionFileName);
3990 clang_disposeString(DefinitionKindSpelling);
3991 }
3992 }
3993
3994 return Result;
3995}
3996
3997CXCursor clang_getNullCursor(void) {
3998 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3999}
4000
4001unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004002 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4003 // can't set consistently. For example, when visiting a DeclStmt we will set
4004 // it but we don't set it on the result of clang_getCursorDefinition for
4005 // a reference of the same declaration.
4006 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4007 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4008 // to provide that kind of info.
4009 if (clang_isDeclaration(X.kind))
4010 X.data[1] = 0;
4011 if (clang_isDeclaration(Y.kind))
4012 Y.data[1] = 0;
4013
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 return X == Y;
4015}
4016
4017unsigned clang_hashCursor(CXCursor C) {
4018 unsigned Index = 0;
4019 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4020 Index = 1;
4021
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004022 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 std::make_pair(C.kind, C.data[Index]));
4024}
4025
4026unsigned clang_isInvalid(enum CXCursorKind K) {
4027 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4028}
4029
4030unsigned clang_isDeclaration(enum CXCursorKind K) {
4031 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4032 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4033}
4034
4035unsigned clang_isReference(enum CXCursorKind K) {
4036 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4037}
4038
4039unsigned clang_isExpression(enum CXCursorKind K) {
4040 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4041}
4042
4043unsigned clang_isStatement(enum CXCursorKind K) {
4044 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4045}
4046
4047unsigned clang_isAttribute(enum CXCursorKind K) {
4048 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4049}
4050
4051unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4052 return K == CXCursor_TranslationUnit;
4053}
4054
4055unsigned clang_isPreprocessing(enum CXCursorKind K) {
4056 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4057}
4058
4059unsigned clang_isUnexposed(enum CXCursorKind K) {
4060 switch (K) {
4061 case CXCursor_UnexposedDecl:
4062 case CXCursor_UnexposedExpr:
4063 case CXCursor_UnexposedStmt:
4064 case CXCursor_UnexposedAttr:
4065 return true;
4066 default:
4067 return false;
4068 }
4069}
4070
4071CXCursorKind clang_getCursorKind(CXCursor C) {
4072 return C.kind;
4073}
4074
4075CXSourceLocation clang_getCursorLocation(CXCursor C) {
4076 if (clang_isReference(C.kind)) {
4077 switch (C.kind) {
4078 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004079 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 = getCursorObjCSuperClassRef(C);
4081 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4082 }
4083
4084 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004085 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 = getCursorObjCProtocolRef(C);
4087 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4088 }
4089
4090 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004091 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 = getCursorObjCClassRef(C);
4093 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4094 }
4095
4096 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004097 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 std::pair<const TemplateDecl *, SourceLocation> P =
4103 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4105 }
4106
4107 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004108 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4110 }
4111
4112 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4115 }
4116
4117 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004118 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4120 }
4121
4122 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 if (!BaseSpec)
4125 return clang_getNullLocation();
4126
4127 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4128 return cxloc::translateSourceLocation(getCursorContext(C),
4129 TSInfo->getTypeLoc().getBeginLoc());
4130
4131 return cxloc::translateSourceLocation(getCursorContext(C),
4132 BaseSpec->getLocStart());
4133 }
4134
4135 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004136 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4138 }
4139
4140 case CXCursor_OverloadedDeclRef:
4141 return cxloc::translateSourceLocation(getCursorContext(C),
4142 getCursorOverloadedDeclRef(C).second);
4143
4144 default:
4145 // FIXME: Need a way to enumerate all non-reference cases.
4146 llvm_unreachable("Missed a reference kind");
4147 }
4148 }
4149
4150 if (clang_isExpression(C.kind))
4151 return cxloc::translateSourceLocation(getCursorContext(C),
4152 getLocationFromExpr(getCursorExpr(C)));
4153
4154 if (clang_isStatement(C.kind))
4155 return cxloc::translateSourceLocation(getCursorContext(C),
4156 getCursorStmt(C)->getLocStart());
4157
4158 if (C.kind == CXCursor_PreprocessingDirective) {
4159 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4160 return cxloc::translateSourceLocation(getCursorContext(C), L);
4161 }
4162
4163 if (C.kind == CXCursor_MacroExpansion) {
4164 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004165 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 return cxloc::translateSourceLocation(getCursorContext(C), L);
4167 }
4168
4169 if (C.kind == CXCursor_MacroDefinition) {
4170 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
4174 if (C.kind == CXCursor_InclusionDirective) {
4175 SourceLocation L
4176 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4177 return cxloc::translateSourceLocation(getCursorContext(C), L);
4178 }
4179
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004180 if (clang_isAttribute(C.kind)) {
4181 SourceLocation L
4182 = cxcursor::getCursorAttr(C)->getLocation();
4183 return cxloc::translateSourceLocation(getCursorContext(C), L);
4184 }
4185
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 if (!clang_isDeclaration(C.kind))
4187 return clang_getNullLocation();
4188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004189 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 if (!D)
4191 return clang_getNullLocation();
4192
4193 SourceLocation Loc = D->getLocation();
4194 // FIXME: Multiple variables declared in a single declaration
4195 // currently lack the information needed to correctly determine their
4196 // ranges when accounting for the type-specifier. We use context
4197 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4198 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004199 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 if (!cxcursor::isFirstInDeclGroup(C))
4201 Loc = VD->getLocation();
4202 }
4203
4204 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004205 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 Loc = MD->getSelectorStartLoc();
4207
4208 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4209}
4210
4211} // end extern "C"
4212
4213CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4214 assert(TU);
4215
4216 // Guard against an invalid SourceLocation, or we may assert in one
4217 // of the following calls.
4218 if (SLoc.isInvalid())
4219 return clang_getNullCursor();
4220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222
4223 // Translate the given source location to make it point at the beginning of
4224 // the token under the cursor.
4225 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4226 CXXUnit->getASTContext().getLangOpts());
4227
4228 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4229 if (SLoc.isValid()) {
4230 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4231 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4232 /*VisitPreprocessorLast=*/true,
4233 /*VisitIncludedEntities=*/false,
4234 SourceLocation(SLoc));
4235 CursorVis.visitFileRegion();
4236 }
4237
4238 return Result;
4239}
4240
4241static SourceRange getRawCursorExtent(CXCursor C) {
4242 if (clang_isReference(C.kind)) {
4243 switch (C.kind) {
4244 case CXCursor_ObjCSuperClassRef:
4245 return getCursorObjCSuperClassRef(C).second;
4246
4247 case CXCursor_ObjCProtocolRef:
4248 return getCursorObjCProtocolRef(C).second;
4249
4250 case CXCursor_ObjCClassRef:
4251 return getCursorObjCClassRef(C).second;
4252
4253 case CXCursor_TypeRef:
4254 return getCursorTypeRef(C).second;
4255
4256 case CXCursor_TemplateRef:
4257 return getCursorTemplateRef(C).second;
4258
4259 case CXCursor_NamespaceRef:
4260 return getCursorNamespaceRef(C).second;
4261
4262 case CXCursor_MemberRef:
4263 return getCursorMemberRef(C).second;
4264
4265 case CXCursor_CXXBaseSpecifier:
4266 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4267
4268 case CXCursor_LabelRef:
4269 return getCursorLabelRef(C).second;
4270
4271 case CXCursor_OverloadedDeclRef:
4272 return getCursorOverloadedDeclRef(C).second;
4273
4274 case CXCursor_VariableRef:
4275 return getCursorVariableRef(C).second;
4276
4277 default:
4278 // FIXME: Need a way to enumerate all non-reference cases.
4279 llvm_unreachable("Missed a reference kind");
4280 }
4281 }
4282
4283 if (clang_isExpression(C.kind))
4284 return getCursorExpr(C)->getSourceRange();
4285
4286 if (clang_isStatement(C.kind))
4287 return getCursorStmt(C)->getSourceRange();
4288
4289 if (clang_isAttribute(C.kind))
4290 return getCursorAttr(C)->getRange();
4291
4292 if (C.kind == CXCursor_PreprocessingDirective)
4293 return cxcursor::getCursorPreprocessingDirective(C);
4294
4295 if (C.kind == CXCursor_MacroExpansion) {
4296 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004297 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 return TU->mapRangeFromPreamble(Range);
4299 }
4300
4301 if (C.kind == CXCursor_MacroDefinition) {
4302 ASTUnit *TU = getCursorASTUnit(C);
4303 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4304 return TU->mapRangeFromPreamble(Range);
4305 }
4306
4307 if (C.kind == CXCursor_InclusionDirective) {
4308 ASTUnit *TU = getCursorASTUnit(C);
4309 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4310 return TU->mapRangeFromPreamble(Range);
4311 }
4312
4313 if (C.kind == CXCursor_TranslationUnit) {
4314 ASTUnit *TU = getCursorASTUnit(C);
4315 FileID MainID = TU->getSourceManager().getMainFileID();
4316 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4317 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4318 return SourceRange(Start, End);
4319 }
4320
4321 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 if (!D)
4324 return SourceRange();
4325
4326 SourceRange R = D->getSourceRange();
4327 // FIXME: Multiple variables declared in a single declaration
4328 // currently lack the information needed to correctly determine their
4329 // ranges when accounting for the type-specifier. We use context
4330 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4331 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004332 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 if (!cxcursor::isFirstInDeclGroup(C))
4334 R.setBegin(VD->getLocation());
4335 }
4336 return R;
4337 }
4338 return SourceRange();
4339}
4340
4341/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4342/// the decl-specifier-seq for declarations.
4343static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4344 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004345 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 if (!D)
4347 return SourceRange();
4348
4349 SourceRange R = D->getSourceRange();
4350
4351 // Adjust the start of the location for declarations preceded by
4352 // declaration specifiers.
4353 SourceLocation StartLoc;
4354 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4355 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4356 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004357 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004358 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4359 StartLoc = TI->getTypeLoc().getLocStart();
4360 }
4361
4362 if (StartLoc.isValid() && R.getBegin().isValid() &&
4363 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4364 R.setBegin(StartLoc);
4365
4366 // FIXME: Multiple variables declared in a single declaration
4367 // currently lack the information needed to correctly determine their
4368 // ranges when accounting for the type-specifier. We use context
4369 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4370 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004371 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 if (!cxcursor::isFirstInDeclGroup(C))
4373 R.setBegin(VD->getLocation());
4374 }
4375
4376 return R;
4377 }
4378
4379 return getRawCursorExtent(C);
4380}
4381
4382extern "C" {
4383
4384CXSourceRange clang_getCursorExtent(CXCursor C) {
4385 SourceRange R = getRawCursorExtent(C);
4386 if (R.isInvalid())
4387 return clang_getNullRange();
4388
4389 return cxloc::translateSourceRange(getCursorContext(C), R);
4390}
4391
4392CXCursor clang_getCursorReferenced(CXCursor C) {
4393 if (clang_isInvalid(C.kind))
4394 return clang_getNullCursor();
4395
4396 CXTranslationUnit tu = getCursorTU(C);
4397 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004398 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 if (!D)
4400 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004401 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 if (const ObjCPropertyImplDecl *PropImpl =
4404 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4406 return MakeCXCursor(Property, tu);
4407
4408 return C;
4409 }
4410
4411 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 const Expr *E = getCursorExpr(C);
4413 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 if (D) {
4415 CXCursor declCursor = MakeCXCursor(D, tu);
4416 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4417 declCursor);
4418 return declCursor;
4419 }
4420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004421 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 return MakeCursorOverloadedDeclRef(Ovl, tu);
4423
4424 return clang_getNullCursor();
4425 }
4426
4427 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004428 const Stmt *S = getCursorStmt(C);
4429 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 if (LabelDecl *label = Goto->getLabel())
4431 if (LabelStmt *labelS = label->getStmt())
4432 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4433
4434 return clang_getNullCursor();
4435 }
4436
4437 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004438 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return MakeMacroDefinitionCursor(Def, tu);
4440 }
4441
4442 if (!clang_isReference(C.kind))
4443 return clang_getNullCursor();
4444
4445 switch (C.kind) {
4446 case CXCursor_ObjCSuperClassRef:
4447 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4448
4449 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004450 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4451 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 return MakeCXCursor(Def, tu);
4453
4454 return MakeCXCursor(Prot, tu);
4455 }
4456
4457 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004458 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4459 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 return MakeCXCursor(Def, tu);
4461
4462 return MakeCXCursor(Class, tu);
4463 }
4464
4465 case CXCursor_TypeRef:
4466 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4467
4468 case CXCursor_TemplateRef:
4469 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4470
4471 case CXCursor_NamespaceRef:
4472 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4473
4474 case CXCursor_MemberRef:
4475 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4476
4477 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004478 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4480 tu ));
4481 }
4482
4483 case CXCursor_LabelRef:
4484 // FIXME: We end up faking the "parent" declaration here because we
4485 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004486 return MakeCXCursor(getCursorLabelRef(C).first,
4487 cxtu::getASTUnit(tu)->getASTContext()
4488 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 tu);
4490
4491 case CXCursor_OverloadedDeclRef:
4492 return C;
4493
4494 case CXCursor_VariableRef:
4495 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4496
4497 default:
4498 // We would prefer to enumerate all non-reference cursor kinds here.
4499 llvm_unreachable("Unhandled reference cursor kind");
4500 }
4501}
4502
4503CXCursor clang_getCursorDefinition(CXCursor C) {
4504 if (clang_isInvalid(C.kind))
4505 return clang_getNullCursor();
4506
4507 CXTranslationUnit TU = getCursorTU(C);
4508
4509 bool WasReference = false;
4510 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4511 C = clang_getCursorReferenced(C);
4512 WasReference = true;
4513 }
4514
4515 if (C.kind == CXCursor_MacroExpansion)
4516 return clang_getCursorReferenced(C);
4517
4518 if (!clang_isDeclaration(C.kind))
4519 return clang_getNullCursor();
4520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 if (!D)
4523 return clang_getNullCursor();
4524
4525 switch (D->getKind()) {
4526 // Declaration kinds that don't really separate the notions of
4527 // declaration and definition.
4528 case Decl::Namespace:
4529 case Decl::Typedef:
4530 case Decl::TypeAlias:
4531 case Decl::TypeAliasTemplate:
4532 case Decl::TemplateTypeParm:
4533 case Decl::EnumConstant:
4534 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004535 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 case Decl::IndirectField:
4537 case Decl::ObjCIvar:
4538 case Decl::ObjCAtDefsField:
4539 case Decl::ImplicitParam:
4540 case Decl::ParmVar:
4541 case Decl::NonTypeTemplateParm:
4542 case Decl::TemplateTemplateParm:
4543 case Decl::ObjCCategoryImpl:
4544 case Decl::ObjCImplementation:
4545 case Decl::AccessSpec:
4546 case Decl::LinkageSpec:
4547 case Decl::ObjCPropertyImpl:
4548 case Decl::FileScopeAsm:
4549 case Decl::StaticAssert:
4550 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004551 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case Decl::Label: // FIXME: Is this right??
4553 case Decl::ClassScopeFunctionSpecialization:
4554 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004555 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 return C;
4557
4558 // Declaration kinds that don't make any sense here, but are
4559 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004560 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case Decl::TranslationUnit:
4562 break;
4563
4564 // Declaration kinds for which the definition is not resolvable.
4565 case Decl::UnresolvedUsingTypename:
4566 case Decl::UnresolvedUsingValue:
4567 break;
4568
4569 case Decl::UsingDirective:
4570 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4571 TU);
4572
4573 case Decl::NamespaceAlias:
4574 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4575
4576 case Decl::Enum:
4577 case Decl::Record:
4578 case Decl::CXXRecord:
4579 case Decl::ClassTemplateSpecialization:
4580 case Decl::ClassTemplatePartialSpecialization:
4581 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4582 return MakeCXCursor(Def, TU);
4583 return clang_getNullCursor();
4584
4585 case Decl::Function:
4586 case Decl::CXXMethod:
4587 case Decl::CXXConstructor:
4588 case Decl::CXXDestructor:
4589 case Decl::CXXConversion: {
4590 const FunctionDecl *Def = 0;
4591 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004592 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 return clang_getNullCursor();
4594 }
4595
Larisse Voufo39a1e502013-08-06 01:03:05 +00004596 case Decl::Var:
4597 case Decl::VarTemplateSpecialization:
4598 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004600 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 return MakeCXCursor(Def, TU);
4602 return clang_getNullCursor();
4603 }
4604
4605 case Decl::FunctionTemplate: {
4606 const FunctionDecl *Def = 0;
4607 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4608 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4609 return clang_getNullCursor();
4610 }
4611
4612 case Decl::ClassTemplate: {
4613 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4614 ->getDefinition())
4615 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4616 TU);
4617 return clang_getNullCursor();
4618 }
4619
Larisse Voufo39a1e502013-08-06 01:03:05 +00004620 case Decl::VarTemplate: {
4621 if (VarDecl *Def =
4622 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4623 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4624 return clang_getNullCursor();
4625 }
4626
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case Decl::Using:
4628 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4629 D->getLocation(), TU);
4630
4631 case Decl::UsingShadow:
4632 return clang_getCursorDefinition(
4633 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4634 TU));
4635
4636 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004637 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 if (Method->isThisDeclarationADefinition())
4639 return C;
4640
4641 // Dig out the method definition in the associated
4642 // @implementation, if we have it.
4643 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004644 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4646 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4647 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4648 Method->isInstanceMethod()))
4649 if (Def->isThisDeclarationADefinition())
4650 return MakeCXCursor(Def, TU);
4651
4652 return clang_getNullCursor();
4653 }
4654
4655 case Decl::ObjCCategory:
4656 if (ObjCCategoryImplDecl *Impl
4657 = cast<ObjCCategoryDecl>(D)->getImplementation())
4658 return MakeCXCursor(Impl, TU);
4659 return clang_getNullCursor();
4660
4661 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004662 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 return MakeCXCursor(Def, TU);
4664 return clang_getNullCursor();
4665
4666 case Decl::ObjCInterface: {
4667 // There are two notions of a "definition" for an Objective-C
4668 // class: the interface and its implementation. When we resolved a
4669 // reference to an Objective-C class, produce the @interface as
4670 // the definition; when we were provided with the interface,
4671 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004672 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004674 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 return MakeCXCursor(Def, TU);
4676 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4677 return MakeCXCursor(Impl, TU);
4678 return clang_getNullCursor();
4679 }
4680
4681 case Decl::ObjCProperty:
4682 // FIXME: We don't really know where to find the
4683 // ObjCPropertyImplDecls that implement this property.
4684 return clang_getNullCursor();
4685
4686 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004687 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004689 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return MakeCXCursor(Def, TU);
4691
4692 return clang_getNullCursor();
4693
4694 case Decl::Friend:
4695 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4696 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4697 return clang_getNullCursor();
4698
4699 case Decl::FriendTemplate:
4700 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4701 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4702 return clang_getNullCursor();
4703 }
4704
4705 return clang_getNullCursor();
4706}
4707
4708unsigned clang_isCursorDefinition(CXCursor C) {
4709 if (!clang_isDeclaration(C.kind))
4710 return 0;
4711
4712 return clang_getCursorDefinition(C) == C;
4713}
4714
4715CXCursor clang_getCanonicalCursor(CXCursor C) {
4716 if (!clang_isDeclaration(C.kind))
4717 return C;
4718
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004719 if (const Decl *D = getCursorDecl(C)) {
4720 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4722 return MakeCXCursor(CatD, getCursorTU(C));
4723
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4725 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 return MakeCXCursor(IFD, getCursorTU(C));
4727
4728 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4729 }
4730
4731 return C;
4732}
4733
4734int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4735 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4736}
4737
4738unsigned clang_getNumOverloadedDecls(CXCursor C) {
4739 if (C.kind != CXCursor_OverloadedDeclRef)
4740 return 0;
4741
4742 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 return E->getNumDecls();
4745
4746 if (OverloadedTemplateStorage *S
4747 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4748 return S->size();
4749
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 const Decl *D = Storage.get<const Decl *>();
4751 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 return Using->shadow_size();
4753
4754 return 0;
4755}
4756
4757CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4758 if (cursor.kind != CXCursor_OverloadedDeclRef)
4759 return clang_getNullCursor();
4760
4761 if (index >= clang_getNumOverloadedDecls(cursor))
4762 return clang_getNullCursor();
4763
4764 CXTranslationUnit TU = getCursorTU(cursor);
4765 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004766 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 return MakeCXCursor(E->decls_begin()[index], TU);
4768
4769 if (OverloadedTemplateStorage *S
4770 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4771 return MakeCXCursor(S->begin()[index], TU);
4772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 const Decl *D = Storage.get<const Decl *>();
4774 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 // FIXME: This is, unfortunately, linear time.
4776 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4777 std::advance(Pos, index);
4778 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4779 }
4780
4781 return clang_getNullCursor();
4782}
4783
4784void clang_getDefinitionSpellingAndExtent(CXCursor C,
4785 const char **startBuf,
4786 const char **endBuf,
4787 unsigned *startLine,
4788 unsigned *startColumn,
4789 unsigned *endLine,
4790 unsigned *endColumn) {
4791 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004792 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4794
4795 SourceManager &SM = FD->getASTContext().getSourceManager();
4796 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4797 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4798 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4799 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4800 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4801 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4802}
4803
4804
4805CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4806 unsigned PieceIndex) {
4807 RefNamePieces Pieces;
4808
4809 switch (C.kind) {
4810 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004811 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4813 E->getQualifierLoc().getSourceRange());
4814 break;
4815
4816 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004817 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4819 E->getQualifierLoc().getSourceRange(),
4820 E->getOptionalExplicitTemplateArgs());
4821 break;
4822
4823 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004824 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004826 const Expr *Callee = OCE->getCallee();
4827 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 Callee = ICE->getSubExpr();
4829
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004830 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4832 DRE->getQualifierLoc().getSourceRange());
4833 }
4834 break;
4835
4836 default:
4837 break;
4838 }
4839
4840 if (Pieces.empty()) {
4841 if (PieceIndex == 0)
4842 return clang_getCursorExtent(C);
4843 } else if (PieceIndex < Pieces.size()) {
4844 SourceRange R = Pieces[PieceIndex];
4845 if (R.isValid())
4846 return cxloc::translateSourceRange(getCursorContext(C), R);
4847 }
4848
4849 return clang_getNullRange();
4850}
4851
4852void clang_enableStackTraces(void) {
4853 llvm::sys::PrintStackTraceOnErrorSignal();
4854}
4855
4856void clang_executeOnThread(void (*fn)(void*), void *user_data,
4857 unsigned stack_size) {
4858 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4859}
4860
4861} // end: extern "C"
4862
4863//===----------------------------------------------------------------------===//
4864// Token-based Operations.
4865//===----------------------------------------------------------------------===//
4866
4867/* CXToken layout:
4868 * int_data[0]: a CXTokenKind
4869 * int_data[1]: starting token location
4870 * int_data[2]: token length
4871 * int_data[3]: reserved
4872 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4873 * otherwise unused.
4874 */
4875extern "C" {
4876
4877CXTokenKind clang_getTokenKind(CXToken CXTok) {
4878 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4879}
4880
4881CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4882 switch (clang_getTokenKind(CXTok)) {
4883 case CXToken_Identifier:
4884 case CXToken_Keyword:
4885 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004886 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 ->getNameStart());
4888
4889 case CXToken_Literal: {
4890 // We have stashed the starting pointer in the ptr_data field. Use it.
4891 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004892 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 }
4894
4895 case CXToken_Punctuation:
4896 case CXToken_Comment:
4897 break;
4898 }
4899
4900 // We have to find the starting buffer pointer the hard way, by
4901 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004902 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004904 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004905
4906 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4907 std::pair<FileID, unsigned> LocInfo
4908 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4909 bool Invalid = false;
4910 StringRef Buffer
4911 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4912 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004913 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004914
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004915 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004916}
4917
4918CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004919 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 if (!CXXUnit)
4921 return clang_getNullLocation();
4922
4923 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4924 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4925}
4926
4927CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004928 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 if (!CXXUnit)
4930 return clang_getNullRange();
4931
4932 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4933 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4934}
4935
4936static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4937 SmallVectorImpl<CXToken> &CXTokens) {
4938 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4939 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004940 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004942 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004943
4944 // Cannot tokenize across files.
4945 if (BeginLocInfo.first != EndLocInfo.first)
4946 return;
4947
4948 // Create a lexer
4949 bool Invalid = false;
4950 StringRef Buffer
4951 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4952 if (Invalid)
4953 return;
4954
4955 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4956 CXXUnit->getASTContext().getLangOpts(),
4957 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4958 Lex.SetCommentRetentionState(true);
4959
4960 // Lex tokens until we hit the end of the range.
4961 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4962 Token Tok;
4963 bool previousWasAt = false;
4964 do {
4965 // Lex the next token
4966 Lex.LexFromRawLexer(Tok);
4967 if (Tok.is(tok::eof))
4968 break;
4969
4970 // Initialize the CXToken.
4971 CXToken CXTok;
4972
4973 // - Common fields
4974 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4975 CXTok.int_data[2] = Tok.getLength();
4976 CXTok.int_data[3] = 0;
4977
4978 // - Kind-specific fields
4979 if (Tok.isLiteral()) {
4980 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004981 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 } else if (Tok.is(tok::raw_identifier)) {
4983 // Lookup the identifier to determine whether we have a keyword.
4984 IdentifierInfo *II
4985 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4986
4987 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4988 CXTok.int_data[0] = CXToken_Keyword;
4989 }
4990 else {
4991 CXTok.int_data[0] = Tok.is(tok::identifier)
4992 ? CXToken_Identifier
4993 : CXToken_Keyword;
4994 }
4995 CXTok.ptr_data = II;
4996 } else if (Tok.is(tok::comment)) {
4997 CXTok.int_data[0] = CXToken_Comment;
4998 CXTok.ptr_data = 0;
4999 } else {
5000 CXTok.int_data[0] = CXToken_Punctuation;
5001 CXTok.ptr_data = 0;
5002 }
5003 CXTokens.push_back(CXTok);
5004 previousWasAt = Tok.is(tok::at);
5005 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5006}
5007
5008void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5009 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005010 LOG_FUNC_SECTION {
5011 *Log << TU << ' ' << Range;
5012 }
5013
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 if (Tokens)
5015 *Tokens = 0;
5016 if (NumTokens)
5017 *NumTokens = 0;
5018
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005019 if (!TU)
5020 return;
5021
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005022 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 if (!CXXUnit || !Tokens || !NumTokens)
5024 return;
5025
5026 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5027
5028 SourceRange R = cxloc::translateCXSourceRange(Range);
5029 if (R.isInvalid())
5030 return;
5031
5032 SmallVector<CXToken, 32> CXTokens;
5033 getTokens(CXXUnit, R, CXTokens);
5034
5035 if (CXTokens.empty())
5036 return;
5037
5038 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5039 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5040 *NumTokens = CXTokens.size();
5041}
5042
5043void clang_disposeTokens(CXTranslationUnit TU,
5044 CXToken *Tokens, unsigned NumTokens) {
5045 free(Tokens);
5046}
5047
5048} // end: extern "C"
5049
5050//===----------------------------------------------------------------------===//
5051// Token annotation APIs.
5052//===----------------------------------------------------------------------===//
5053
Guy Benyei11169dd2012-12-18 14:30:41 +00005054static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5055 CXCursor parent,
5056 CXClientData client_data);
5057static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5058 CXClientData client_data);
5059
5060namespace {
5061class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 CXToken *Tokens;
5063 CXCursor *Cursors;
5064 unsigned NumTokens;
5065 unsigned TokIdx;
5066 unsigned PreprocessingTokIdx;
5067 CursorVisitor AnnotateVis;
5068 SourceManager &SrcMgr;
5069 bool HasContextSensitiveKeywords;
5070
5071 struct PostChildrenInfo {
5072 CXCursor Cursor;
5073 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005074 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 unsigned BeforeChildrenTokenIdx;
5076 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005077 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei11169dd2012-12-18 14:30:41 +00005078
5079 bool MoreTokens() const { return TokIdx < NumTokens; }
5080 unsigned NextToken() const { return TokIdx; }
5081 void AdvanceToken() { ++TokIdx; }
5082 SourceLocation GetTokenLoc(unsigned tokI) {
5083 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5084 }
5085 bool isFunctionMacroToken(unsigned tokI) const {
5086 return Tokens[tokI].int_data[3] != 0;
5087 }
5088 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5089 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5090 }
5091
5092 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005093 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 SourceRange);
5095
5096public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005097 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005098 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005099 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005101 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 AnnotateTokensVisitor, this,
5103 /*VisitPreprocessorLast=*/true,
5104 /*VisitIncludedEntities=*/false,
5105 RegionOfInterest,
5106 /*VisitDeclsOnly=*/false,
5107 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005108 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 HasContextSensitiveKeywords(false) { }
5110
5111 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5112 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5113 bool postVisitChildren(CXCursor cursor);
5114 void AnnotateTokens();
5115
5116 /// \brief Determine whether the annotator saw any cursors that have
5117 /// context-sensitive keywords.
5118 bool hasContextSensitiveKeywords() const {
5119 return HasContextSensitiveKeywords;
5120 }
5121
5122 ~AnnotateTokensWorker() {
5123 assert(PostChildrenInfos.empty());
5124 }
5125};
5126}
5127
5128void AnnotateTokensWorker::AnnotateTokens() {
5129 // Walk the AST within the region of interest, annotating tokens
5130 // along the way.
5131 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005132}
Guy Benyei11169dd2012-12-18 14:30:41 +00005133
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005134static inline void updateCursorAnnotation(CXCursor &Cursor,
5135 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005136 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005138 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005139}
5140
5141/// \brief It annotates and advances tokens with a cursor until the comparison
5142//// between the cursor location and the source range is the same as
5143/// \arg compResult.
5144///
5145/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5146/// Pass RangeOverlap to annotate tokens inside a range.
5147void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5148 RangeComparisonResult compResult,
5149 SourceRange range) {
5150 while (MoreTokens()) {
5151 const unsigned I = NextToken();
5152 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005153 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5154 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005155
5156 SourceLocation TokLoc = GetTokenLoc(I);
5157 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005158 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 AdvanceToken();
5160 continue;
5161 }
5162 break;
5163 }
5164}
5165
5166/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005167/// \returns true if it advanced beyond all macro tokens, false otherwise.
5168bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 CXCursor updateC,
5170 RangeComparisonResult compResult,
5171 SourceRange range) {
5172 assert(MoreTokens());
5173 assert(isFunctionMacroToken(NextToken()) &&
5174 "Should be called only for macro arg tokens");
5175
5176 // This works differently than annotateAndAdvanceTokens; because expanded
5177 // macro arguments can have arbitrary translation-unit source order, we do not
5178 // advance the token index one by one until a token fails the range test.
5179 // We only advance once past all of the macro arg tokens if all of them
5180 // pass the range test. If one of them fails we keep the token index pointing
5181 // at the start of the macro arg tokens so that the failing token will be
5182 // annotated by a subsequent annotation try.
5183
5184 bool atLeastOneCompFail = false;
5185
5186 unsigned I = NextToken();
5187 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5188 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5189 if (TokLoc.isFileID())
5190 continue; // not macro arg token, it's parens or comma.
5191 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5192 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5193 Cursors[I] = updateC;
5194 } else
5195 atLeastOneCompFail = true;
5196 }
5197
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005198 if (atLeastOneCompFail)
5199 return false;
5200
5201 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5202 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005203}
5204
5205enum CXChildVisitResult
5206AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 SourceRange cursorRange = getRawCursorExtent(cursor);
5208 if (cursorRange.isInvalid())
5209 return CXChildVisit_Recurse;
5210
5211 if (!HasContextSensitiveKeywords) {
5212 // Objective-C properties can have context-sensitive keywords.
5213 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005214 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5216 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5217 }
5218 // Objective-C methods can have context-sensitive keywords.
5219 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5220 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005221 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5223 if (Method->getObjCDeclQualifier())
5224 HasContextSensitiveKeywords = true;
5225 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005226 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5227 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 P != PEnd; ++P) {
5229 if ((*P)->getObjCDeclQualifier()) {
5230 HasContextSensitiveKeywords = true;
5231 break;
5232 }
5233 }
5234 }
5235 }
5236 }
5237 // C++ methods can have context-sensitive keywords.
5238 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005239 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5241 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5242 HasContextSensitiveKeywords = true;
5243 }
5244 }
5245 // C++ classes can have context-sensitive keywords.
5246 else if (cursor.kind == CXCursor_StructDecl ||
5247 cursor.kind == CXCursor_ClassDecl ||
5248 cursor.kind == CXCursor_ClassTemplate ||
5249 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005250 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005251 if (D->hasAttr<FinalAttr>())
5252 HasContextSensitiveKeywords = true;
5253 }
5254 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005255
5256 // Don't override a property annotation with its getter/setter method.
5257 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5258 parent.kind == CXCursor_ObjCPropertyDecl)
5259 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005260
5261 if (clang_isPreprocessing(cursor.kind)) {
5262 // Items in the preprocessing record are kept separate from items in
5263 // declarations, so we keep a separate token index.
5264 unsigned SavedTokIdx = TokIdx;
5265 TokIdx = PreprocessingTokIdx;
5266
5267 // Skip tokens up until we catch up to the beginning of the preprocessing
5268 // entry.
5269 while (MoreTokens()) {
5270 const unsigned I = NextToken();
5271 SourceLocation TokLoc = GetTokenLoc(I);
5272 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5273 case RangeBefore:
5274 AdvanceToken();
5275 continue;
5276 case RangeAfter:
5277 case RangeOverlap:
5278 break;
5279 }
5280 break;
5281 }
5282
5283 // Look at all of the tokens within this range.
5284 while (MoreTokens()) {
5285 const unsigned I = NextToken();
5286 SourceLocation TokLoc = GetTokenLoc(I);
5287 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5288 case RangeBefore:
5289 llvm_unreachable("Infeasible");
5290 case RangeAfter:
5291 break;
5292 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005293 // For macro expansions, just note where the beginning of the macro
5294 // expansion occurs.
5295 if (cursor.kind == CXCursor_MacroExpansion) {
5296 if (TokLoc == cursorRange.getBegin())
5297 Cursors[I] = cursor;
5298 AdvanceToken();
5299 break;
5300 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005301 // We may have already annotated macro names inside macro definitions.
5302 if (Cursors[I].kind != CXCursor_MacroExpansion)
5303 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 continue;
5306 }
5307 break;
5308 }
5309
5310 // Save the preprocessing token index; restore the non-preprocessing
5311 // token index.
5312 PreprocessingTokIdx = TokIdx;
5313 TokIdx = SavedTokIdx;
5314 return CXChildVisit_Recurse;
5315 }
5316
5317 if (cursorRange.isInvalid())
5318 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005319
5320 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 const enum CXCursorKind K = clang_getCursorKind(parent);
5323 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005324 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5325 // Attributes are annotated out-of-order, skip tokens until we reach it.
5326 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 ? clang_getNullCursor() : parent;
5328
5329 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5330
5331 // Avoid having the cursor of an expression "overwrite" the annotation of the
5332 // variable declaration that it belongs to.
5333 // This can happen for C++ constructor expressions whose range generally
5334 // include the variable declaration, e.g.:
5335 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5336 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005337 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005338 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 const unsigned I = NextToken();
5340 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5341 E->getLocStart() == D->getLocation() &&
5342 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005343 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 AdvanceToken();
5345 }
5346 }
5347 }
5348
5349 // Before recursing into the children keep some state that we are going
5350 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5351 // extra work after the child nodes are visited.
5352 // Note that we don't call VisitChildren here to avoid traversing statements
5353 // code-recursively which can blow the stack.
5354
5355 PostChildrenInfo Info;
5356 Info.Cursor = cursor;
5357 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005358 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 Info.BeforeChildrenTokenIdx = NextToken();
5360 PostChildrenInfos.push_back(Info);
5361
5362 return CXChildVisit_Recurse;
5363}
5364
5365bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5366 if (PostChildrenInfos.empty())
5367 return false;
5368 const PostChildrenInfo &Info = PostChildrenInfos.back();
5369 if (!clang_equalCursors(Info.Cursor, cursor))
5370 return false;
5371
5372 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5373 const unsigned AfterChildren = NextToken();
5374 SourceRange cursorRange = Info.CursorRange;
5375
5376 // Scan the tokens that are at the end of the cursor, but are not captured
5377 // but the child cursors.
5378 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5379
5380 // Scan the tokens that are at the beginning of the cursor, but are not
5381 // capture by the child cursors.
5382 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5383 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5384 break;
5385
5386 Cursors[I] = cursor;
5387 }
5388
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005389 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5390 // encountered the attribute cursor.
5391 if (clang_isAttribute(cursor.kind))
5392 TokIdx = Info.BeforeReachingCursorIdx;
5393
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 PostChildrenInfos.pop_back();
5395 return false;
5396}
5397
5398static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5399 CXCursor parent,
5400 CXClientData client_data) {
5401 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5402}
5403
5404static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5405 CXClientData client_data) {
5406 return static_cast<AnnotateTokensWorker*>(client_data)->
5407 postVisitChildren(cursor);
5408}
5409
5410namespace {
5411
5412/// \brief Uses the macro expansions in the preprocessing record to find
5413/// and mark tokens that are macro arguments. This info is used by the
5414/// AnnotateTokensWorker.
5415class MarkMacroArgTokensVisitor {
5416 SourceManager &SM;
5417 CXToken *Tokens;
5418 unsigned NumTokens;
5419 unsigned CurIdx;
5420
5421public:
5422 MarkMacroArgTokensVisitor(SourceManager &SM,
5423 CXToken *tokens, unsigned numTokens)
5424 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5425
5426 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5427 if (cursor.kind != CXCursor_MacroExpansion)
5428 return CXChildVisit_Continue;
5429
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005430 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 if (macroRange.getBegin() == macroRange.getEnd())
5432 return CXChildVisit_Continue; // it's not a function macro.
5433
5434 for (; CurIdx < NumTokens; ++CurIdx) {
5435 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5436 macroRange.getBegin()))
5437 break;
5438 }
5439
5440 if (CurIdx == NumTokens)
5441 return CXChildVisit_Break;
5442
5443 for (; CurIdx < NumTokens; ++CurIdx) {
5444 SourceLocation tokLoc = getTokenLoc(CurIdx);
5445 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5446 break;
5447
5448 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5449 }
5450
5451 if (CurIdx == NumTokens)
5452 return CXChildVisit_Break;
5453
5454 return CXChildVisit_Continue;
5455 }
5456
5457private:
5458 SourceLocation getTokenLoc(unsigned tokI) {
5459 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5460 }
5461
5462 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5463 // The third field is reserved and currently not used. Use it here
5464 // to mark macro arg expanded tokens with their expanded locations.
5465 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5466 }
5467};
5468
5469} // end anonymous namespace
5470
5471static CXChildVisitResult
5472MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5473 CXClientData client_data) {
5474 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5475 parent);
5476}
5477
5478namespace {
5479 struct clang_annotateTokens_Data {
5480 CXTranslationUnit TU;
5481 ASTUnit *CXXUnit;
5482 CXToken *Tokens;
5483 unsigned NumTokens;
5484 CXCursor *Cursors;
5485 };
5486}
5487
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005488/// \brief Used by \c annotatePreprocessorTokens.
5489/// \returns true if lexing was finished, false otherwise.
5490static bool lexNext(Lexer &Lex, Token &Tok,
5491 unsigned &NextIdx, unsigned NumTokens) {
5492 if (NextIdx >= NumTokens)
5493 return true;
5494
5495 ++NextIdx;
5496 Lex.LexFromRawLexer(Tok);
5497 if (Tok.is(tok::eof))
5498 return true;
5499
5500 return false;
5501}
5502
Guy Benyei11169dd2012-12-18 14:30:41 +00005503static void annotatePreprocessorTokens(CXTranslationUnit TU,
5504 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005505 CXCursor *Cursors,
5506 CXToken *Tokens,
5507 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005508 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005509
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005510 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5512 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005513 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005515 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005516
5517 if (BeginLocInfo.first != EndLocInfo.first)
5518 return;
5519
5520 StringRef Buffer;
5521 bool Invalid = false;
5522 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5523 if (Buffer.empty() || Invalid)
5524 return;
5525
5526 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5527 CXXUnit->getASTContext().getLangOpts(),
5528 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5529 Buffer.end());
5530 Lex.SetCommentRetentionState(true);
5531
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005532 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 // Lex tokens in raw mode until we hit the end of the range, to avoid
5534 // entering #includes or expanding macros.
5535 while (true) {
5536 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005537 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5538 break;
5539 unsigned TokIdx = NextIdx-1;
5540 assert(Tok.getLocation() ==
5541 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005542
5543 reprocess:
5544 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005545 // We have found a preprocessing directive. Annotate the tokens
5546 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 //
5548 // FIXME: Some simple tests here could identify macro definitions and
5549 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005550
5551 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005552 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5553 break;
5554
5555 MacroInfo *MI = 0;
5556 if (Tok.is(tok::raw_identifier) &&
5557 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5558 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5559 break;
5560
5561 if (Tok.is(tok::raw_identifier)) {
5562 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5563 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5564 SourceLocation MappedTokLoc =
5565 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5566 MI = getMacroInfo(II, MappedTokLoc, TU);
5567 }
5568 }
5569
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005570 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005572 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5573 finished = true;
5574 break;
5575 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005576 // If we are in a macro definition, check if the token was ever a
5577 // macro name and annotate it if that's the case.
5578 if (MI) {
5579 SourceLocation SaveLoc = Tok.getLocation();
5580 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5581 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5582 Tok.setLocation(SaveLoc);
5583 if (MacroDef)
5584 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5585 Tok.getLocation(), TU);
5586 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005587 } while (!Tok.isAtStartOfLine());
5588
5589 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5590 assert(TokIdx <= LastIdx);
5591 SourceLocation EndLoc =
5592 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5593 CXCursor Cursor =
5594 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5595
5596 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005597 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005598
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005599 if (finished)
5600 break;
5601 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 }
5604}
5605
5606// This gets run a separate thread to avoid stack blowout.
5607static void clang_annotateTokensImpl(void *UserData) {
5608 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5609 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5610 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5611 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5612 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5613
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005614 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5616 setThreadBackgroundPriority();
5617
5618 // Determine the region of interest, which contains all of the tokens.
5619 SourceRange RegionOfInterest;
5620 RegionOfInterest.setBegin(
5621 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5622 RegionOfInterest.setEnd(
5623 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5624 Tokens[NumTokens-1])));
5625
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 // Relex the tokens within the source range to look for preprocessing
5627 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005628 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005629
5630 // If begin location points inside a macro argument, set it to the expansion
5631 // location so we can have the full context when annotating semantically.
5632 {
5633 SourceManager &SM = CXXUnit->getSourceManager();
5634 SourceLocation Loc =
5635 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5636 if (Loc.isMacroID())
5637 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5638 }
5639
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5641 // Search and mark tokens that are macro argument expansions.
5642 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5643 Tokens, NumTokens);
5644 CursorVisitor MacroArgMarker(TU,
5645 MarkMacroArgTokensVisitorDelegate, &Visitor,
5646 /*VisitPreprocessorLast=*/true,
5647 /*VisitIncludedEntities=*/false,
5648 RegionOfInterest);
5649 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5650 }
5651
5652 // Annotate all of the source locations in the region of interest that map to
5653 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005654 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005655
5656 // FIXME: We use a ridiculous stack size here because the data-recursion
5657 // algorithm uses a large stack frame than the non-data recursive version,
5658 // and AnnotationTokensWorker currently transforms the data-recursion
5659 // algorithm back into a traditional recursion by explicitly calling
5660 // VisitChildren(). We will need to remove this explicit recursive call.
5661 W.AnnotateTokens();
5662
5663 // If we ran into any entities that involve context-sensitive keywords,
5664 // take another pass through the tokens to mark them as such.
5665 if (W.hasContextSensitiveKeywords()) {
5666 for (unsigned I = 0; I != NumTokens; ++I) {
5667 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5668 continue;
5669
5670 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5671 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005672 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5674 if (Property->getPropertyAttributesAsWritten() != 0 &&
5675 llvm::StringSwitch<bool>(II->getName())
5676 .Case("readonly", true)
5677 .Case("assign", true)
5678 .Case("unsafe_unretained", true)
5679 .Case("readwrite", true)
5680 .Case("retain", true)
5681 .Case("copy", true)
5682 .Case("nonatomic", true)
5683 .Case("atomic", true)
5684 .Case("getter", true)
5685 .Case("setter", true)
5686 .Case("strong", true)
5687 .Case("weak", true)
5688 .Default(false))
5689 Tokens[I].int_data[0] = CXToken_Keyword;
5690 }
5691 continue;
5692 }
5693
5694 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5695 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5696 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5697 if (llvm::StringSwitch<bool>(II->getName())
5698 .Case("in", true)
5699 .Case("out", true)
5700 .Case("inout", true)
5701 .Case("oneway", true)
5702 .Case("bycopy", true)
5703 .Case("byref", true)
5704 .Default(false))
5705 Tokens[I].int_data[0] = CXToken_Keyword;
5706 continue;
5707 }
5708
5709 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5710 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5711 Tokens[I].int_data[0] = CXToken_Keyword;
5712 continue;
5713 }
5714 }
5715 }
5716}
5717
5718extern "C" {
5719
5720void clang_annotateTokens(CXTranslationUnit TU,
5721 CXToken *Tokens, unsigned NumTokens,
5722 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005723 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005724 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005726 }
5727
5728 LOG_FUNC_SECTION {
5729 *Log << TU << ' ';
5730 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5731 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5732 *Log << clang_getRange(bloc, eloc);
5733 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005734
5735 // Any token we don't specifically annotate will have a NULL cursor.
5736 CXCursor C = clang_getNullCursor();
5737 for (unsigned I = 0; I != NumTokens; ++I)
5738 Cursors[I] = C;
5739
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005740 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 if (!CXXUnit)
5742 return;
5743
5744 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5745
5746 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5747 llvm::CrashRecoveryContext CRC;
5748 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5749 GetSafetyThreadStackSize() * 2)) {
5750 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5751 }
5752}
5753
5754} // end: extern "C"
5755
5756//===----------------------------------------------------------------------===//
5757// Operations for querying linkage of a cursor.
5758//===----------------------------------------------------------------------===//
5759
5760extern "C" {
5761CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5762 if (!clang_isDeclaration(cursor.kind))
5763 return CXLinkage_Invalid;
5764
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005765 const Decl *D = cxcursor::getCursorDecl(cursor);
5766 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005767 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005768 case NoLinkage:
5769 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 case InternalLinkage: return CXLinkage_Internal;
5771 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5772 case ExternalLinkage: return CXLinkage_External;
5773 };
5774
5775 return CXLinkage_Invalid;
5776}
5777} // end: extern "C"
5778
5779//===----------------------------------------------------------------------===//
5780// Operations for querying language of a cursor.
5781//===----------------------------------------------------------------------===//
5782
5783static CXLanguageKind getDeclLanguage(const Decl *D) {
5784 if (!D)
5785 return CXLanguage_C;
5786
5787 switch (D->getKind()) {
5788 default:
5789 break;
5790 case Decl::ImplicitParam:
5791 case Decl::ObjCAtDefsField:
5792 case Decl::ObjCCategory:
5793 case Decl::ObjCCategoryImpl:
5794 case Decl::ObjCCompatibleAlias:
5795 case Decl::ObjCImplementation:
5796 case Decl::ObjCInterface:
5797 case Decl::ObjCIvar:
5798 case Decl::ObjCMethod:
5799 case Decl::ObjCProperty:
5800 case Decl::ObjCPropertyImpl:
5801 case Decl::ObjCProtocol:
5802 return CXLanguage_ObjC;
5803 case Decl::CXXConstructor:
5804 case Decl::CXXConversion:
5805 case Decl::CXXDestructor:
5806 case Decl::CXXMethod:
5807 case Decl::CXXRecord:
5808 case Decl::ClassTemplate:
5809 case Decl::ClassTemplatePartialSpecialization:
5810 case Decl::ClassTemplateSpecialization:
5811 case Decl::Friend:
5812 case Decl::FriendTemplate:
5813 case Decl::FunctionTemplate:
5814 case Decl::LinkageSpec:
5815 case Decl::Namespace:
5816 case Decl::NamespaceAlias:
5817 case Decl::NonTypeTemplateParm:
5818 case Decl::StaticAssert:
5819 case Decl::TemplateTemplateParm:
5820 case Decl::TemplateTypeParm:
5821 case Decl::UnresolvedUsingTypename:
5822 case Decl::UnresolvedUsingValue:
5823 case Decl::Using:
5824 case Decl::UsingDirective:
5825 case Decl::UsingShadow:
5826 return CXLanguage_CPlusPlus;
5827 }
5828
5829 return CXLanguage_C;
5830}
5831
5832extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005833
5834static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5835 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5836 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005837
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005838 switch (D->getAvailability()) {
5839 case AR_Available:
5840 case AR_NotYetIntroduced:
5841 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005842 return getCursorAvailabilityForDecl(
5843 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005844 return CXAvailability_Available;
5845
5846 case AR_Deprecated:
5847 return CXAvailability_Deprecated;
5848
5849 case AR_Unavailable:
5850 return CXAvailability_NotAvailable;
5851 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005852
5853 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005854}
5855
Guy Benyei11169dd2012-12-18 14:30:41 +00005856enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5857 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005858 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5859 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005860
5861 return CXAvailability_Available;
5862}
5863
5864static CXVersion convertVersion(VersionTuple In) {
5865 CXVersion Out = { -1, -1, -1 };
5866 if (In.empty())
5867 return Out;
5868
5869 Out.Major = In.getMajor();
5870
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005871 Optional<unsigned> Minor = In.getMinor();
5872 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 Out.Minor = *Minor;
5874 else
5875 return Out;
5876
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005877 Optional<unsigned> Subminor = In.getSubminor();
5878 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 Out.Subminor = *Subminor;
5880
5881 return Out;
5882}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005883
5884static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5885 int *always_deprecated,
5886 CXString *deprecated_message,
5887 int *always_unavailable,
5888 CXString *unavailable_message,
5889 CXPlatformAvailability *availability,
5890 int availability_size) {
5891 bool HadAvailAttr = false;
5892 int N = 0;
5893 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5894 ++A) {
5895 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5896 HadAvailAttr = true;
5897 if (always_deprecated)
5898 *always_deprecated = 1;
5899 if (deprecated_message)
5900 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5901 continue;
5902 }
5903
5904 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5905 HadAvailAttr = true;
5906 if (always_unavailable)
5907 *always_unavailable = 1;
5908 if (unavailable_message) {
5909 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5910 }
5911 continue;
5912 }
5913
5914 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5915 HadAvailAttr = true;
5916 if (N < availability_size) {
5917 availability[N].Platform
5918 = cxstring::createDup(Avail->getPlatform()->getName());
5919 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5920 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5921 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5922 availability[N].Unavailable = Avail->getUnavailable();
5923 availability[N].Message = cxstring::createDup(Avail->getMessage());
5924 }
5925 ++N;
5926 }
5927 }
5928
5929 if (!HadAvailAttr)
5930 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5931 return getCursorPlatformAvailabilityForDecl(
5932 cast<Decl>(EnumConst->getDeclContext()),
5933 always_deprecated,
5934 deprecated_message,
5935 always_unavailable,
5936 unavailable_message,
5937 availability,
5938 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005939
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005940 return N;
5941}
5942
Guy Benyei11169dd2012-12-18 14:30:41 +00005943int clang_getCursorPlatformAvailability(CXCursor cursor,
5944 int *always_deprecated,
5945 CXString *deprecated_message,
5946 int *always_unavailable,
5947 CXString *unavailable_message,
5948 CXPlatformAvailability *availability,
5949 int availability_size) {
5950 if (always_deprecated)
5951 *always_deprecated = 0;
5952 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005953 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005954 if (always_unavailable)
5955 *always_unavailable = 0;
5956 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005957 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005958
Guy Benyei11169dd2012-12-18 14:30:41 +00005959 if (!clang_isDeclaration(cursor.kind))
5960 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005961
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005962 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 if (!D)
5964 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005965
5966 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5967 deprecated_message,
5968 always_unavailable,
5969 unavailable_message,
5970 availability,
5971 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005972}
5973
5974void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5975 clang_disposeString(availability->Platform);
5976 clang_disposeString(availability->Message);
5977}
5978
5979CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5980 if (clang_isDeclaration(cursor.kind))
5981 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5982
5983 return CXLanguage_Invalid;
5984}
5985
5986 /// \brief If the given cursor is the "templated" declaration
5987 /// descibing a class or function template, return the class or
5988 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005989static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 if (!D)
5991 return 0;
5992
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005993 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5995 return FunTmpl;
5996
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005997 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5999 return ClassTmpl;
6000
6001 return D;
6002}
6003
6004CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6005 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006006 if (const Decl *D = getCursorDecl(cursor)) {
6007 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 if (!DC)
6009 return clang_getNullCursor();
6010
6011 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6012 getCursorTU(cursor));
6013 }
6014 }
6015
6016 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006017 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 return MakeCXCursor(D, getCursorTU(cursor));
6019 }
6020
6021 return clang_getNullCursor();
6022}
6023
6024CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6025 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006026 if (const Decl *D = getCursorDecl(cursor)) {
6027 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006028 if (!DC)
6029 return clang_getNullCursor();
6030
6031 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6032 getCursorTU(cursor));
6033 }
6034 }
6035
6036 // FIXME: Note that we can't easily compute the lexical context of a
6037 // statement or expression, so we return nothing.
6038 return clang_getNullCursor();
6039}
6040
6041CXFile clang_getIncludedFile(CXCursor cursor) {
6042 if (cursor.kind != CXCursor_InclusionDirective)
6043 return 0;
6044
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006045 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006046 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006047}
6048
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006049unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6050 if (C.kind != CXCursor_ObjCPropertyDecl)
6051 return CXObjCPropertyAttr_noattr;
6052
6053 unsigned Result = CXObjCPropertyAttr_noattr;
6054 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6055 ObjCPropertyDecl::PropertyAttributeKind Attr =
6056 PD->getPropertyAttributesAsWritten();
6057
6058#define SET_CXOBJCPROP_ATTR(A) \
6059 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6060 Result |= CXObjCPropertyAttr_##A
6061 SET_CXOBJCPROP_ATTR(readonly);
6062 SET_CXOBJCPROP_ATTR(getter);
6063 SET_CXOBJCPROP_ATTR(assign);
6064 SET_CXOBJCPROP_ATTR(readwrite);
6065 SET_CXOBJCPROP_ATTR(retain);
6066 SET_CXOBJCPROP_ATTR(copy);
6067 SET_CXOBJCPROP_ATTR(nonatomic);
6068 SET_CXOBJCPROP_ATTR(setter);
6069 SET_CXOBJCPROP_ATTR(atomic);
6070 SET_CXOBJCPROP_ATTR(weak);
6071 SET_CXOBJCPROP_ATTR(strong);
6072 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6073#undef SET_CXOBJCPROP_ATTR
6074
6075 return Result;
6076}
6077
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006078unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6079 if (!clang_isDeclaration(C.kind))
6080 return CXObjCDeclQualifier_None;
6081
6082 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6083 const Decl *D = getCursorDecl(C);
6084 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6085 QT = MD->getObjCDeclQualifier();
6086 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6087 QT = PD->getObjCDeclQualifier();
6088 if (QT == Decl::OBJC_TQ_None)
6089 return CXObjCDeclQualifier_None;
6090
6091 unsigned Result = CXObjCDeclQualifier_None;
6092 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6093 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6094 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6095 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6096 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6097 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6098
6099 return Result;
6100}
6101
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006102unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6103 if (!clang_isDeclaration(C.kind))
6104 return 0;
6105
6106 const Decl *D = getCursorDecl(C);
6107 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6108 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6109 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6110 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6111
6112 return 0;
6113}
6114
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006115unsigned clang_Cursor_isVariadic(CXCursor C) {
6116 if (!clang_isDeclaration(C.kind))
6117 return 0;
6118
6119 const Decl *D = getCursorDecl(C);
6120 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6121 return FD->isVariadic();
6122 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6123 return MD->isVariadic();
6124
6125 return 0;
6126}
6127
Guy Benyei11169dd2012-12-18 14:30:41 +00006128CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6129 if (!clang_isDeclaration(C.kind))
6130 return clang_getNullRange();
6131
6132 const Decl *D = getCursorDecl(C);
6133 ASTContext &Context = getCursorContext(C);
6134 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6135 if (!RC)
6136 return clang_getNullRange();
6137
6138 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6139}
6140
6141CXString clang_Cursor_getRawCommentText(CXCursor C) {
6142 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006143 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006144
6145 const Decl *D = getCursorDecl(C);
6146 ASTContext &Context = getCursorContext(C);
6147 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6148 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6149 StringRef();
6150
6151 // Don't duplicate the string because RawText points directly into source
6152 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006153 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006154}
6155
6156CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6157 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006158 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006159
6160 const Decl *D = getCursorDecl(C);
6161 const ASTContext &Context = getCursorContext(C);
6162 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6163
6164 if (RC) {
6165 StringRef BriefText = RC->getBriefText(Context);
6166
6167 // Don't duplicate the string because RawComment ensures that this memory
6168 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006169 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 }
6171
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006172 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006173}
6174
6175CXComment clang_Cursor_getParsedComment(CXCursor C) {
6176 if (!clang_isDeclaration(C.kind))
6177 return cxcomment::createCXComment(NULL, NULL);
6178
6179 const Decl *D = getCursorDecl(C);
6180 const ASTContext &Context = getCursorContext(C);
6181 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6182
6183 return cxcomment::createCXComment(FC, getCursorTU(C));
6184}
6185
6186CXModule clang_Cursor_getModule(CXCursor C) {
6187 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006188 if (const ImportDecl *ImportD =
6189 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 return ImportD->getImportedModule();
6191 }
6192
6193 return 0;
6194}
6195
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006196CXFile clang_Module_getASTFile(CXModule CXMod) {
6197 if (!CXMod)
6198 return 0;
6199 Module *Mod = static_cast<Module*>(CXMod);
6200 return const_cast<FileEntry *>(Mod->getASTFile());
6201}
6202
Guy Benyei11169dd2012-12-18 14:30:41 +00006203CXModule clang_Module_getParent(CXModule CXMod) {
6204 if (!CXMod)
6205 return 0;
6206 Module *Mod = static_cast<Module*>(CXMod);
6207 return Mod->Parent;
6208}
6209
6210CXString clang_Module_getName(CXModule CXMod) {
6211 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006212 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006214 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006215}
6216
6217CXString clang_Module_getFullName(CXModule CXMod) {
6218 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006219 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006221 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006222}
6223
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006224unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6225 CXModule CXMod) {
6226 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 return 0;
6228 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006229 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6230 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6231 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006232}
6233
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006234CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6235 CXModule CXMod, unsigned Index) {
6236 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006237 return 0;
6238 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006239 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006240
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006241 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6242 if (Index < TopHeaders.size())
6243 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006244
6245 return 0;
6246}
6247
6248} // end: extern "C"
6249
6250//===----------------------------------------------------------------------===//
6251// C++ AST instrospection.
6252//===----------------------------------------------------------------------===//
6253
6254extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006255unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6256 if (!clang_isDeclaration(C.kind))
6257 return 0;
6258
6259 const CXXMethodDecl *Method = 0;
6260 const Decl *D = cxcursor::getCursorDecl(C);
6261 if (const FunctionTemplateDecl *FunTmpl =
6262 dyn_cast_or_null<FunctionTemplateDecl>(D))
6263 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6264 else
6265 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6266 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6267}
6268
Guy Benyei11169dd2012-12-18 14:30:41 +00006269unsigned clang_CXXMethod_isStatic(CXCursor C) {
6270 if (!clang_isDeclaration(C.kind))
6271 return 0;
6272
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006273 const CXXMethodDecl *Method = 0;
6274 const Decl *D = cxcursor::getCursorDecl(C);
6275 if (const FunctionTemplateDecl *FunTmpl =
6276 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006277 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6278 else
6279 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6280 return (Method && Method->isStatic()) ? 1 : 0;
6281}
6282
6283unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6284 if (!clang_isDeclaration(C.kind))
6285 return 0;
6286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006287 const CXXMethodDecl *Method = 0;
6288 const Decl *D = cxcursor::getCursorDecl(C);
6289 if (const FunctionTemplateDecl *FunTmpl =
6290 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6292 else
6293 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6294 return (Method && Method->isVirtual()) ? 1 : 0;
6295}
6296} // end: extern "C"
6297
6298//===----------------------------------------------------------------------===//
6299// Attribute introspection.
6300//===----------------------------------------------------------------------===//
6301
6302extern "C" {
6303CXType clang_getIBOutletCollectionType(CXCursor C) {
6304 if (C.kind != CXCursor_IBOutletCollectionAttr)
6305 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6306
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006307 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6309
6310 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6311}
6312} // end: extern "C"
6313
6314//===----------------------------------------------------------------------===//
6315// Inspecting memory usage.
6316//===----------------------------------------------------------------------===//
6317
6318typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6319
6320static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6321 enum CXTUResourceUsageKind k,
6322 unsigned long amount) {
6323 CXTUResourceUsageEntry entry = { k, amount };
6324 entries.push_back(entry);
6325}
6326
6327extern "C" {
6328
6329const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6330 const char *str = "";
6331 switch (kind) {
6332 case CXTUResourceUsage_AST:
6333 str = "ASTContext: expressions, declarations, and types";
6334 break;
6335 case CXTUResourceUsage_Identifiers:
6336 str = "ASTContext: identifiers";
6337 break;
6338 case CXTUResourceUsage_Selectors:
6339 str = "ASTContext: selectors";
6340 break;
6341 case CXTUResourceUsage_GlobalCompletionResults:
6342 str = "Code completion: cached global results";
6343 break;
6344 case CXTUResourceUsage_SourceManagerContentCache:
6345 str = "SourceManager: content cache allocator";
6346 break;
6347 case CXTUResourceUsage_AST_SideTables:
6348 str = "ASTContext: side tables";
6349 break;
6350 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6351 str = "SourceManager: malloc'ed memory buffers";
6352 break;
6353 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6354 str = "SourceManager: mmap'ed memory buffers";
6355 break;
6356 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6357 str = "ExternalASTSource: malloc'ed memory buffers";
6358 break;
6359 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6360 str = "ExternalASTSource: mmap'ed memory buffers";
6361 break;
6362 case CXTUResourceUsage_Preprocessor:
6363 str = "Preprocessor: malloc'ed memory";
6364 break;
6365 case CXTUResourceUsage_PreprocessingRecord:
6366 str = "Preprocessor: PreprocessingRecord";
6367 break;
6368 case CXTUResourceUsage_SourceManager_DataStructures:
6369 str = "SourceManager: data structures and tables";
6370 break;
6371 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6372 str = "Preprocessor: header search tables";
6373 break;
6374 }
6375 return str;
6376}
6377
6378CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6379 if (!TU) {
6380 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6381 return usage;
6382 }
6383
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006384 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006385 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6386 ASTContext &astContext = astUnit->getASTContext();
6387
6388 // How much memory is used by AST nodes and types?
6389 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6390 (unsigned long) astContext.getASTAllocatedMemory());
6391
6392 // How much memory is used by identifiers?
6393 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6394 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6395
6396 // How much memory is used for selectors?
6397 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6398 (unsigned long) astContext.Selectors.getTotalMemory());
6399
6400 // How much memory is used by ASTContext's side tables?
6401 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6402 (unsigned long) astContext.getSideTableAllocatedMemory());
6403
6404 // How much memory is used for caching global code completion results?
6405 unsigned long completionBytes = 0;
6406 if (GlobalCodeCompletionAllocator *completionAllocator =
6407 astUnit->getCachedCompletionAllocator().getPtr()) {
6408 completionBytes = completionAllocator->getTotalMemory();
6409 }
6410 createCXTUResourceUsageEntry(*entries,
6411 CXTUResourceUsage_GlobalCompletionResults,
6412 completionBytes);
6413
6414 // How much memory is being used by SourceManager's content cache?
6415 createCXTUResourceUsageEntry(*entries,
6416 CXTUResourceUsage_SourceManagerContentCache,
6417 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6418
6419 // How much memory is being used by the MemoryBuffer's in SourceManager?
6420 const SourceManager::MemoryBufferSizes &srcBufs =
6421 astUnit->getSourceManager().getMemoryBufferSizes();
6422
6423 createCXTUResourceUsageEntry(*entries,
6424 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6425 (unsigned long) srcBufs.malloc_bytes);
6426 createCXTUResourceUsageEntry(*entries,
6427 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6428 (unsigned long) srcBufs.mmap_bytes);
6429 createCXTUResourceUsageEntry(*entries,
6430 CXTUResourceUsage_SourceManager_DataStructures,
6431 (unsigned long) astContext.getSourceManager()
6432 .getDataStructureSizes());
6433
6434 // How much memory is being used by the ExternalASTSource?
6435 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6436 const ExternalASTSource::MemoryBufferSizes &sizes =
6437 esrc->getMemoryBufferSizes();
6438
6439 createCXTUResourceUsageEntry(*entries,
6440 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6441 (unsigned long) sizes.malloc_bytes);
6442 createCXTUResourceUsageEntry(*entries,
6443 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6444 (unsigned long) sizes.mmap_bytes);
6445 }
6446
6447 // How much memory is being used by the Preprocessor?
6448 Preprocessor &pp = astUnit->getPreprocessor();
6449 createCXTUResourceUsageEntry(*entries,
6450 CXTUResourceUsage_Preprocessor,
6451 pp.getTotalMemory());
6452
6453 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6454 createCXTUResourceUsageEntry(*entries,
6455 CXTUResourceUsage_PreprocessingRecord,
6456 pRec->getTotalMemory());
6457 }
6458
6459 createCXTUResourceUsageEntry(*entries,
6460 CXTUResourceUsage_Preprocessor_HeaderSearch,
6461 pp.getHeaderSearchInfo().getTotalMemory());
6462
6463 CXTUResourceUsage usage = { (void*) entries.get(),
6464 (unsigned) entries->size(),
6465 entries->size() ? &(*entries)[0] : 0 };
6466 entries.take();
6467 return usage;
6468}
6469
6470void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6471 if (usage.data)
6472 delete (MemUsageEntries*) usage.data;
6473}
6474
6475} // end extern "C"
6476
6477void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6478 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6479 for (unsigned I = 0; I != Usage.numEntries; ++I)
6480 fprintf(stderr, " %s: %lu\n",
6481 clang_getTUResourceUsageName(Usage.entries[I].kind),
6482 Usage.entries[I].amount);
6483
6484 clang_disposeCXTUResourceUsage(Usage);
6485}
6486
6487//===----------------------------------------------------------------------===//
6488// Misc. utility functions.
6489//===----------------------------------------------------------------------===//
6490
6491/// Default to using an 8 MB stack size on "safety" threads.
6492static unsigned SafetyStackThreadSize = 8 << 20;
6493
6494namespace clang {
6495
6496bool RunSafely(llvm::CrashRecoveryContext &CRC,
6497 void (*Fn)(void*), void *UserData,
6498 unsigned Size) {
6499 if (!Size)
6500 Size = GetSafetyThreadStackSize();
6501 if (Size)
6502 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6503 return CRC.RunSafely(Fn, UserData);
6504}
6505
6506unsigned GetSafetyThreadStackSize() {
6507 return SafetyStackThreadSize;
6508}
6509
6510void SetSafetyThreadStackSize(unsigned Value) {
6511 SafetyStackThreadSize = Value;
6512}
6513
6514}
6515
6516void clang::setThreadBackgroundPriority() {
6517 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6518 return;
6519
6520 // FIXME: Move to llvm/Support and make it cross-platform.
6521#ifdef __APPLE__
6522 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6523#endif
6524}
6525
6526void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6527 if (!Unit)
6528 return;
6529
6530 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6531 DEnd = Unit->stored_diag_end();
6532 D != DEnd; ++D) {
6533 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6534 CXString Msg = clang_formatDiagnostic(&Diag,
6535 clang_defaultDiagnosticDisplayOptions());
6536 fprintf(stderr, "%s\n", clang_getCString(Msg));
6537 clang_disposeString(Msg);
6538 }
6539#ifdef LLVM_ON_WIN32
6540 // On Windows, force a flush, since there may be multiple copies of
6541 // stderr and stdout in the file system, all with different buffers
6542 // but writing to the same device.
6543 fflush(stderr);
6544#endif
6545}
6546
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006547MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6548 SourceLocation MacroDefLoc,
6549 CXTranslationUnit TU){
6550 if (MacroDefLoc.isInvalid() || !TU)
6551 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006552 if (!II.hadMacroDefinition())
6553 return 0;
6554
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006555 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006556 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006557 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006558 if (MD) {
6559 for (MacroDirective::DefInfo
6560 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6561 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6562 return Def.getMacroInfo();
6563 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006564 }
6565
6566 return 0;
6567}
6568
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006569const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6570 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006571 if (!MacroDef || !TU)
6572 return 0;
6573 const IdentifierInfo *II = MacroDef->getName();
6574 if (!II)
6575 return 0;
6576
6577 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6578}
6579
6580MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6581 const Token &Tok,
6582 CXTranslationUnit TU) {
6583 if (!MI || !TU)
6584 return 0;
6585 if (Tok.isNot(tok::raw_identifier))
6586 return 0;
6587
6588 if (MI->getNumTokens() == 0)
6589 return 0;
6590 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6591 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006592 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006593
6594 // Check that the token is inside the definition and not its argument list.
6595 SourceManager &SM = Unit->getSourceManager();
6596 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6597 return 0;
6598 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6599 return 0;
6600
6601 Preprocessor &PP = Unit->getPreprocessor();
6602 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6603 if (!PPRec)
6604 return 0;
6605
6606 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6607 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6608 if (!II.hadMacroDefinition())
6609 return 0;
6610
6611 // Check that the identifier is not one of the macro arguments.
6612 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6613 return 0;
6614
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006615 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6616 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006617 return 0;
6618
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006619 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006620}
6621
6622MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6623 SourceLocation Loc,
6624 CXTranslationUnit TU) {
6625 if (Loc.isInvalid() || !MI || !TU)
6626 return 0;
6627
6628 if (MI->getNumTokens() == 0)
6629 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006630 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006631 Preprocessor &PP = Unit->getPreprocessor();
6632 if (!PP.getPreprocessingRecord())
6633 return 0;
6634 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6635 Token Tok;
6636 if (PP.getRawToken(Loc, Tok))
6637 return 0;
6638
6639 return checkForMacroInMacroDefinition(MI, Tok, TU);
6640}
6641
Guy Benyei11169dd2012-12-18 14:30:41 +00006642extern "C" {
6643
6644CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006645 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006646}
6647
6648} // end: extern "C"
6649
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006650Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6651 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006652 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006653 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006654 if (Unit->isMainFileAST())
6655 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006656 return *this;
6657 }
6658 }
6659
6660 LogOS << "<NULL TU>";
6661 return *this;
6662}
6663
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006664Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6665 *this << FE->getName();
6666 return *this;
6667}
6668
6669Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6670 CXString cursorName = clang_getCursorDisplayName(cursor);
6671 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6672 clang_disposeString(cursorName);
6673 return *this;
6674}
6675
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006676Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6677 CXFile File;
6678 unsigned Line, Column;
6679 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6680 CXString FileName = clang_getFileName(File);
6681 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6682 clang_disposeString(FileName);
6683 return *this;
6684}
6685
6686Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6687 CXSourceLocation BLoc = clang_getRangeStart(range);
6688 CXSourceLocation ELoc = clang_getRangeEnd(range);
6689
6690 CXFile BFile;
6691 unsigned BLine, BColumn;
6692 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6693
6694 CXFile EFile;
6695 unsigned ELine, EColumn;
6696 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6697
6698 CXString BFileName = clang_getFileName(BFile);
6699 if (BFile == EFile) {
6700 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6701 BLine, BColumn, ELine, EColumn);
6702 } else {
6703 CXString EFileName = clang_getFileName(EFile);
6704 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6705 BLine, BColumn)
6706 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6707 ELine, EColumn);
6708 clang_disposeString(EFileName);
6709 }
6710 clang_disposeString(BFileName);
6711 return *this;
6712}
6713
6714Logger &cxindex::Logger::operator<<(CXString Str) {
6715 *this << clang_getCString(Str);
6716 return *this;
6717}
6718
6719Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6720 LogOS << Fmt;
6721 return *this;
6722}
6723
6724cxindex::Logger::~Logger() {
6725 LogOS.flush();
6726
6727 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6728
6729 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6730
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006731 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006732 OS << "[libclang:" << Name << ':';
6733
6734 // FIXME: Portability.
6735#if HAVE_PTHREAD_H && __APPLE__
6736 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6737 OS << tid << ':';
6738#endif
6739
6740 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6741 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6742 OS << Msg.str() << '\n';
6743
6744 if (Trace) {
6745 llvm::sys::PrintStackTrace(stderr);
6746 OS << "--------------------------------------------------\n";
6747 }
6748}