blob: 0a8a06899833f34cb2acb1e6d5c595d8f0e6524b [file] [log] [blame]
Guy Benyei7f92f2d2012-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 Carruthb1ba0ef2013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei7f92f2d2012-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"
Fariborz Jahanian88b95212012-12-18 23:02:59 +000025#include "SimpleFormatContext.h"
Guy Benyei7f92f2d2012-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"
32#include "clang/Lex/HeaderSearch.h"
33#include "clang/Lex/Lexer.h"
34#include "clang/Lex/PreprocessingRecord.h"
35#include "clang/Lex/Preprocessor.h"
36#include "llvm/ADT/Optional.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringSwitch.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000039#include "llvm/Config/config.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000040#include "llvm/Support/Compiler.h"
41#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000042#include "llvm/Support/Format.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000043#include "llvm/Support/MemoryBuffer.h"
44#include "llvm/Support/Mutex.h"
45#include "llvm/Support/PrettyStackTrace.h"
46#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 Kyrtzidisc6f5c6a2013-01-10 18:54:52 +000052
53#if HAVE_PTHREAD_H
54#include <pthread.h>
55#endif
Guy Benyei7f92f2d2012-12-18 14:30:41 +000056
57using namespace clang;
58using namespace clang::cxcursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000059using namespace clang::cxtu;
60using namespace clang::cxindex;
61
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000062CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
63 if (!AU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +000064 return 0;
65 CXTranslationUnit D = new CXTranslationUnitImpl();
66 D->CIdx = CIdx;
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000067 D->TheASTUnit = AU;
Dmitri Gribenkoaca3e562013-02-03 13:52:47 +000068 D->StringPool = new cxstring::CXStringPool();
Guy Benyei7f92f2d2012-12-18 14:30:41 +000069 D->Diagnostics = 0;
70 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Fariborz Jahanian88b95212012-12-18 23:02:59 +000071 D->FormatContext = 0;
72 D->FormatInMemoryUniqueId = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000073 return D;
74}
75
76cxtu::CXTUOwner::~CXTUOwner() {
77 if (TU)
78 clang_disposeTranslationUnit(TU);
79}
80
81/// \brief Compare two source ranges to determine their relative position in
82/// the translation unit.
83static RangeComparisonResult RangeCompare(SourceManager &SM,
84 SourceRange R1,
85 SourceRange R2) {
86 assert(R1.isValid() && "First range is invalid?");
87 assert(R2.isValid() && "Second range is invalid?");
88 if (R1.getEnd() != R2.getBegin() &&
89 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
90 return RangeBefore;
91 if (R2.getEnd() != R1.getBegin() &&
92 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
93 return RangeAfter;
94 return RangeOverlap;
95}
96
97/// \brief Determine if a source location falls within, before, or after a
98/// a given source range.
99static RangeComparisonResult LocationCompare(SourceManager &SM,
100 SourceLocation L, SourceRange R) {
101 assert(R.isValid() && "First range is invalid?");
102 assert(L.isValid() && "Second range is invalid?");
103 if (L == R.getBegin() || L == R.getEnd())
104 return RangeOverlap;
105 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
106 return RangeBefore;
107 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Translate a Clang source range into a CIndex source range.
113///
114/// Clang internally represents ranges where the end location points to the
115/// start of the token at the end. However, for external clients it is more
116/// useful to have a CXSourceRange be a proper half-open interval. This routine
117/// does the appropriate translation.
118CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
119 const LangOptions &LangOpts,
120 const CharSourceRange &R) {
121 // We want the last character in this location, so we will adjust the
122 // location accordingly.
123 SourceLocation EndLoc = R.getEnd();
124 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
125 EndLoc = SM.getExpansionRange(EndLoc).second;
126 if (R.isTokenRange() && !EndLoc.isInvalid()) {
127 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
128 SM, LangOpts);
129 EndLoc = EndLoc.getLocWithOffset(Length);
130 }
131
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000132 CXSourceRange Result = {
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +0000133 { &SM, &LangOpts },
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000134 R.getBegin().getRawEncoding(),
135 EndLoc.getRawEncoding()
136 };
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000137 return Result;
138}
139
140//===----------------------------------------------------------------------===//
141// Cursor visitor.
142//===----------------------------------------------------------------------===//
143
144static SourceRange getRawCursorExtent(CXCursor C);
145static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
146
147
148RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
149 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
150}
151
152/// \brief Visit the given cursor and, if requested by the visitor,
153/// its children.
154///
155/// \param Cursor the cursor to visit.
156///
157/// \param CheckedRegionOfInterest if true, then the caller already checked
158/// that this cursor is within the region of interest.
159///
160/// \returns true if the visitation should be aborted, false if it
161/// should continue.
162bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
163 if (clang_isInvalid(Cursor.kind))
164 return false;
165
166 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000167 const Decl *D = getCursorDecl(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000168 if (!D) {
169 assert(0 && "Invalid declaration cursor");
170 return true; // abort.
171 }
172
173 // Ignore implicit declarations, unless it's an objc method because
174 // currently we should report implicit methods for properties when indexing.
175 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
176 return false;
177 }
178
179 // If we have a range of interest, and this cursor doesn't intersect with it,
180 // we're done.
181 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
182 SourceRange Range = getRawCursorExtent(Cursor);
183 if (Range.isInvalid() || CompareRegionOfInterest(Range))
184 return false;
185 }
186
187 switch (Visitor(Cursor, Parent, ClientData)) {
188 case CXChildVisit_Break:
189 return true;
190
191 case CXChildVisit_Continue:
192 return false;
193
194 case CXChildVisit_Recurse: {
195 bool ret = VisitChildren(Cursor);
196 if (PostChildrenVisitor)
197 if (PostChildrenVisitor(Cursor, ClientData))
198 return true;
199 return ret;
200 }
201 }
202
203 llvm_unreachable("Invalid CXChildVisitResult!");
204}
205
206static bool visitPreprocessedEntitiesInRange(SourceRange R,
207 PreprocessingRecord &PPRec,
208 CursorVisitor &Visitor) {
209 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
210 FileID FID;
211
212 if (!Visitor.shouldVisitIncludedEntities()) {
213 // If the begin/end of the range lie in the same FileID, do the optimization
214 // where we skip preprocessed entities that do not come from the same FileID.
215 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
216 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
217 FID = FileID();
218 }
219
220 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
221 Entities = PPRec.getPreprocessedEntitiesInRange(R);
222 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
223 PPRec, FID);
224}
225
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000226bool CursorVisitor::visitFileRegion() {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000227 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000228 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000229
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000230 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000231 SourceManager &SM = Unit->getSourceManager();
232
233 std::pair<FileID, unsigned>
234 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
235 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
236
237 if (End.first != Begin.first) {
238 // If the end does not reside in the same file, try to recover by
239 // picking the end of the file of begin location.
240 End.first = Begin.first;
241 End.second = SM.getFileIDSize(Begin.first);
242 }
243
244 assert(Begin.first == End.first);
245 if (Begin.second > End.second)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000246 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000247
248 FileID File = Begin.first;
249 unsigned Offset = Begin.second;
250 unsigned Length = End.second - Begin.second;
251
252 if (!VisitDeclsOnly && !VisitPreprocessorLast)
253 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000254 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000255
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000256 if (visitDeclsFromFileRegion(File, Offset, Length))
257 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000258
259 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000260 return visitPreprocessedEntitiesInRegion();
261
262 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000263}
264
265static bool isInLexicalContext(Decl *D, DeclContext *DC) {
266 if (!DC)
267 return false;
268
269 for (DeclContext *DeclDC = D->getLexicalDeclContext();
270 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
271 if (DeclDC == DC)
272 return true;
273 }
274 return false;
275}
276
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000277bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000278 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000279 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000280 SourceManager &SM = Unit->getSourceManager();
281 SourceRange Range = RegionOfInterest;
282
283 SmallVector<Decl *, 16> Decls;
284 Unit->findFileRegionDecls(File, Offset, Length, Decls);
285
286 // If we didn't find any file level decls for the file, try looking at the
287 // file that it was included from.
288 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
289 bool Invalid = false;
290 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
291 if (Invalid)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000292 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000293
294 SourceLocation Outer;
295 if (SLEntry.isFile())
296 Outer = SLEntry.getFile().getIncludeLoc();
297 else
298 Outer = SLEntry.getExpansion().getExpansionLocStart();
299 if (Outer.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000300 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000301
302 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
303 Length = 0;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305 }
306
307 assert(!Decls.empty());
308
309 bool VisitedAtLeastOnce = false;
310 DeclContext *CurDC = 0;
311 SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
312 for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
313 Decl *D = *DIt;
314 if (D->getSourceRange().isInvalid())
315 continue;
316
317 if (isInLexicalContext(D, CurDC))
318 continue;
319
320 CurDC = dyn_cast<DeclContext>(D);
321
322 if (TagDecl *TD = dyn_cast<TagDecl>(D))
323 if (!TD->isFreeStanding())
324 continue;
325
326 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
327 if (CompRes == RangeBefore)
328 continue;
329 if (CompRes == RangeAfter)
330 break;
331
332 assert(CompRes == RangeOverlap);
333 VisitedAtLeastOnce = true;
334
335 if (isa<ObjCContainerDecl>(D)) {
336 FileDI_current = &DIt;
337 FileDE_current = DE;
338 } else {
339 FileDI_current = 0;
340 }
341
342 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000343 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000344 }
345
346 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000347 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000348
349 // No Decls overlapped with the range. Move up the lexical context until there
350 // is a context that contains the range or we reach the translation unit
351 // level.
352 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
353 : (*(DIt-1))->getLexicalDeclContext();
354
355 while (DC && !DC->isTranslationUnit()) {
356 Decl *D = cast<Decl>(DC);
357 SourceRange CurDeclRange = D->getSourceRange();
358 if (CurDeclRange.isInvalid())
359 break;
360
361 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
363 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000364 }
365
366 DC = D->getLexicalDeclContext();
367 }
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000368
369 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000370}
371
372bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
373 if (!AU->getPreprocessor().getPreprocessingRecord())
374 return false;
375
376 PreprocessingRecord &PPRec
377 = *AU->getPreprocessor().getPreprocessingRecord();
378 SourceManager &SM = AU->getSourceManager();
379
380 if (RegionOfInterest.isValid()) {
381 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
382 SourceLocation B = MappedRange.getBegin();
383 SourceLocation E = MappedRange.getEnd();
384
385 if (AU->isInPreambleFileID(B)) {
386 if (SM.isLoadedSourceLocation(E))
387 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
388 PPRec, *this);
389
390 // Beginning of range lies in the preamble but it also extends beyond
391 // it into the main file. Split the range into 2 parts, one covering
392 // the preamble and another covering the main file. This allows subsequent
393 // calls to visitPreprocessedEntitiesInRange to accept a source range that
394 // lies in the same FileID, allowing it to skip preprocessed entities that
395 // do not come from the same FileID.
396 bool breaked =
397 visitPreprocessedEntitiesInRange(
398 SourceRange(B, AU->getEndOfPreambleFileID()),
399 PPRec, *this);
400 if (breaked) return true;
401 return visitPreprocessedEntitiesInRange(
402 SourceRange(AU->getStartOfMainFileID(), E),
403 PPRec, *this);
404 }
405
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
407 }
408
409 bool OnlyLocalDecls
410 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
411
412 if (OnlyLocalDecls)
413 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
414 PPRec);
415
416 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
417}
418
419template<typename InputIterator>
420bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
421 InputIterator Last,
422 PreprocessingRecord &PPRec,
423 FileID FID) {
424 for (; First != Last; ++First) {
425 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
426 continue;
427
428 PreprocessedEntity *PPE = *First;
429 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
430 if (Visit(MakeMacroExpansionCursor(ME, TU)))
431 return true;
432
433 continue;
434 }
435
436 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
437 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
438 return true;
439
440 continue;
441 }
442
443 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
444 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
445 return true;
446
447 continue;
448 }
449 }
450
451 return false;
452}
453
454/// \brief Visit the children of the given cursor.
455///
456/// \returns true if the visitation should be aborted, false if it
457/// should continue.
458bool CursorVisitor::VisitChildren(CXCursor Cursor) {
459 if (clang_isReference(Cursor.kind) &&
460 Cursor.kind != CXCursor_CXXBaseSpecifier) {
461 // By definition, references have no children.
462 return false;
463 }
464
465 // Set the Parent field to Cursor, then back to its old value once we're
466 // done.
467 SetParentRAII SetParent(Parent, StmtParent, Cursor);
468
469 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000470 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000471 if (!D)
472 return false;
473
474 return VisitAttributes(D) || Visit(D);
475 }
476
477 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000478 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000479 return Visit(S);
480
481 return false;
482 }
483
484 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000485 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000486 return Visit(E);
487
488 return false;
489 }
490
491 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000492 CXTranslationUnit TU = getCursorTU(Cursor);
493 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000494
495 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
496 for (unsigned I = 0; I != 2; ++I) {
497 if (VisitOrder[I]) {
498 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
499 RegionOfInterest.isInvalid()) {
500 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
501 TLEnd = CXXUnit->top_level_end();
502 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000503 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000504 return true;
505 }
506 } else if (VisitDeclContext(
507 CXXUnit->getASTContext().getTranslationUnitDecl()))
508 return true;
509 continue;
510 }
511
512 // Walk the preprocessing record.
513 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
514 visitPreprocessedEntitiesInRegion();
515 }
516
517 return false;
518 }
519
520 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000521 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000522 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
523 return Visit(BaseTSInfo->getTypeLoc());
524 }
525 }
526 }
527
528 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000529 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000530 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
531 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
532 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
533 A->getInterfaceLoc(), TU));
534 }
535
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000536 // If pointing inside a macro definition, check if the token is an identifier
537 // that was ever defined as a macro. In such a case, create a "pseudo" macro
538 // expansion cursor for that token.
539 SourceLocation BeginLoc = RegionOfInterest.getBegin();
540 if (Cursor.kind == CXCursor_MacroDefinition &&
541 BeginLoc == RegionOfInterest.getEnd()) {
542 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000543 const MacroInfo *MI =
544 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000545 if (MacroDefinition *MacroDef =
546 checkForMacroInMacroDefinition(MI, Loc, TU))
547 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
548 }
549
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000550 // Nothing to visit at the moment.
551 return false;
552}
553
554bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
555 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
556 if (Visit(TSInfo->getTypeLoc()))
557 return true;
558
559 if (Stmt *Body = B->getBody())
560 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
561
562 return false;
563}
564
Ted Kremenek943f9092013-02-21 01:29:01 +0000565Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000566 if (RegionOfInterest.isValid()) {
567 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
568 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000569 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000570
571 switch (CompareRegionOfInterest(Range)) {
572 case RangeBefore:
573 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000574 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000575
576 case RangeAfter:
577 // This declaration comes after the region of interest; we're done.
578 return false;
579
580 case RangeOverlap:
581 // This declaration overlaps the region of interest; visit it.
582 break;
583 }
584 }
585 return true;
586}
587
588bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
589 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
590
591 // FIXME: Eventually remove. This part of a hack to support proper
592 // iteration over all Decls contained lexically within an ObjC container.
593 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
594 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
595
596 for ( ; I != E; ++I) {
597 Decl *D = *I;
598 if (D->getLexicalDeclContext() != DC)
599 continue;
600 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
601
602 // Ignore synthesized ivars here, otherwise if we have something like:
603 // @synthesize prop = _prop;
604 // and '_prop' is not declared, we will encounter a '_prop' ivar before
605 // encountering the 'prop' synthesize declaration and we will think that
606 // we passed the region-of-interest.
607 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
608 if (ivarD->getSynthesize())
609 continue;
610 }
611
612 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
613 // declarations is a mismatch with the compiler semantics.
614 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
615 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
616 if (!ID->isThisDeclarationADefinition())
617 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
618
619 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
620 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
621 if (!PD->isThisDeclarationADefinition())
622 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
623 }
624
Ted Kremenek943f9092013-02-21 01:29:01 +0000625 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000626 if (!V.hasValue())
627 continue;
628 if (!V.getValue())
629 return false;
630 if (Visit(Cursor, true))
631 return true;
632 }
633 return false;
634}
635
636bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
637 llvm_unreachable("Translation units are visited directly by Visit()");
638}
639
640bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
641 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
642 return Visit(TSInfo->getTypeLoc());
643
644 return false;
645}
646
647bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
648 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
649 return Visit(TSInfo->getTypeLoc());
650
651 return false;
652}
653
654bool CursorVisitor::VisitTagDecl(TagDecl *D) {
655 return VisitDeclContext(D);
656}
657
658bool CursorVisitor::VisitClassTemplateSpecializationDecl(
659 ClassTemplateSpecializationDecl *D) {
660 bool ShouldVisitBody = false;
661 switch (D->getSpecializationKind()) {
662 case TSK_Undeclared:
663 case TSK_ImplicitInstantiation:
664 // Nothing to visit
665 return false;
666
667 case TSK_ExplicitInstantiationDeclaration:
668 case TSK_ExplicitInstantiationDefinition:
669 break;
670
671 case TSK_ExplicitSpecialization:
672 ShouldVisitBody = true;
673 break;
674 }
675
676 // Visit the template arguments used in the specialization.
677 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
678 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000679 if (TemplateSpecializationTypeLoc TSTLoc =
680 TL.getAs<TemplateSpecializationTypeLoc>()) {
681 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
682 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000683 return true;
684 }
685 }
686
687 if (ShouldVisitBody && VisitCXXRecordDecl(D))
688 return true;
689
690 return false;
691}
692
693bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
694 ClassTemplatePartialSpecializationDecl *D) {
695 // FIXME: Visit the "outer" template parameter lists on the TagDecl
696 // before visiting these template parameters.
697 if (VisitTemplateParameters(D->getTemplateParameters()))
698 return true;
699
700 // Visit the partial specialization arguments.
701 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
702 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
703 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
704 return true;
705
706 return VisitCXXRecordDecl(D);
707}
708
709bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
710 // Visit the default argument.
711 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
712 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
713 if (Visit(DefArg->getTypeLoc()))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
720 if (Expr *Init = D->getInitExpr())
721 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
722 return false;
723}
724
725bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000726 unsigned NumParamList = DD->getNumTemplateParameterLists();
727 for (unsigned i = 0; i < NumParamList; i++) {
728 TemplateParameterList* Params = DD->getTemplateParameterList(i);
729 if (VisitTemplateParameters(Params))
730 return true;
731 }
732
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000733 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
734 if (Visit(TSInfo->getTypeLoc()))
735 return true;
736
737 // Visit the nested-name-specifier, if present.
738 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
739 if (VisitNestedNameSpecifierLoc(QualifierLoc))
740 return true;
741
742 return false;
743}
744
745/// \brief Compare two base or member initializers based on their source order.
746static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
747 CXXCtorInitializer const * const *X
748 = static_cast<CXXCtorInitializer const * const *>(Xp);
749 CXXCtorInitializer const * const *Y
750 = static_cast<CXXCtorInitializer const * const *>(Yp);
751
752 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
753 return -1;
754 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
755 return 1;
756 else
757 return 0;
758}
759
760bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000761 unsigned NumParamList = ND->getNumTemplateParameterLists();
762 for (unsigned i = 0; i < NumParamList; i++) {
763 TemplateParameterList* Params = ND->getTemplateParameterList(i);
764 if (VisitTemplateParameters(Params))
765 return true;
766 }
767
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000768 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
769 // Visit the function declaration's syntactic components in the order
770 // written. This requires a bit of work.
771 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000772 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000773
774 // If we have a function declared directly (without the use of a typedef),
775 // visit just the return type. Otherwise, just visit the function's type
776 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000777 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000778 (!FTL && Visit(TL)))
779 return true;
780
781 // Visit the nested-name-specifier, if present.
782 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
783 if (VisitNestedNameSpecifierLoc(QualifierLoc))
784 return true;
785
786 // Visit the declaration name.
787 if (VisitDeclarationNameInfo(ND->getNameInfo()))
788 return true;
789
790 // FIXME: Visit explicitly-specified template arguments!
791
792 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000793 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000794 return true;
795
Bill Wendlingad017fa2012-12-20 19:22:21 +0000796 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000797 }
798
799 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
800 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
801 // Find the initializers that were written in the source.
802 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
803 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
804 IEnd = Constructor->init_end();
805 I != IEnd; ++I) {
806 if (!(*I)->isWritten())
807 continue;
808
809 WrittenInits.push_back(*I);
810 }
811
812 // Sort the initializers in source order
813 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
814 &CompareCXXCtorInitializers);
815
816 // Visit the initializers in source order
817 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
818 CXXCtorInitializer *Init = WrittenInits[I];
819 if (Init->isAnyMemberInitializer()) {
820 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
821 Init->getMemberLocation(), TU)))
822 return true;
823 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
824 if (Visit(TInfo->getTypeLoc()))
825 return true;
826 }
827
828 // Visit the initializer value.
829 if (Expr *Initializer = Init->getInit())
830 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
831 return true;
832 }
833 }
834
835 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
836 return true;
837 }
838
839 return false;
840}
841
842bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
843 if (VisitDeclaratorDecl(D))
844 return true;
845
846 if (Expr *BitWidth = D->getBitWidth())
847 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
848
849 return false;
850}
851
852bool CursorVisitor::VisitVarDecl(VarDecl *D) {
853 if (VisitDeclaratorDecl(D))
854 return true;
855
856 if (Expr *Init = D->getInit())
857 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
858
859 return false;
860}
861
862bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
863 if (VisitDeclaratorDecl(D))
864 return true;
865
866 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
867 if (Expr *DefArg = D->getDefaultArgument())
868 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
869
870 return false;
871}
872
873bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
874 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
875 // before visiting these template parameters.
876 if (VisitTemplateParameters(D->getTemplateParameters()))
877 return true;
878
879 return VisitFunctionDecl(D->getTemplatedDecl());
880}
881
882bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
883 // FIXME: Visit the "outer" template parameter lists on the TagDecl
884 // before visiting these template parameters.
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 return VisitCXXRecordDecl(D->getTemplatedDecl());
889}
890
891bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
892 if (VisitTemplateParameters(D->getTemplateParameters()))
893 return true;
894
895 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
896 VisitTemplateArgumentLoc(D->getDefaultArgument()))
897 return true;
898
899 return false;
900}
901
902bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
903 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
904 if (Visit(TSInfo->getTypeLoc()))
905 return true;
906
907 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
908 PEnd = ND->param_end();
909 P != PEnd; ++P) {
910 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
911 return true;
912 }
913
914 if (ND->isThisDeclarationADefinition() &&
915 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
916 return true;
917
918 return false;
919}
920
921template <typename DeclIt>
922static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
923 SourceManager &SM, SourceLocation EndLoc,
924 SmallVectorImpl<Decl *> &Decls) {
925 DeclIt next = *DI_current;
926 while (++next != DE_current) {
927 Decl *D_next = *next;
928 if (!D_next)
929 break;
930 SourceLocation L = D_next->getLocStart();
931 if (!L.isValid())
932 break;
933 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
934 *DI_current = next;
935 Decls.push_back(D_next);
936 continue;
937 }
938 break;
939 }
940}
941
942namespace {
943 struct ContainerDeclsSort {
944 SourceManager &SM;
945 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
946 bool operator()(Decl *A, Decl *B) {
947 SourceLocation L_A = A->getLocStart();
948 SourceLocation L_B = B->getLocStart();
949 assert(L_A.isValid() && L_B.isValid());
950 return SM.isBeforeInTranslationUnit(L_A, L_B);
951 }
952 };
953}
954
955bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
956 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
957 // an @implementation can lexically contain Decls that are not properly
958 // nested in the AST. When we identify such cases, we need to retrofit
959 // this nesting here.
960 if (!DI_current && !FileDI_current)
961 return VisitDeclContext(D);
962
963 // Scan the Decls that immediately come after the container
964 // in the current DeclContext. If any fall within the
965 // container's lexical region, stash them into a vector
966 // for later processing.
967 SmallVector<Decl *, 24> DeclsInContainer;
968 SourceLocation EndLoc = D->getSourceRange().getEnd();
969 SourceManager &SM = AU->getSourceManager();
970 if (EndLoc.isValid()) {
971 if (DI_current) {
972 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
973 DeclsInContainer);
974 } else {
975 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
976 DeclsInContainer);
977 }
978 }
979
980 // The common case.
981 if (DeclsInContainer.empty())
982 return VisitDeclContext(D);
983
984 // Get all the Decls in the DeclContext, and sort them with the
985 // additional ones we've collected. Then visit them.
986 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
987 I!=E; ++I) {
988 Decl *subDecl = *I;
989 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
990 subDecl->getLocStart().isInvalid())
991 continue;
992 DeclsInContainer.push_back(subDecl);
993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
997 ContainerDeclsSort(SM));
998
999 // Now visit the decls.
1000 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1001 E = DeclsInContainer.end(); I != E; ++I) {
1002 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +00001003 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001004 if (!V.hasValue())
1005 continue;
1006 if (!V.getValue())
1007 return false;
1008 if (Visit(Cursor, true))
1009 return true;
1010 }
1011 return false;
1012}
1013
1014bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1015 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1016 TU)))
1017 return true;
1018
1019 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1020 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1021 E = ND->protocol_end(); I != E; ++I, ++PL)
1022 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1023 return true;
1024
1025 return VisitObjCContainerDecl(ND);
1026}
1027
1028bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1029 if (!PID->isThisDeclarationADefinition())
1030 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1031
1032 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1033 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1034 E = PID->protocol_end(); I != E; ++I, ++PL)
1035 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1036 return true;
1037
1038 return VisitObjCContainerDecl(PID);
1039}
1040
1041bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1042 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1043 return true;
1044
1045 // FIXME: This implements a workaround with @property declarations also being
1046 // installed in the DeclContext for the @interface. Eventually this code
1047 // should be removed.
1048 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1049 if (!CDecl || !CDecl->IsClassExtension())
1050 return false;
1051
1052 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1053 if (!ID)
1054 return false;
1055
1056 IdentifierInfo *PropertyId = PD->getIdentifier();
1057 ObjCPropertyDecl *prevDecl =
1058 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1059
1060 if (!prevDecl)
1061 return false;
1062
1063 // Visit synthesized methods since they will be skipped when visiting
1064 // the @interface.
1065 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1066 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1067 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1068 return true;
1069
1070 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 return false;
1076}
1077
1078bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1079 if (!D->isThisDeclarationADefinition()) {
1080 // Forward declaration is treated like a reference.
1081 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1082 }
1083
1084 // Issue callbacks for super class.
1085 if (D->getSuperClass() &&
1086 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1087 D->getSuperClassLoc(),
1088 TU)))
1089 return true;
1090
1091 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1092 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1093 E = D->protocol_end(); I != E; ++I, ++PL)
1094 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1095 return true;
1096
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1105 // 'ID' could be null when dealing with invalid code.
1106 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1107 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1108 return true;
1109
1110 return VisitObjCImplDecl(D);
1111}
1112
1113bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1114#if 0
1115 // Issue callbacks for super class.
1116 // FIXME: No source location information!
1117 if (D->getSuperClass() &&
1118 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1119 D->getSuperClassLoc(),
1120 TU)))
1121 return true;
1122#endif
1123
1124 return VisitObjCImplDecl(D);
1125}
1126
1127bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1128 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1129 if (PD->isIvarNameSpecified())
1130 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1131
1132 return false;
1133}
1134
1135bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1136 return VisitDeclContext(D);
1137}
1138
1139bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1140 // Visit nested-name-specifier.
1141 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1142 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1143 return true;
1144
1145 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1146 D->getTargetNameLoc(), TU));
1147}
1148
1149bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1150 // Visit nested-name-specifier.
1151 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1152 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1153 return true;
1154 }
1155
1156 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitDeclarationNameInfo(D->getNameInfo());
1160}
1161
1162bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1163 // Visit nested-name-specifier.
1164 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1165 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1166 return true;
1167
1168 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1169 D->getIdentLocation(), TU));
1170}
1171
1172bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1173 // Visit nested-name-specifier.
1174 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1176 return true;
1177 }
1178
1179 return VisitDeclarationNameInfo(D->getNameInfo());
1180}
1181
1182bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1183 UnresolvedUsingTypenameDecl *D) {
1184 // Visit nested-name-specifier.
1185 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1186 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1187 return true;
1188
1189 return false;
1190}
1191
1192bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1193 switch (Name.getName().getNameKind()) {
1194 case clang::DeclarationName::Identifier:
1195 case clang::DeclarationName::CXXLiteralOperatorName:
1196 case clang::DeclarationName::CXXOperatorName:
1197 case clang::DeclarationName::CXXUsingDirective:
1198 return false;
1199
1200 case clang::DeclarationName::CXXConstructorName:
1201 case clang::DeclarationName::CXXDestructorName:
1202 case clang::DeclarationName::CXXConversionFunctionName:
1203 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1204 return Visit(TSInfo->getTypeLoc());
1205 return false;
1206
1207 case clang::DeclarationName::ObjCZeroArgSelector:
1208 case clang::DeclarationName::ObjCOneArgSelector:
1209 case clang::DeclarationName::ObjCMultiArgSelector:
1210 // FIXME: Per-identifier location info?
1211 return false;
1212 }
1213
1214 llvm_unreachable("Invalid DeclarationName::Kind!");
1215}
1216
1217bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1218 SourceRange Range) {
1219 // FIXME: This whole routine is a hack to work around the lack of proper
1220 // source information in nested-name-specifiers (PR5791). Since we do have
1221 // a beginning source location, we can visit the first component of the
1222 // nested-name-specifier, if it's a single-token component.
1223 if (!NNS)
1224 return false;
1225
1226 // Get the first component in the nested-name-specifier.
1227 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1228 NNS = Prefix;
1229
1230 switch (NNS->getKind()) {
1231 case NestedNameSpecifier::Namespace:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1233 TU));
1234
1235 case NestedNameSpecifier::NamespaceAlias:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1237 Range.getBegin(), TU));
1238
1239 case NestedNameSpecifier::TypeSpec: {
1240 // If the type has a form where we know that the beginning of the source
1241 // range matches up with a reference cursor. Visit the appropriate reference
1242 // cursor.
1243 const Type *T = NNS->getAsType();
1244 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1245 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1246 if (const TagType *Tag = dyn_cast<TagType>(T))
1247 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1248 if (const TemplateSpecializationType *TST
1249 = dyn_cast<TemplateSpecializationType>(T))
1250 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1251 break;
1252 }
1253
1254 case NestedNameSpecifier::TypeSpecWithTemplate:
1255 case NestedNameSpecifier::Global:
1256 case NestedNameSpecifier::Identifier:
1257 break;
1258 }
1259
1260 return false;
1261}
1262
1263bool
1264CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1265 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1266 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1267 Qualifiers.push_back(Qualifier);
1268
1269 while (!Qualifiers.empty()) {
1270 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1271 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1275 Q.getLocalBeginLoc(),
1276 TU)))
1277 return true;
1278
1279 break;
1280
1281 case NestedNameSpecifier::NamespaceAlias:
1282 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1283 Q.getLocalBeginLoc(),
1284 TU)))
1285 return true;
1286
1287 break;
1288
1289 case NestedNameSpecifier::TypeSpec:
1290 case NestedNameSpecifier::TypeSpecWithTemplate:
1291 if (Visit(Q.getTypeLoc()))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
1298 break;
1299 }
1300 }
1301
1302 return false;
1303}
1304
1305bool CursorVisitor::VisitTemplateParameters(
1306 const TemplateParameterList *Params) {
1307 if (!Params)
1308 return false;
1309
1310 for (TemplateParameterList::const_iterator P = Params->begin(),
1311 PEnd = Params->end();
1312 P != PEnd; ++P) {
1313 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1314 return true;
1315 }
1316
1317 return false;
1318}
1319
1320bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1321 switch (Name.getKind()) {
1322 case TemplateName::Template:
1323 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1324
1325 case TemplateName::OverloadedTemplate:
1326 // Visit the overloaded template set.
1327 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1328 return true;
1329
1330 return false;
1331
1332 case TemplateName::DependentTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return false;
1335
1336 case TemplateName::QualifiedTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return Visit(MakeCursorTemplateRef(
1339 Name.getAsQualifiedTemplateName()->getDecl(),
1340 Loc, TU));
1341
1342 case TemplateName::SubstTemplateTemplateParm:
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1345 Loc, TU));
1346
1347 case TemplateName::SubstTemplateTemplateParmPack:
1348 return Visit(MakeCursorTemplateRef(
1349 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1350 Loc, TU));
1351 }
1352
1353 llvm_unreachable("Invalid TemplateName::Kind!");
1354}
1355
1356bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1357 switch (TAL.getArgument().getKind()) {
1358 case TemplateArgument::Null:
1359 case TemplateArgument::Integral:
1360 case TemplateArgument::Pack:
1361 return false;
1362
1363 case TemplateArgument::Type:
1364 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1365 return Visit(TSInfo->getTypeLoc());
1366 return false;
1367
1368 case TemplateArgument::Declaration:
1369 if (Expr *E = TAL.getSourceDeclExpression())
1370 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1371 return false;
1372
1373 case TemplateArgument::NullPtr:
1374 if (Expr *E = TAL.getSourceNullPtrExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::Expression:
1379 if (Expr *E = TAL.getSourceExpression())
1380 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1381 return false;
1382
1383 case TemplateArgument::Template:
1384 case TemplateArgument::TemplateExpansion:
1385 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1386 return true;
1387
1388 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1389 TAL.getTemplateNameLoc());
1390 }
1391
1392 llvm_unreachable("Invalid TemplateArgument::Kind!");
1393}
1394
1395bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1396 return VisitDeclContext(D);
1397}
1398
1399bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1400 return Visit(TL.getUnqualifiedLoc());
1401}
1402
1403bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1404 ASTContext &Context = AU->getASTContext();
1405
1406 // Some builtin types (such as Objective-C's "id", "sel", and
1407 // "Class") have associated declarations. Create cursors for those.
1408 QualType VisitType;
1409 switch (TL.getTypePtr()->getKind()) {
1410
1411 case BuiltinType::Void:
1412 case BuiltinType::NullPtr:
1413 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001414 case BuiltinType::OCLImage1d:
1415 case BuiltinType::OCLImage1dArray:
1416 case BuiltinType::OCLImage1dBuffer:
1417 case BuiltinType::OCLImage2d:
1418 case BuiltinType::OCLImage2dArray:
1419 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001420 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001421 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001422#define BUILTIN_TYPE(Id, SingletonId)
1423#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#include "clang/AST/BuiltinTypes.def"
1428 break;
1429
1430 case BuiltinType::ObjCId:
1431 VisitType = Context.getObjCIdType();
1432 break;
1433
1434 case BuiltinType::ObjCClass:
1435 VisitType = Context.getObjCClassType();
1436 break;
1437
1438 case BuiltinType::ObjCSel:
1439 VisitType = Context.getObjCSelType();
1440 break;
1441 }
1442
1443 if (!VisitType.isNull()) {
1444 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1445 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1446 TU));
1447 }
1448
1449 return false;
1450}
1451
1452bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1461 if (TL.isDefinition())
1462 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1463
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1472 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1473 return true;
1474
1475 return false;
1476}
1477
1478bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1479 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1480 return true;
1481
1482 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1483 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1484 TU)))
1485 return true;
1486 }
1487
1488 return false;
1489}
1490
1491bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1496 return Visit(TL.getInnerLoc());
1497}
1498
1499bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1520 return Visit(TL.getModifiedLoc());
1521}
1522
1523bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1524 bool SkipResultType) {
1525 if (!SkipResultType && Visit(TL.getResultLoc()))
1526 return true;
1527
1528 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1529 if (Decl *D = TL.getArg(I))
1530 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1531 return true;
1532
1533 return false;
1534}
1535
1536bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1537 if (Visit(TL.getElementLoc()))
1538 return true;
1539
1540 if (Expr *Size = TL.getSizeExpr())
1541 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1542
1543 return false;
1544}
1545
1546bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1547 TemplateSpecializationTypeLoc TL) {
1548 // Visit the template name.
1549 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1550 TL.getTemplateNameLoc()))
1551 return true;
1552
1553 // Visit the template arguments.
1554 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1555 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1556 return true;
1557
1558 return false;
1559}
1560
1561bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1562 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1563}
1564
1565bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1566 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1567 return Visit(TSInfo->getTypeLoc());
1568
1569 return false;
1570}
1571
1572bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1573 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1574 return Visit(TSInfo->getTypeLoc());
1575
1576 return false;
1577}
1578
1579bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1580 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1581 return true;
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1587 DependentTemplateSpecializationTypeLoc TL) {
1588 // Visit the nested-name-specifier, if there is one.
1589 if (TL.getQualifierLoc() &&
1590 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 // Visit the template arguments.
1594 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1595 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1602 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1603 return true;
1604
1605 return Visit(TL.getNamedTypeLoc());
1606}
1607
1608bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1609 return Visit(TL.getPatternLoc());
1610}
1611
1612bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1613 if (Expr *E = TL.getUnderlyingExpr())
1614 return Visit(MakeCXCursor(E, StmtParent, TU));
1615
1616 return false;
1617}
1618
1619bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1620 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1621}
1622
1623bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1624 return Visit(TL.getValueLoc());
1625}
1626
1627#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1628bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1629 return Visit##PARENT##Loc(TL); \
1630}
1631
1632DEFAULT_TYPELOC_IMPL(Complex, Type)
1633DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1634DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1635DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1636DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1638DEFAULT_TYPELOC_IMPL(Vector, Type)
1639DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1640DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1641DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1642DEFAULT_TYPELOC_IMPL(Record, TagType)
1643DEFAULT_TYPELOC_IMPL(Enum, TagType)
1644DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1645DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1646DEFAULT_TYPELOC_IMPL(Auto, Type)
1647
1648bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1649 // Visit the nested-name-specifier, if present.
1650 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1651 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1652 return true;
1653
1654 if (D->isCompleteDefinition()) {
1655 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1656 E = D->bases_end(); I != E; ++I) {
1657 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1658 return true;
1659 }
1660 }
1661
1662 return VisitTagDecl(D);
1663}
1664
1665bool CursorVisitor::VisitAttributes(Decl *D) {
1666 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1667 i != e; ++i)
1668 if (Visit(MakeCXCursor(*i, D, TU)))
1669 return true;
1670
1671 return false;
1672}
1673
1674//===----------------------------------------------------------------------===//
1675// Data-recursive visitor methods.
1676//===----------------------------------------------------------------------===//
1677
1678namespace {
1679#define DEF_JOB(NAME, DATA, KIND)\
1680class NAME : public VisitorJob {\
1681public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001682 NAME(const DATA *d, CXCursor parent) : \
1683 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001684 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001685 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001686};
1687
1688DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1689DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1690DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1691DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1692DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1693 ExplicitTemplateArgsVisitKind)
1694DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1695DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1696DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1697#undef DEF_JOB
1698
1699class DeclVisit : public VisitorJob {
1700public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001701 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001702 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001703 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001704 static bool classof(const VisitorJob *VJ) {
1705 return VJ->getKind() == DeclVisitKind;
1706 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001707 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001708 bool isFirst() const { return data[1] ? true : false; }
1709};
1710class TypeLocVisit : public VisitorJob {
1711public:
1712 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1713 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1714 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1715
1716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == TypeLocVisitKind;
1718 }
1719
1720 TypeLoc get() const {
1721 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001722 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001723 }
1724};
1725
1726class LabelRefVisit : public VisitorJob {
1727public:
1728 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1729 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1730 labelLoc.getPtrEncoding()) {}
1731
1732 static bool classof(const VisitorJob *VJ) {
1733 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1734 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001735 const LabelDecl *get() const {
1736 return static_cast<const LabelDecl *>(data[0]);
1737 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001738 SourceLocation getLoc() const {
1739 return SourceLocation::getFromPtrEncoding(data[1]); }
1740};
1741
1742class NestedNameSpecifierLocVisit : public VisitorJob {
1743public:
1744 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1745 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1746 Qualifier.getNestedNameSpecifier(),
1747 Qualifier.getOpaqueData()) { }
1748
1749 static bool classof(const VisitorJob *VJ) {
1750 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1751 }
1752
1753 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001754 return NestedNameSpecifierLoc(
1755 const_cast<NestedNameSpecifier *>(
1756 static_cast<const NestedNameSpecifier *>(data[0])),
1757 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001758 }
1759};
1760
1761class DeclarationNameInfoVisit : public VisitorJob {
1762public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001763 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001764 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001765 static bool classof(const VisitorJob *VJ) {
1766 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1767 }
1768 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001769 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001770 switch (S->getStmtClass()) {
1771 default:
1772 llvm_unreachable("Unhandled Stmt");
1773 case clang::Stmt::MSDependentExistsStmtClass:
1774 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1775 case Stmt::CXXDependentScopeMemberExprClass:
1776 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1777 case Stmt::DependentScopeDeclRefExprClass:
1778 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1779 }
1780 }
1781};
1782class MemberRefVisit : public VisitorJob {
1783public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001784 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001785 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1786 L.getPtrEncoding()) {}
1787 static bool classof(const VisitorJob *VJ) {
1788 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1789 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001790 const FieldDecl *get() const {
1791 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001792 }
1793 SourceLocation getLoc() const {
1794 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1795 }
1796};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001797class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-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 Gribenkoff74f962013-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);
1849
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001850private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001851 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001852 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1853 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001854 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1855 void AddStmt(const Stmt *S);
1856 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001857 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001858 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001859};
1860} // end anonyous namespace
1861
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001862void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001863 // 'S' should always be non-null, since it comes from the
1864 // statement we are visiting.
1865 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1866}
1867
1868void
1869EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1870 if (Qualifier)
1871 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1872}
1873
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001874void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001875 if (S)
1876 WL.push_back(StmtVisit(S, Parent));
1877}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001878void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001879 if (D)
1880 WL.push_back(DeclVisit(D, Parent, isFirst));
1881}
1882void EnqueueVisitor::
1883 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1884 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001885 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001886}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001887void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001888 if (D)
1889 WL.push_back(MemberRefVisit(D, L, Parent));
1890}
1891void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1892 if (TI)
1893 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1894 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001895void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001896 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001897 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001898 AddStmt(*Child);
1899 }
1900 if (size == WL.size())
1901 return;
1902 // Now reverse the entries we just added. This will match the DFS
1903 // ordering performed by the worklist.
1904 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1905 std::reverse(I, E);
1906}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001907void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001908 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1909}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001910void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001911 AddDecl(B->getBlockDecl());
1912}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001913void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001914 EnqueueChildren(E);
1915 AddTypeLoc(E->getTypeSourceInfo());
1916}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001917void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1918 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001919 E = S->body_rend(); I != E; ++I) {
1920 AddStmt(*I);
1921 }
1922}
1923void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001924VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001925 AddStmt(S->getSubStmt());
1926 AddDeclarationNameInfo(S);
1927 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1928 AddNestedNameSpecifierLoc(QualifierLoc);
1929}
1930
1931void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001932VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001933 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1934 AddDeclarationNameInfo(E);
1935 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1936 AddNestedNameSpecifierLoc(QualifierLoc);
1937 if (!E->isImplicitAccess())
1938 AddStmt(E->getBase());
1939}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001940void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001941 // Enqueue the initializer , if any.
1942 AddStmt(E->getInitializer());
1943 // Enqueue the array size, if any.
1944 AddStmt(E->getArraySize());
1945 // Enqueue the allocated type.
1946 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1947 // Enqueue the placement arguments.
1948 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1949 AddStmt(E->getPlacementArg(I-1));
1950}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001951void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001952 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1953 AddStmt(CE->getArg(I-1));
1954 AddStmt(CE->getCallee());
1955 AddStmt(CE->getArg(0));
1956}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001957void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1958 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001959 // Visit the name of the type being destroyed.
1960 AddTypeLoc(E->getDestroyedTypeInfo());
1961 // Visit the scope type that looks disturbingly like the nested-name-specifier
1962 // but isn't.
1963 AddTypeLoc(E->getScopeTypeInfo());
1964 // Visit the nested-name-specifier.
1965 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1966 AddNestedNameSpecifierLoc(QualifierLoc);
1967 // Visit base expression.
1968 AddStmt(E->getBase());
1969}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001970void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1971 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001972 AddTypeLoc(E->getTypeSourceInfo());
1973}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001974void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1975 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001976 EnqueueChildren(E);
1977 AddTypeLoc(E->getTypeSourceInfo());
1978}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001979void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001980 EnqueueChildren(E);
1981 if (E->isTypeOperand())
1982 AddTypeLoc(E->getTypeOperandSourceInfo());
1983}
1984
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001985void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1986 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001987 EnqueueChildren(E);
1988 AddTypeLoc(E->getTypeSourceInfo());
1989}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001990void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001991 EnqueueChildren(E);
1992 if (E->isTypeOperand())
1993 AddTypeLoc(E->getTypeOperandSourceInfo());
1994}
1995
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001996void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001997 EnqueueChildren(S);
1998 AddDecl(S->getExceptionDecl());
1999}
2000
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002001void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002002 if (DR->hasExplicitTemplateArgs()) {
2003 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2004 }
2005 WL.push_back(DeclRefExprParts(DR, Parent));
2006}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002007void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2008 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002009 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2010 AddDeclarationNameInfo(E);
2011 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2012}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002013void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002014 unsigned size = WL.size();
2015 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002016 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002017 D != DEnd; ++D) {
2018 AddDecl(*D, isFirst);
2019 isFirst = false;
2020 }
2021 if (size == WL.size())
2022 return;
2023 // Now reverse the entries we just added. This will match the DFS
2024 // ordering performed by the worklist.
2025 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2026 std::reverse(I, E);
2027}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002029 AddStmt(E->getInit());
2030 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002031 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002032 D = E->designators_rbegin(), DEnd = E->designators_rend();
2033 D != DEnd; ++D) {
2034 if (D->isFieldDesignator()) {
2035 if (FieldDecl *Field = D->getField())
2036 AddMemberRef(Field, D->getFieldLoc());
2037 continue;
2038 }
2039 if (D->isArrayDesignator()) {
2040 AddStmt(E->getArrayIndex(*D));
2041 continue;
2042 }
2043 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2044 AddStmt(E->getArrayRangeEnd(*D));
2045 AddStmt(E->getArrayRangeStart(*D));
2046 }
2047}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002049 EnqueueChildren(E);
2050 AddTypeLoc(E->getTypeInfoAsWritten());
2051}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002053 AddStmt(FS->getBody());
2054 AddStmt(FS->getInc());
2055 AddStmt(FS->getCond());
2056 AddDecl(FS->getConditionVariable());
2057 AddStmt(FS->getInit());
2058}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002060 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2061}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002063 AddStmt(If->getElse());
2064 AddStmt(If->getThen());
2065 AddStmt(If->getCond());
2066 AddDecl(If->getConditionVariable());
2067}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002069 // We care about the syntactic form of the initializer list, only.
2070 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2071 IE = Syntactic;
2072 EnqueueChildren(IE);
2073}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002075 WL.push_back(MemberExprParts(M, Parent));
2076
2077 // If the base of the member access expression is an implicit 'this', don't
2078 // visit it.
2079 // FIXME: If we ever want to show these implicit accesses, this will be
2080 // unfortunate. However, clang_getCursor() relies on this behavior.
2081 if (!M->isImplicitAccess())
2082 AddStmt(M->getBase());
2083}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002085 AddTypeLoc(E->getEncodedTypeSourceInfo());
2086}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002088 EnqueueChildren(M);
2089 AddTypeLoc(M->getClassReceiverTypeInfo());
2090}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002092 // Visit the components of the offsetof expression.
2093 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2094 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2095 const OffsetOfNode &Node = E->getComponent(I-1);
2096 switch (Node.getKind()) {
2097 case OffsetOfNode::Array:
2098 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2099 break;
2100 case OffsetOfNode::Field:
2101 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2102 break;
2103 case OffsetOfNode::Identifier:
2104 case OffsetOfNode::Base:
2105 continue;
2106 }
2107 }
2108 // Visit the type into which we're computing the offset.
2109 AddTypeLoc(E->getTypeSourceInfo());
2110}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002112 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2113 WL.push_back(OverloadExprParts(E, Parent));
2114}
2115void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002116 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002117 EnqueueChildren(E);
2118 if (E->isArgumentType())
2119 AddTypeLoc(E->getArgumentTypeInfo());
2120}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002122 EnqueueChildren(S);
2123}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002125 AddStmt(S->getBody());
2126 AddStmt(S->getCond());
2127 AddDecl(S->getConditionVariable());
2128}
2129
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002131 AddStmt(W->getBody());
2132 AddStmt(W->getCond());
2133 AddDecl(W->getConditionVariable());
2134}
2135
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002137 AddTypeLoc(E->getQueriedTypeSourceInfo());
2138}
2139
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002141 AddTypeLoc(E->getRhsTypeSourceInfo());
2142 AddTypeLoc(E->getLhsTypeSourceInfo());
2143}
2144
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002146 for (unsigned I = E->getNumArgs(); I > 0; --I)
2147 AddTypeLoc(E->getArg(I-1));
2148}
2149
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002151 AddTypeLoc(E->getQueriedTypeSourceInfo());
2152}
2153
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002155 EnqueueChildren(E);
2156}
2157
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002159 VisitOverloadExpr(U);
2160 if (!U->isImplicitAccess())
2161 AddStmt(U->getBase());
2162}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002164 AddStmt(E->getSubExpr());
2165 AddTypeLoc(E->getWrittenTypeInfo());
2166}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002168 WL.push_back(SizeOfPackExprParts(E, Parent));
2169}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002171 // If the opaque value has a source expression, just transparently
2172 // visit that. This is useful for (e.g.) pseudo-object expressions.
2173 if (Expr *SourceExpr = E->getSourceExpr())
2174 return Visit(SourceExpr);
2175}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002177 AddStmt(E->getBody());
2178 WL.push_back(LambdaExprParts(E, Parent));
2179}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002181 // Treat the expression like its syntactic form.
2182 Visit(E->getSyntacticForm());
2183}
2184
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002185void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002186 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2187}
2188
2189bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2190 if (RegionOfInterest.isValid()) {
2191 SourceRange Range = getRawCursorExtent(C);
2192 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2193 return false;
2194 }
2195 return true;
2196}
2197
2198bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2199 while (!WL.empty()) {
2200 // Dequeue the worklist item.
2201 VisitorJob LI = WL.back();
2202 WL.pop_back();
2203
2204 // Set the Parent field, then back to its old value once we're done.
2205 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2206
2207 switch (LI.getKind()) {
2208 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002209 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002210 if (!D)
2211 continue;
2212
2213 // For now, perform default visitation for Decls.
2214 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2215 cast<DeclVisit>(&LI)->isFirst())))
2216 return true;
2217
2218 continue;
2219 }
2220 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2221 const ASTTemplateArgumentListInfo *ArgList =
2222 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2223 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2224 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2225 Arg != ArgEnd; ++Arg) {
2226 if (VisitTemplateArgumentLoc(*Arg))
2227 return true;
2228 }
2229 continue;
2230 }
2231 case VisitorJob::TypeLocVisitKind: {
2232 // Perform default visitation for TypeLocs.
2233 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2234 return true;
2235 continue;
2236 }
2237 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002238 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002239 if (LabelStmt *stmt = LS->getStmt()) {
2240 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2241 TU))) {
2242 return true;
2243 }
2244 }
2245 continue;
2246 }
2247
2248 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2249 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2250 if (VisitNestedNameSpecifierLoc(V->get()))
2251 return true;
2252 continue;
2253 }
2254
2255 case VisitorJob::DeclarationNameInfoVisitKind: {
2256 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2257 ->get()))
2258 return true;
2259 continue;
2260 }
2261 case VisitorJob::MemberRefVisitKind: {
2262 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2263 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2264 return true;
2265 continue;
2266 }
2267 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002268 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002269 if (!S)
2270 continue;
2271
2272 // Update the current cursor.
2273 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2274 if (!IsInRegionOfInterest(Cursor))
2275 continue;
2276 switch (Visitor(Cursor, Parent, ClientData)) {
2277 case CXChildVisit_Break: return true;
2278 case CXChildVisit_Continue: break;
2279 case CXChildVisit_Recurse:
2280 if (PostChildrenVisitor)
2281 WL.push_back(PostChildrenVisit(0, Cursor));
2282 EnqueueWorkList(WL, S);
2283 break;
2284 }
2285 continue;
2286 }
2287 case VisitorJob::MemberExprPartsKind: {
2288 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002289 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002290
2291 // Visit the nested-name-specifier
2292 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2293 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2294 return true;
2295
2296 // Visit the declaration name.
2297 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2298 return true;
2299
2300 // Visit the explicitly-specified template arguments, if any.
2301 if (M->hasExplicitTemplateArgs()) {
2302 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2303 *ArgEnd = Arg + M->getNumTemplateArgs();
2304 Arg != ArgEnd; ++Arg) {
2305 if (VisitTemplateArgumentLoc(*Arg))
2306 return true;
2307 }
2308 }
2309 continue;
2310 }
2311 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002312 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002313 // Visit nested-name-specifier, if present.
2314 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2315 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2316 return true;
2317 // Visit declaration name.
2318 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2319 return true;
2320 continue;
2321 }
2322 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002323 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002324 // Visit the nested-name-specifier.
2325 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2326 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2327 return true;
2328 // Visit the declaration name.
2329 if (VisitDeclarationNameInfo(O->getNameInfo()))
2330 return true;
2331 // Visit the overloaded declaration reference.
2332 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2333 return true;
2334 continue;
2335 }
2336 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002337 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002338 NamedDecl *Pack = E->getPack();
2339 if (isa<TemplateTypeParmDecl>(Pack)) {
2340 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2341 E->getPackLoc(), TU)))
2342 return true;
2343
2344 continue;
2345 }
2346
2347 if (isa<TemplateTemplateParmDecl>(Pack)) {
2348 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2349 E->getPackLoc(), TU)))
2350 return true;
2351
2352 continue;
2353 }
2354
2355 // Non-type template parameter packs and function parameter packs are
2356 // treated like DeclRefExpr cursors.
2357 continue;
2358 }
2359
2360 case VisitorJob::LambdaExprPartsKind: {
2361 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002362 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002363 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2364 CEnd = E->explicit_capture_end();
2365 C != CEnd; ++C) {
2366 if (C->capturesThis())
2367 continue;
2368
2369 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2370 C->getLocation(),
2371 TU)))
2372 return true;
2373 }
2374
2375 // Visit parameters and return type, if present.
2376 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2377 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2378 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2379 // Visit the whole type.
2380 if (Visit(TL))
2381 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002382 } else if (FunctionProtoTypeLoc Proto =
2383 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002384 if (E->hasExplicitParameters()) {
2385 // Visit parameters.
2386 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2387 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2388 return true;
2389 } else {
2390 // Visit result type.
2391 if (Visit(Proto.getResultLoc()))
2392 return true;
2393 }
2394 }
2395 }
2396 break;
2397 }
2398
2399 case VisitorJob::PostChildrenVisitKind:
2400 if (PostChildrenVisitor(Parent, ClientData))
2401 return true;
2402 break;
2403 }
2404 }
2405 return false;
2406}
2407
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002408bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002409 VisitorWorkList *WL = 0;
2410 if (!WorkListFreeList.empty()) {
2411 WL = WorkListFreeList.back();
2412 WL->clear();
2413 WorkListFreeList.pop_back();
2414 }
2415 else {
2416 WL = new VisitorWorkList();
2417 WorkListCache.push_back(WL);
2418 }
2419 EnqueueWorkList(*WL, S);
2420 bool result = RunVisitorWorkList(*WL);
2421 WorkListFreeList.push_back(WL);
2422 return result;
2423}
2424
2425namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002426typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002427RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2428 const DeclarationNameInfo &NI,
2429 const SourceRange &QLoc,
2430 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2431 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2432 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2433 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2434
2435 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2436
2437 RefNamePieces Pieces;
2438
2439 if (WantQualifier && QLoc.isValid())
2440 Pieces.push_back(QLoc);
2441
2442 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2443 Pieces.push_back(NI.getLoc());
2444
2445 if (WantTemplateArgs && TemplateArgs)
2446 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2447 TemplateArgs->RAngleLoc));
2448
2449 if (Kind == DeclarationName::CXXOperatorName) {
2450 Pieces.push_back(SourceLocation::getFromRawEncoding(
2451 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2452 Pieces.push_back(SourceLocation::getFromRawEncoding(
2453 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2454 }
2455
2456 if (WantSinglePiece) {
2457 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2458 Pieces.clear();
2459 Pieces.push_back(R);
2460 }
2461
2462 return Pieces;
2463}
2464}
2465
2466//===----------------------------------------------------------------------===//
2467// Misc. API hooks.
2468//===----------------------------------------------------------------------===//
2469
2470static llvm::sys::Mutex EnableMultithreadingMutex;
2471static bool EnabledMultithreading;
2472
Chad Rosier90836282013-03-27 18:28:23 +00002473static void fatal_error_handler(void *user_data, const std::string& reason,
2474 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002475 // Write the result out to stderr avoiding errs() because raw_ostreams can
2476 // call report_fatal_error.
2477 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2478 ::abort();
2479}
2480
2481extern "C" {
2482CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2483 int displayDiagnostics) {
2484 // Disable pretty stack trace functionality, which will otherwise be a very
2485 // poor citizen of the world and set up all sorts of signal handlers.
2486 llvm::DisablePrettyStackTrace = true;
2487
2488 // We use crash recovery to make some of our APIs more reliable, implicitly
2489 // enable it.
2490 llvm::CrashRecoveryContext::Enable();
2491
2492 // Enable support for multithreading in LLVM.
2493 {
2494 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2495 if (!EnabledMultithreading) {
2496 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2497 llvm::llvm_start_multithreaded();
2498 EnabledMultithreading = true;
2499 }
2500 }
2501
2502 CIndexer *CIdxr = new CIndexer();
2503 if (excludeDeclarationsFromPCH)
2504 CIdxr->setOnlyLocalDecls();
2505 if (displayDiagnostics)
2506 CIdxr->setDisplayDiagnostics();
2507
2508 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2509 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2510 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2511 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2512 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2513 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2514
2515 return CIdxr;
2516}
2517
2518void clang_disposeIndex(CXIndex CIdx) {
2519 if (CIdx)
2520 delete static_cast<CIndexer *>(CIdx);
2521}
2522
2523void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2524 if (CIdx)
2525 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2526}
2527
2528unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2529 if (CIdx)
2530 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2531 return 0;
2532}
2533
2534void clang_toggleCrashRecovery(unsigned isEnabled) {
2535 if (isEnabled)
2536 llvm::CrashRecoveryContext::Enable();
2537 else
2538 llvm::CrashRecoveryContext::Disable();
2539}
2540
2541CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2542 const char *ast_filename) {
2543 if (!CIdx)
2544 return 0;
2545
2546 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2547 FileSystemOptions FileSystemOpts;
2548
2549 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2550 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2551 CXXIdx->getOnlyLocalDecls(),
2552 0, 0,
2553 /*CaptureDiagnostics=*/true,
2554 /*AllowPCHWithCompilerErrors=*/true,
2555 /*UserFilesAreVolatile=*/true);
2556 return MakeCXTranslationUnit(CXXIdx, TU);
2557}
2558
2559unsigned clang_defaultEditingTranslationUnitOptions() {
2560 return CXTranslationUnit_PrecompiledPreamble |
2561 CXTranslationUnit_CacheCompletionResults;
2562}
2563
2564CXTranslationUnit
2565clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2566 const char *source_filename,
2567 int num_command_line_args,
2568 const char * const *command_line_args,
2569 unsigned num_unsaved_files,
2570 struct CXUnsavedFile *unsaved_files) {
2571 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2572 return clang_parseTranslationUnit(CIdx, source_filename,
2573 command_line_args, num_command_line_args,
2574 unsaved_files, num_unsaved_files,
2575 Options);
2576}
2577
2578struct ParseTranslationUnitInfo {
2579 CXIndex CIdx;
2580 const char *source_filename;
2581 const char *const *command_line_args;
2582 int num_command_line_args;
2583 struct CXUnsavedFile *unsaved_files;
2584 unsigned num_unsaved_files;
2585 unsigned options;
2586 CXTranslationUnit result;
2587};
2588static void clang_parseTranslationUnit_Impl(void *UserData) {
2589 ParseTranslationUnitInfo *PTUI =
2590 static_cast<ParseTranslationUnitInfo*>(UserData);
2591 CXIndex CIdx = PTUI->CIdx;
2592 const char *source_filename = PTUI->source_filename;
2593 const char * const *command_line_args = PTUI->command_line_args;
2594 int num_command_line_args = PTUI->num_command_line_args;
2595 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2596 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2597 unsigned options = PTUI->options;
2598 PTUI->result = 0;
2599
2600 if (!CIdx)
2601 return;
2602
2603 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2604
2605 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2606 setThreadBackgroundPriority();
2607
2608 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2609 // FIXME: Add a flag for modules.
2610 TranslationUnitKind TUKind
2611 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2612 bool CacheCodeCompetionResults
2613 = options & CXTranslationUnit_CacheCompletionResults;
2614 bool IncludeBriefCommentsInCodeCompletion
2615 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2616 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2617 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2618
2619 // Configure the diagnostics.
2620 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002621 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002622
2623 // Recover resources if we crash before exiting this function.
2624 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2625 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2626 DiagCleanup(Diags.getPtr());
2627
2628 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2629 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2630
2631 // Recover resources if we crash before exiting this function.
2632 llvm::CrashRecoveryContextCleanupRegistrar<
2633 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2634
2635 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2636 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2637 const llvm::MemoryBuffer *Buffer
2638 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2639 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2640 Buffer));
2641 }
2642
2643 OwningPtr<std::vector<const char *> >
2644 Args(new std::vector<const char*>());
2645
2646 // Recover resources if we crash before exiting this method.
2647 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2648 ArgsCleanup(Args.get());
2649
2650 // Since the Clang C library is primarily used by batch tools dealing with
2651 // (often very broken) source code, where spell-checking can have a
2652 // significant negative impact on performance (particularly when
2653 // precompiled headers are involved), we disable it by default.
2654 // Only do this if we haven't found a spell-checking-related argument.
2655 bool FoundSpellCheckingArgument = false;
2656 for (int I = 0; I != num_command_line_args; ++I) {
2657 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2658 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2659 FoundSpellCheckingArgument = true;
2660 break;
2661 }
2662 }
2663 if (!FoundSpellCheckingArgument)
2664 Args->push_back("-fno-spell-checking");
2665
2666 Args->insert(Args->end(), command_line_args,
2667 command_line_args + num_command_line_args);
2668
2669 // The 'source_filename' argument is optional. If the caller does not
2670 // specify it then it is assumed that the source file is specified
2671 // in the actual argument list.
2672 // Put the source file after command_line_args otherwise if '-x' flag is
2673 // present it will be unused.
2674 if (source_filename)
2675 Args->push_back(source_filename);
2676
2677 // Do we need the detailed preprocessing record?
2678 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2679 Args->push_back("-Xclang");
2680 Args->push_back("-detailed-preprocessing-record");
2681 }
2682
2683 unsigned NumErrors = Diags->getClient()->getNumErrors();
2684 OwningPtr<ASTUnit> ErrUnit;
2685 OwningPtr<ASTUnit> Unit(
2686 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2687 /* vector::data() not portable */,
2688 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2689 Diags,
2690 CXXIdx->getClangResourcesPath(),
2691 CXXIdx->getOnlyLocalDecls(),
2692 /*CaptureDiagnostics=*/true,
2693 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2694 RemappedFiles->size(),
2695 /*RemappedFilesKeepOriginalName=*/true,
2696 PrecompilePreamble,
2697 TUKind,
2698 CacheCodeCompetionResults,
2699 IncludeBriefCommentsInCodeCompletion,
2700 /*AllowPCHWithCompilerErrors=*/true,
2701 SkipFunctionBodies,
2702 /*UserFilesAreVolatile=*/true,
2703 ForSerialization,
2704 &ErrUnit));
2705
2706 if (NumErrors != Diags->getClient()->getNumErrors()) {
2707 // Make sure to check that 'Unit' is non-NULL.
2708 if (CXXIdx->getDisplayDiagnostics())
2709 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2710 }
2711
2712 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2713}
2714CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2715 const char *source_filename,
2716 const char * const *command_line_args,
2717 int num_command_line_args,
2718 struct CXUnsavedFile *unsaved_files,
2719 unsigned num_unsaved_files,
2720 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002721 LOG_FUNC_SECTION {
2722 *Log << source_filename << ": ";
2723 for (int i = 0; i != num_command_line_args; ++i)
2724 *Log << command_line_args[i] << " ";
2725 }
2726
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002727 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2728 num_command_line_args, unsaved_files,
2729 num_unsaved_files, options, 0 };
2730 llvm::CrashRecoveryContext CRC;
2731
2732 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2733 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2734 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2735 fprintf(stderr, " 'command_line_args' : [");
2736 for (int i = 0; i != num_command_line_args; ++i) {
2737 if (i)
2738 fprintf(stderr, ", ");
2739 fprintf(stderr, "'%s'", command_line_args[i]);
2740 }
2741 fprintf(stderr, "],\n");
2742 fprintf(stderr, " 'unsaved_files' : [");
2743 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2744 if (i)
2745 fprintf(stderr, ", ");
2746 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2747 unsaved_files[i].Length);
2748 }
2749 fprintf(stderr, "],\n");
2750 fprintf(stderr, " 'options' : %d,\n", options);
2751 fprintf(stderr, "}\n");
2752
2753 return 0;
2754 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2755 PrintLibclangResourceUsage(PTUI.result);
2756 }
2757
2758 return PTUI.result;
2759}
2760
2761unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2762 return CXSaveTranslationUnit_None;
2763}
2764
2765namespace {
2766
2767struct SaveTranslationUnitInfo {
2768 CXTranslationUnit TU;
2769 const char *FileName;
2770 unsigned options;
2771 CXSaveError result;
2772};
2773
2774}
2775
2776static void clang_saveTranslationUnit_Impl(void *UserData) {
2777 SaveTranslationUnitInfo *STUI =
2778 static_cast<SaveTranslationUnitInfo*>(UserData);
2779
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002780 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002781 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2782 setThreadBackgroundPriority();
2783
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002784 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002785 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2786}
2787
2788int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2789 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002790 LOG_FUNC_SECTION {
2791 *Log << TU << ' ' << FileName;
2792 }
2793
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002794 if (!TU)
2795 return CXSaveError_InvalidTU;
2796
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002797 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002798 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2799 if (!CXXUnit->hasSema())
2800 return CXSaveError_InvalidTU;
2801
2802 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2803
2804 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2805 getenv("LIBCLANG_NOTHREADS")) {
2806 clang_saveTranslationUnit_Impl(&STUI);
2807
2808 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2809 PrintLibclangResourceUsage(TU);
2810
2811 return STUI.result;
2812 }
2813
2814 // We have an AST that has invalid nodes due to compiler errors.
2815 // Use a crash recovery thread for protection.
2816
2817 llvm::CrashRecoveryContext CRC;
2818
2819 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2820 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2821 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2822 fprintf(stderr, " 'options' : %d,\n", options);
2823 fprintf(stderr, "}\n");
2824
2825 return CXSaveError_Unknown;
2826
2827 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2828 PrintLibclangResourceUsage(TU);
2829 }
2830
2831 return STUI.result;
2832}
2833
2834void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2835 if (CTUnit) {
2836 // If the translation unit has been marked as unsafe to free, just discard
2837 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002838 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002839 return;
2840
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002841 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002842 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002843 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2844 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002845 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002846 delete CTUnit;
2847 }
2848}
2849
2850unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2851 return CXReparse_None;
2852}
2853
2854struct ReparseTranslationUnitInfo {
2855 CXTranslationUnit TU;
2856 unsigned num_unsaved_files;
2857 struct CXUnsavedFile *unsaved_files;
2858 unsigned options;
2859 int result;
2860};
2861
2862static void clang_reparseTranslationUnit_Impl(void *UserData) {
2863 ReparseTranslationUnitInfo *RTUI =
2864 static_cast<ReparseTranslationUnitInfo*>(UserData);
2865 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002866 if (!TU)
2867 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002868
2869 // Reset the associated diagnostics.
2870 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2871 TU->Diagnostics = 0;
2872
2873 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2874 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2875 unsigned options = RTUI->options;
2876 (void) options;
2877 RTUI->result = 1;
2878
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002879 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002880 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2881 setThreadBackgroundPriority();
2882
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002883 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002884 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2885
2886 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2887 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2888
2889 // Recover resources if we crash before exiting this function.
2890 llvm::CrashRecoveryContextCleanupRegistrar<
2891 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2892
2893 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2894 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2895 const llvm::MemoryBuffer *Buffer
2896 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2897 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2898 Buffer));
2899 }
2900
2901 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2902 RemappedFiles->size()))
2903 RTUI->result = 0;
2904}
2905
2906int clang_reparseTranslationUnit(CXTranslationUnit TU,
2907 unsigned num_unsaved_files,
2908 struct CXUnsavedFile *unsaved_files,
2909 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002910 LOG_FUNC_SECTION {
2911 *Log << TU;
2912 }
2913
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002914 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2915 options, 0 };
2916
2917 if (getenv("LIBCLANG_NOTHREADS")) {
2918 clang_reparseTranslationUnit_Impl(&RTUI);
2919 return RTUI.result;
2920 }
2921
2922 llvm::CrashRecoveryContext CRC;
2923
2924 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2925 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002926 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002927 return 1;
2928 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2929 PrintLibclangResourceUsage(TU);
2930
2931 return RTUI.result;
2932}
2933
2934
2935CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2936 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002937 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002938
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002939 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002940 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002941}
2942
2943CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00002944 if (!TU)
2945 return clang_getNullCursor();
2946
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002947 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002948 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2949}
2950
2951} // end: extern "C"
2952
2953//===----------------------------------------------------------------------===//
2954// CXFile Operations.
2955//===----------------------------------------------------------------------===//
2956
2957extern "C" {
2958CXString clang_getFileName(CXFile SFile) {
2959 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002960 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002961
2962 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002963 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002964}
2965
2966time_t clang_getFileTime(CXFile SFile) {
2967 if (!SFile)
2968 return 0;
2969
2970 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2971 return FEnt->getModificationTime();
2972}
2973
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002974CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2975 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002976 return 0;
2977
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002978 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002979
2980 FileManager &FMgr = CXXUnit->getFileManager();
2981 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2982}
2983
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002984unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2985 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002986 return 0;
2987
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002988 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002989 FileEntry *FEnt = static_cast<FileEntry *>(file);
2990 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2991 .isFileMultipleIncludeGuarded(FEnt);
2992}
2993
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002994int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2995 if (!file || !outID)
2996 return 1;
2997
2998#ifdef LLVM_ON_WIN32
2999 return 1; // inodes not supported on windows.
3000#else
3001 FileEntry *FEnt = static_cast<FileEntry *>(file);
3002 outID->data[0] = FEnt->getDevice();
3003 outID->data[1] = FEnt->getInode();
3004 outID->data[2] = FEnt->getModificationTime();
3005 return 0;
3006#endif
3007}
3008
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003009} // end: extern "C"
3010
3011//===----------------------------------------------------------------------===//
3012// CXCursor Operations.
3013//===----------------------------------------------------------------------===//
3014
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003015static const Decl *getDeclFromExpr(const Stmt *E) {
3016 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003017 return getDeclFromExpr(CE->getSubExpr());
3018
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003019 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003020 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003021 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003022 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003023 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003024 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003025 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003026 if (PRE->isExplicitProperty())
3027 return PRE->getExplicitProperty();
3028 // It could be messaging both getter and setter as in:
3029 // ++myobj.myprop;
3030 // in which case prefer to associate the setter since it is less obvious
3031 // from inspecting the source that the setter is going to get called.
3032 if (PRE->isMessagingSetter())
3033 return PRE->getImplicitPropertySetter();
3034 return PRE->getImplicitPropertyGetter();
3035 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003036 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003037 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003038 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003039 if (Expr *Src = OVE->getSourceExpr())
3040 return getDeclFromExpr(Src);
3041
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003042 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003043 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003044 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003045 if (!CE->isElidable())
3046 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003047 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003048 return OME->getMethodDecl();
3049
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003050 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003052 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003053 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3054 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003055 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003056 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3057 isa<ParmVarDecl>(SizeOfPack->getPack()))
3058 return SizeOfPack->getPack();
3059
3060 return 0;
3061}
3062
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003063static SourceLocation getLocationFromExpr(const Expr *E) {
3064 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003065 return getLocationFromExpr(CE->getSubExpr());
3066
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003067 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003068 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003069 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003070 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003071 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003072 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003073 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003074 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003075 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003076 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003077 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003078 return PropRef->getLocation();
3079
3080 return E->getLocStart();
3081}
3082
3083extern "C" {
3084
3085unsigned clang_visitChildren(CXCursor parent,
3086 CXCursorVisitor visitor,
3087 CXClientData client_data) {
3088 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3089 /*VisitPreprocessorLast=*/false);
3090 return CursorVis.VisitChildren(parent);
3091}
3092
3093#ifndef __has_feature
3094#define __has_feature(x) 0
3095#endif
3096#if __has_feature(blocks)
3097typedef enum CXChildVisitResult
3098 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3099
3100static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3101 CXClientData client_data) {
3102 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3103 return block(cursor, parent);
3104}
3105#else
3106// If we are compiled with a compiler that doesn't have native blocks support,
3107// define and call the block manually, so the
3108typedef struct _CXChildVisitResult
3109{
3110 void *isa;
3111 int flags;
3112 int reserved;
3113 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3114 CXCursor);
3115} *CXCursorVisitorBlock;
3116
3117static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3118 CXClientData client_data) {
3119 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3120 return block->invoke(block, cursor, parent);
3121}
3122#endif
3123
3124
3125unsigned clang_visitChildrenWithBlock(CXCursor parent,
3126 CXCursorVisitorBlock block) {
3127 return clang_visitChildren(parent, visitWithBlock, block);
3128}
3129
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003130static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003131 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003132 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003134 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003136 if (const ObjCPropertyImplDecl *PropImpl =
3137 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003138 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003139 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003140
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003141 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003142 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003143 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003144
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003145 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003146 }
3147
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003148 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003149 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003150
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003151 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003152 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3153 // and returns different names. NamedDecl returns the class name and
3154 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003155 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003156
3157 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003158 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003159
3160 SmallString<1024> S;
3161 llvm::raw_svector_ostream os(S);
3162 ND->printName(os);
3163
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003164 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003165}
3166
3167CXString clang_getCursorSpelling(CXCursor C) {
3168 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003169 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003170
3171 if (clang_isReference(C.kind)) {
3172 switch (C.kind) {
3173 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003174 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003175 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003176 }
3177 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003178 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003179 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003180 }
3181 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003182 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003183 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003184 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003185 }
3186 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003187 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003188 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003189 }
3190 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003191 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 assert(Type && "Missing type decl");
3193
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003194 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195 getAsString());
3196 }
3197 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003198 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 assert(Template && "Missing template decl");
3200
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003201 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003202 }
3203
3204 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003205 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003206 assert(NS && "Missing namespace decl");
3207
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003208 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209 }
3210
3211 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003212 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003213 assert(Field && "Missing member decl");
3214
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003215 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003216 }
3217
3218 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003219 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003220 assert(Label && "Missing label");
3221
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003222 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003223 }
3224
3225 case CXCursor_OverloadedDeclRef: {
3226 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003227 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3228 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003229 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003230 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003231 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003232 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003233 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003234 OverloadedTemplateStorage *Ovl
3235 = Storage.get<OverloadedTemplateStorage*>();
3236 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003237 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003238 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003239 }
3240
3241 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003242 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003243 assert(Var && "Missing variable decl");
3244
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003245 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246 }
3247
3248 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003249 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003250 }
3251 }
3252
3253 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003254 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003255 if (D)
3256 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003257 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 }
3259
3260 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003261 const Stmt *S = getCursorStmt(C);
3262 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003263 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003264
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003265 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003266 }
3267
3268 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003269 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003270 ->getNameStart());
3271
3272 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003273 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003274 ->getNameStart());
3275
3276 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003277 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003278
3279 if (clang_isDeclaration(C.kind))
3280 return getDeclSpelling(getCursorDecl(C));
3281
3282 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003283 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003284 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003285 }
3286
3287 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003288 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003289 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003290 }
3291
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003292 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293}
3294
3295CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3296 unsigned pieceIndex,
3297 unsigned options) {
3298 if (clang_Cursor_isNull(C))
3299 return clang_getNullRange();
3300
3301 ASTContext &Ctx = getCursorContext(C);
3302
3303 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003304 const Stmt *S = getCursorStmt(C);
3305 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003306 if (pieceIndex > 0)
3307 return clang_getNullRange();
3308 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3309 }
3310
3311 return clang_getNullRange();
3312 }
3313
3314 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003315 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003316 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3317 if (pieceIndex >= ME->getNumSelectorLocs())
3318 return clang_getNullRange();
3319 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3320 }
3321 }
3322
3323 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3324 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003325 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003326 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3327 if (pieceIndex >= MD->getNumSelectorLocs())
3328 return clang_getNullRange();
3329 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3330 }
3331 }
3332
3333 if (C.kind == CXCursor_ObjCCategoryDecl ||
3334 C.kind == CXCursor_ObjCCategoryImplDecl) {
3335 if (pieceIndex > 0)
3336 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003337 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003338 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3339 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003340 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003341 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3342 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3343 }
3344
3345 if (C.kind == CXCursor_ModuleImportDecl) {
3346 if (pieceIndex > 0)
3347 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003348 if (const ImportDecl *ImportD =
3349 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003350 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3351 if (!Locs.empty())
3352 return cxloc::translateSourceRange(Ctx,
3353 SourceRange(Locs.front(), Locs.back()));
3354 }
3355 return clang_getNullRange();
3356 }
3357
3358 // FIXME: A CXCursor_InclusionDirective should give the location of the
3359 // filename, but we don't keep track of this.
3360
3361 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3362 // but we don't keep track of this.
3363
3364 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3365 // but we don't keep track of this.
3366
3367 // Default handling, give the location of the cursor.
3368
3369 if (pieceIndex > 0)
3370 return clang_getNullRange();
3371
3372 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3373 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3374 return cxloc::translateSourceRange(Ctx, Loc);
3375}
3376
3377CXString clang_getCursorDisplayName(CXCursor C) {
3378 if (!clang_isDeclaration(C.kind))
3379 return clang_getCursorSpelling(C);
3380
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003381 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003382 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003383 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003384
3385 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003386 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003387 D = FunTmpl->getTemplatedDecl();
3388
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003389 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003390 SmallString<64> Str;
3391 llvm::raw_svector_ostream OS(Str);
3392 OS << *Function;
3393 if (Function->getPrimaryTemplate())
3394 OS << "<>";
3395 OS << "(";
3396 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3397 if (I)
3398 OS << ", ";
3399 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3400 }
3401
3402 if (Function->isVariadic()) {
3403 if (Function->getNumParams())
3404 OS << ", ";
3405 OS << "...";
3406 }
3407 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003408 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003409 }
3410
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003411 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003412 SmallString<64> Str;
3413 llvm::raw_svector_ostream OS(Str);
3414 OS << *ClassTemplate;
3415 OS << "<";
3416 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3417 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3418 if (I)
3419 OS << ", ";
3420
3421 NamedDecl *Param = Params->getParam(I);
3422 if (Param->getIdentifier()) {
3423 OS << Param->getIdentifier()->getName();
3424 continue;
3425 }
3426
3427 // There is no parameter name, which makes this tricky. Try to come up
3428 // with something useful that isn't too long.
3429 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3430 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3431 else if (NonTypeTemplateParmDecl *NTTP
3432 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3433 OS << NTTP->getType().getAsString(Policy);
3434 else
3435 OS << "template<...> class";
3436 }
3437
3438 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003439 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003440 }
3441
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003442 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003443 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3444 // If the type was explicitly written, use that.
3445 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003446 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003447
Benjamin Kramer5eada842013-02-22 15:46:01 +00003448 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003449 llvm::raw_svector_ostream OS(Str);
3450 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003451 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003452 ClassSpec->getTemplateArgs().data(),
3453 ClassSpec->getTemplateArgs().size(),
3454 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003455 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003456 }
3457
3458 return clang_getCursorSpelling(C);
3459}
3460
3461CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3462 switch (Kind) {
3463 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003464 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003465 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003466 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003467 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003468 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003469 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003470 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003472 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003474 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003591 case CXCursor_ObjCSelfExpr:
3592 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003742 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003743 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003744 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003745 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003746 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003747 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003748 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003749 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003751 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003752 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003753 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003754 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003755 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003756 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003757 }
3758
3759 llvm_unreachable("Unhandled CXCursorKind");
3760}
3761
3762struct GetCursorData {
3763 SourceLocation TokenBeginLoc;
3764 bool PointsAtMacroArgExpansion;
3765 bool VisitedObjCPropertyImplDecl;
3766 SourceLocation VisitedDeclaratorDeclStartLoc;
3767 CXCursor &BestCursor;
3768
3769 GetCursorData(SourceManager &SM,
3770 SourceLocation tokenBegin, CXCursor &outputCursor)
3771 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3772 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3773 VisitedObjCPropertyImplDecl = false;
3774 }
3775};
3776
3777static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3778 CXCursor parent,
3779 CXClientData client_data) {
3780 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3781 CXCursor *BestCursor = &Data->BestCursor;
3782
3783 // If we point inside a macro argument we should provide info of what the
3784 // token is so use the actual cursor, don't replace it with a macro expansion
3785 // cursor.
3786 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3787 return CXChildVisit_Recurse;
3788
3789 if (clang_isDeclaration(cursor.kind)) {
3790 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003791 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003792 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3793 if (MD->isImplicit())
3794 return CXChildVisit_Break;
3795
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003796 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003797 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3798 // Check that when we have multiple @class references in the same line,
3799 // that later ones do not override the previous ones.
3800 // If we have:
3801 // @class Foo, Bar;
3802 // source ranges for both start at '@', so 'Bar' will end up overriding
3803 // 'Foo' even though the cursor location was at 'Foo'.
3804 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3805 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003806 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003807 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3808 if (PrevID != ID &&
3809 !PrevID->isThisDeclarationADefinition() &&
3810 !ID->isThisDeclarationADefinition())
3811 return CXChildVisit_Break;
3812 }
3813
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003814 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003815 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3816 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3817 // Check that when we have multiple declarators in the same line,
3818 // that later ones do not override the previous ones.
3819 // If we have:
3820 // int Foo, Bar;
3821 // source ranges for both start at 'int', so 'Bar' will end up overriding
3822 // 'Foo' even though the cursor location was at 'Foo'.
3823 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3824 return CXChildVisit_Break;
3825 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3826
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003827 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003828 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3829 (void)PropImp;
3830 // Check that when we have multiple @synthesize in the same line,
3831 // that later ones do not override the previous ones.
3832 // If we have:
3833 // @synthesize Foo, Bar;
3834 // source ranges for both start at '@', so 'Bar' will end up overriding
3835 // 'Foo' even though the cursor location was at 'Foo'.
3836 if (Data->VisitedObjCPropertyImplDecl)
3837 return CXChildVisit_Break;
3838 Data->VisitedObjCPropertyImplDecl = true;
3839 }
3840 }
3841
3842 if (clang_isExpression(cursor.kind) &&
3843 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003844 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003845 // Avoid having the cursor of an expression replace the declaration cursor
3846 // when the expression source range overlaps the declaration range.
3847 // This can happen for C++ constructor expressions whose range generally
3848 // include the variable declaration, e.g.:
3849 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3850 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3851 D->getLocation() == Data->TokenBeginLoc)
3852 return CXChildVisit_Break;
3853 }
3854 }
3855
3856 // If our current best cursor is the construction of a temporary object,
3857 // don't replace that cursor with a type reference, because we want
3858 // clang_getCursor() to point at the constructor.
3859 if (clang_isExpression(BestCursor->kind) &&
3860 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3861 cursor.kind == CXCursor_TypeRef) {
3862 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3863 // as having the actual point on the type reference.
3864 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3865 return CXChildVisit_Recurse;
3866 }
3867
3868 *BestCursor = cursor;
3869 return CXChildVisit_Recurse;
3870}
3871
3872CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3873 if (!TU)
3874 return clang_getNullCursor();
3875
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003876 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003877 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3878
3879 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3880 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3881
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003882 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003883 CXFile SearchFile;
3884 unsigned SearchLine, SearchColumn;
3885 CXFile ResultFile;
3886 unsigned ResultLine, ResultColumn;
3887 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3888 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3889 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3890
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003891 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3892 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003893 &ResultColumn, 0);
3894 SearchFileName = clang_getFileName(SearchFile);
3895 ResultFileName = clang_getFileName(ResultFile);
3896 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3897 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003898 *Log << llvm::format("(%s:%d:%d) = %s",
3899 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3900 clang_getCString(KindSpelling))
3901 << llvm::format("(%s:%d:%d):%s%s",
3902 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3903 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003904 clang_disposeString(SearchFileName);
3905 clang_disposeString(ResultFileName);
3906 clang_disposeString(KindSpelling);
3907 clang_disposeString(USR);
3908
3909 CXCursor Definition = clang_getCursorDefinition(Result);
3910 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3911 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3912 CXString DefinitionKindSpelling
3913 = clang_getCursorKindSpelling(Definition.kind);
3914 CXFile DefinitionFile;
3915 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003916 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003917 &DefinitionLine, &DefinitionColumn, 0);
3918 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003919 *Log << llvm::format(" -> %s(%s:%d:%d)",
3920 clang_getCString(DefinitionKindSpelling),
3921 clang_getCString(DefinitionFileName),
3922 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003923 clang_disposeString(DefinitionFileName);
3924 clang_disposeString(DefinitionKindSpelling);
3925 }
3926 }
3927
3928 return Result;
3929}
3930
3931CXCursor clang_getNullCursor(void) {
3932 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3933}
3934
3935unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003936 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3937 // can't set consistently. For example, when visiting a DeclStmt we will set
3938 // it but we don't set it on the result of clang_getCursorDefinition for
3939 // a reference of the same declaration.
3940 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3941 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3942 // to provide that kind of info.
3943 if (clang_isDeclaration(X.kind))
3944 X.data[1] = 0;
3945 if (clang_isDeclaration(Y.kind))
3946 Y.data[1] = 0;
3947
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003948 return X == Y;
3949}
3950
3951unsigned clang_hashCursor(CXCursor C) {
3952 unsigned Index = 0;
3953 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3954 Index = 1;
3955
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003956 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003957 std::make_pair(C.kind, C.data[Index]));
3958}
3959
3960unsigned clang_isInvalid(enum CXCursorKind K) {
3961 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3962}
3963
3964unsigned clang_isDeclaration(enum CXCursorKind K) {
3965 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3966 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3967}
3968
3969unsigned clang_isReference(enum CXCursorKind K) {
3970 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3971}
3972
3973unsigned clang_isExpression(enum CXCursorKind K) {
3974 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3975}
3976
3977unsigned clang_isStatement(enum CXCursorKind K) {
3978 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3979}
3980
3981unsigned clang_isAttribute(enum CXCursorKind K) {
3982 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3983}
3984
3985unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3986 return K == CXCursor_TranslationUnit;
3987}
3988
3989unsigned clang_isPreprocessing(enum CXCursorKind K) {
3990 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3991}
3992
3993unsigned clang_isUnexposed(enum CXCursorKind K) {
3994 switch (K) {
3995 case CXCursor_UnexposedDecl:
3996 case CXCursor_UnexposedExpr:
3997 case CXCursor_UnexposedStmt:
3998 case CXCursor_UnexposedAttr:
3999 return true;
4000 default:
4001 return false;
4002 }
4003}
4004
4005CXCursorKind clang_getCursorKind(CXCursor C) {
4006 return C.kind;
4007}
4008
4009CXSourceLocation clang_getCursorLocation(CXCursor C) {
4010 if (clang_isReference(C.kind)) {
4011 switch (C.kind) {
4012 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004013 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004014 = getCursorObjCSuperClassRef(C);
4015 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4016 }
4017
4018 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004019 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004020 = getCursorObjCProtocolRef(C);
4021 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4022 }
4023
4024 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004025 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004026 = getCursorObjCClassRef(C);
4027 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4028 }
4029
4030 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004031 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004032 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4033 }
4034
4035 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004036 std::pair<const TemplateDecl *, SourceLocation> P =
4037 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004038 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4039 }
4040
4041 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004042 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004043 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4044 }
4045
4046 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004047 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004048 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4049 }
4050
4051 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004052 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004053 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4054 }
4055
4056 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004057 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004058 if (!BaseSpec)
4059 return clang_getNullLocation();
4060
4061 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4062 return cxloc::translateSourceLocation(getCursorContext(C),
4063 TSInfo->getTypeLoc().getBeginLoc());
4064
4065 return cxloc::translateSourceLocation(getCursorContext(C),
4066 BaseSpec->getLocStart());
4067 }
4068
4069 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004070 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004071 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4072 }
4073
4074 case CXCursor_OverloadedDeclRef:
4075 return cxloc::translateSourceLocation(getCursorContext(C),
4076 getCursorOverloadedDeclRef(C).second);
4077
4078 default:
4079 // FIXME: Need a way to enumerate all non-reference cases.
4080 llvm_unreachable("Missed a reference kind");
4081 }
4082 }
4083
4084 if (clang_isExpression(C.kind))
4085 return cxloc::translateSourceLocation(getCursorContext(C),
4086 getLocationFromExpr(getCursorExpr(C)));
4087
4088 if (clang_isStatement(C.kind))
4089 return cxloc::translateSourceLocation(getCursorContext(C),
4090 getCursorStmt(C)->getLocStart());
4091
4092 if (C.kind == CXCursor_PreprocessingDirective) {
4093 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4094 return cxloc::translateSourceLocation(getCursorContext(C), L);
4095 }
4096
4097 if (C.kind == CXCursor_MacroExpansion) {
4098 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004099 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004100 return cxloc::translateSourceLocation(getCursorContext(C), L);
4101 }
4102
4103 if (C.kind == CXCursor_MacroDefinition) {
4104 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4105 return cxloc::translateSourceLocation(getCursorContext(C), L);
4106 }
4107
4108 if (C.kind == CXCursor_InclusionDirective) {
4109 SourceLocation L
4110 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4111 return cxloc::translateSourceLocation(getCursorContext(C), L);
4112 }
4113
4114 if (!clang_isDeclaration(C.kind))
4115 return clang_getNullLocation();
4116
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004117 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004118 if (!D)
4119 return clang_getNullLocation();
4120
4121 SourceLocation Loc = D->getLocation();
4122 // FIXME: Multiple variables declared in a single declaration
4123 // currently lack the information needed to correctly determine their
4124 // ranges when accounting for the type-specifier. We use context
4125 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4126 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004127 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004128 if (!cxcursor::isFirstInDeclGroup(C))
4129 Loc = VD->getLocation();
4130 }
4131
4132 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004133 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004134 Loc = MD->getSelectorStartLoc();
4135
4136 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4137}
4138
4139} // end extern "C"
4140
4141CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4142 assert(TU);
4143
4144 // Guard against an invalid SourceLocation, or we may assert in one
4145 // of the following calls.
4146 if (SLoc.isInvalid())
4147 return clang_getNullCursor();
4148
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004149 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004150
4151 // Translate the given source location to make it point at the beginning of
4152 // the token under the cursor.
4153 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4154 CXXUnit->getASTContext().getLangOpts());
4155
4156 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4157 if (SLoc.isValid()) {
4158 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4159 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4160 /*VisitPreprocessorLast=*/true,
4161 /*VisitIncludedEntities=*/false,
4162 SourceLocation(SLoc));
4163 CursorVis.visitFileRegion();
4164 }
4165
4166 return Result;
4167}
4168
4169static SourceRange getRawCursorExtent(CXCursor C) {
4170 if (clang_isReference(C.kind)) {
4171 switch (C.kind) {
4172 case CXCursor_ObjCSuperClassRef:
4173 return getCursorObjCSuperClassRef(C).second;
4174
4175 case CXCursor_ObjCProtocolRef:
4176 return getCursorObjCProtocolRef(C).second;
4177
4178 case CXCursor_ObjCClassRef:
4179 return getCursorObjCClassRef(C).second;
4180
4181 case CXCursor_TypeRef:
4182 return getCursorTypeRef(C).second;
4183
4184 case CXCursor_TemplateRef:
4185 return getCursorTemplateRef(C).second;
4186
4187 case CXCursor_NamespaceRef:
4188 return getCursorNamespaceRef(C).second;
4189
4190 case CXCursor_MemberRef:
4191 return getCursorMemberRef(C).second;
4192
4193 case CXCursor_CXXBaseSpecifier:
4194 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4195
4196 case CXCursor_LabelRef:
4197 return getCursorLabelRef(C).second;
4198
4199 case CXCursor_OverloadedDeclRef:
4200 return getCursorOverloadedDeclRef(C).second;
4201
4202 case CXCursor_VariableRef:
4203 return getCursorVariableRef(C).second;
4204
4205 default:
4206 // FIXME: Need a way to enumerate all non-reference cases.
4207 llvm_unreachable("Missed a reference kind");
4208 }
4209 }
4210
4211 if (clang_isExpression(C.kind))
4212 return getCursorExpr(C)->getSourceRange();
4213
4214 if (clang_isStatement(C.kind))
4215 return getCursorStmt(C)->getSourceRange();
4216
4217 if (clang_isAttribute(C.kind))
4218 return getCursorAttr(C)->getRange();
4219
4220 if (C.kind == CXCursor_PreprocessingDirective)
4221 return cxcursor::getCursorPreprocessingDirective(C);
4222
4223 if (C.kind == CXCursor_MacroExpansion) {
4224 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004225 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004226 return TU->mapRangeFromPreamble(Range);
4227 }
4228
4229 if (C.kind == CXCursor_MacroDefinition) {
4230 ASTUnit *TU = getCursorASTUnit(C);
4231 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4232 return TU->mapRangeFromPreamble(Range);
4233 }
4234
4235 if (C.kind == CXCursor_InclusionDirective) {
4236 ASTUnit *TU = getCursorASTUnit(C);
4237 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4238 return TU->mapRangeFromPreamble(Range);
4239 }
4240
4241 if (C.kind == CXCursor_TranslationUnit) {
4242 ASTUnit *TU = getCursorASTUnit(C);
4243 FileID MainID = TU->getSourceManager().getMainFileID();
4244 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4245 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4246 return SourceRange(Start, End);
4247 }
4248
4249 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004250 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004251 if (!D)
4252 return SourceRange();
4253
4254 SourceRange R = D->getSourceRange();
4255 // FIXME: Multiple variables declared in a single declaration
4256 // currently lack the information needed to correctly determine their
4257 // ranges when accounting for the type-specifier. We use context
4258 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4259 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004260 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004261 if (!cxcursor::isFirstInDeclGroup(C))
4262 R.setBegin(VD->getLocation());
4263 }
4264 return R;
4265 }
4266 return SourceRange();
4267}
4268
4269/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4270/// the decl-specifier-seq for declarations.
4271static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4272 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004273 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004274 if (!D)
4275 return SourceRange();
4276
4277 SourceRange R = D->getSourceRange();
4278
4279 // Adjust the start of the location for declarations preceded by
4280 // declaration specifiers.
4281 SourceLocation StartLoc;
4282 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4283 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4284 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004285 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004286 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4287 StartLoc = TI->getTypeLoc().getLocStart();
4288 }
4289
4290 if (StartLoc.isValid() && R.getBegin().isValid() &&
4291 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4292 R.setBegin(StartLoc);
4293
4294 // FIXME: Multiple variables declared in a single declaration
4295 // currently lack the information needed to correctly determine their
4296 // ranges when accounting for the type-specifier. We use context
4297 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4298 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004299 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004300 if (!cxcursor::isFirstInDeclGroup(C))
4301 R.setBegin(VD->getLocation());
4302 }
4303
4304 return R;
4305 }
4306
4307 return getRawCursorExtent(C);
4308}
4309
4310extern "C" {
4311
4312CXSourceRange clang_getCursorExtent(CXCursor C) {
4313 SourceRange R = getRawCursorExtent(C);
4314 if (R.isInvalid())
4315 return clang_getNullRange();
4316
4317 return cxloc::translateSourceRange(getCursorContext(C), R);
4318}
4319
4320CXCursor clang_getCursorReferenced(CXCursor C) {
4321 if (clang_isInvalid(C.kind))
4322 return clang_getNullCursor();
4323
4324 CXTranslationUnit tu = getCursorTU(C);
4325 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004326 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004327 if (!D)
4328 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004329 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004330 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004331 if (const ObjCPropertyImplDecl *PropImpl =
4332 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004333 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4334 return MakeCXCursor(Property, tu);
4335
4336 return C;
4337 }
4338
4339 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004340 const Expr *E = getCursorExpr(C);
4341 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004342 if (D) {
4343 CXCursor declCursor = MakeCXCursor(D, tu);
4344 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4345 declCursor);
4346 return declCursor;
4347 }
4348
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004349 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004350 return MakeCursorOverloadedDeclRef(Ovl, tu);
4351
4352 return clang_getNullCursor();
4353 }
4354
4355 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004356 const Stmt *S = getCursorStmt(C);
4357 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004358 if (LabelDecl *label = Goto->getLabel())
4359 if (LabelStmt *labelS = label->getStmt())
4360 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4361
4362 return clang_getNullCursor();
4363 }
4364
4365 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004366 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004367 return MakeMacroDefinitionCursor(Def, tu);
4368 }
4369
4370 if (!clang_isReference(C.kind))
4371 return clang_getNullCursor();
4372
4373 switch (C.kind) {
4374 case CXCursor_ObjCSuperClassRef:
4375 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4376
4377 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004378 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4379 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004380 return MakeCXCursor(Def, tu);
4381
4382 return MakeCXCursor(Prot, tu);
4383 }
4384
4385 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004386 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4387 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004388 return MakeCXCursor(Def, tu);
4389
4390 return MakeCXCursor(Class, tu);
4391 }
4392
4393 case CXCursor_TypeRef:
4394 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4395
4396 case CXCursor_TemplateRef:
4397 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4398
4399 case CXCursor_NamespaceRef:
4400 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4401
4402 case CXCursor_MemberRef:
4403 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4404
4405 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004406 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004407 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4408 tu ));
4409 }
4410
4411 case CXCursor_LabelRef:
4412 // FIXME: We end up faking the "parent" declaration here because we
4413 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004414 return MakeCXCursor(getCursorLabelRef(C).first,
4415 cxtu::getASTUnit(tu)->getASTContext()
4416 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004417 tu);
4418
4419 case CXCursor_OverloadedDeclRef:
4420 return C;
4421
4422 case CXCursor_VariableRef:
4423 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4424
4425 default:
4426 // We would prefer to enumerate all non-reference cursor kinds here.
4427 llvm_unreachable("Unhandled reference cursor kind");
4428 }
4429}
4430
4431CXCursor clang_getCursorDefinition(CXCursor C) {
4432 if (clang_isInvalid(C.kind))
4433 return clang_getNullCursor();
4434
4435 CXTranslationUnit TU = getCursorTU(C);
4436
4437 bool WasReference = false;
4438 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4439 C = clang_getCursorReferenced(C);
4440 WasReference = true;
4441 }
4442
4443 if (C.kind == CXCursor_MacroExpansion)
4444 return clang_getCursorReferenced(C);
4445
4446 if (!clang_isDeclaration(C.kind))
4447 return clang_getNullCursor();
4448
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004449 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004450 if (!D)
4451 return clang_getNullCursor();
4452
4453 switch (D->getKind()) {
4454 // Declaration kinds that don't really separate the notions of
4455 // declaration and definition.
4456 case Decl::Namespace:
4457 case Decl::Typedef:
4458 case Decl::TypeAlias:
4459 case Decl::TypeAliasTemplate:
4460 case Decl::TemplateTypeParm:
4461 case Decl::EnumConstant:
4462 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004463 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004464 case Decl::IndirectField:
4465 case Decl::ObjCIvar:
4466 case Decl::ObjCAtDefsField:
4467 case Decl::ImplicitParam:
4468 case Decl::ParmVar:
4469 case Decl::NonTypeTemplateParm:
4470 case Decl::TemplateTemplateParm:
4471 case Decl::ObjCCategoryImpl:
4472 case Decl::ObjCImplementation:
4473 case Decl::AccessSpec:
4474 case Decl::LinkageSpec:
4475 case Decl::ObjCPropertyImpl:
4476 case Decl::FileScopeAsm:
4477 case Decl::StaticAssert:
4478 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004479 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004480 case Decl::Label: // FIXME: Is this right??
4481 case Decl::ClassScopeFunctionSpecialization:
4482 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004483 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004484 return C;
4485
4486 // Declaration kinds that don't make any sense here, but are
4487 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004488 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004489 case Decl::TranslationUnit:
4490 break;
4491
4492 // Declaration kinds for which the definition is not resolvable.
4493 case Decl::UnresolvedUsingTypename:
4494 case Decl::UnresolvedUsingValue:
4495 break;
4496
4497 case Decl::UsingDirective:
4498 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4499 TU);
4500
4501 case Decl::NamespaceAlias:
4502 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4503
4504 case Decl::Enum:
4505 case Decl::Record:
4506 case Decl::CXXRecord:
4507 case Decl::ClassTemplateSpecialization:
4508 case Decl::ClassTemplatePartialSpecialization:
4509 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4510 return MakeCXCursor(Def, TU);
4511 return clang_getNullCursor();
4512
4513 case Decl::Function:
4514 case Decl::CXXMethod:
4515 case Decl::CXXConstructor:
4516 case Decl::CXXDestructor:
4517 case Decl::CXXConversion: {
4518 const FunctionDecl *Def = 0;
4519 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004520 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004521 return clang_getNullCursor();
4522 }
4523
4524 case Decl::Var: {
4525 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004526 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004527 return MakeCXCursor(Def, TU);
4528 return clang_getNullCursor();
4529 }
4530
4531 case Decl::FunctionTemplate: {
4532 const FunctionDecl *Def = 0;
4533 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4534 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4535 return clang_getNullCursor();
4536 }
4537
4538 case Decl::ClassTemplate: {
4539 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4540 ->getDefinition())
4541 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4542 TU);
4543 return clang_getNullCursor();
4544 }
4545
4546 case Decl::Using:
4547 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4548 D->getLocation(), TU);
4549
4550 case Decl::UsingShadow:
4551 return clang_getCursorDefinition(
4552 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4553 TU));
4554
4555 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004556 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004557 if (Method->isThisDeclarationADefinition())
4558 return C;
4559
4560 // Dig out the method definition in the associated
4561 // @implementation, if we have it.
4562 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004563 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004564 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4565 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4566 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4567 Method->isInstanceMethod()))
4568 if (Def->isThisDeclarationADefinition())
4569 return MakeCXCursor(Def, TU);
4570
4571 return clang_getNullCursor();
4572 }
4573
4574 case Decl::ObjCCategory:
4575 if (ObjCCategoryImplDecl *Impl
4576 = cast<ObjCCategoryDecl>(D)->getImplementation())
4577 return MakeCXCursor(Impl, TU);
4578 return clang_getNullCursor();
4579
4580 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004581 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004582 return MakeCXCursor(Def, TU);
4583 return clang_getNullCursor();
4584
4585 case Decl::ObjCInterface: {
4586 // There are two notions of a "definition" for an Objective-C
4587 // class: the interface and its implementation. When we resolved a
4588 // reference to an Objective-C class, produce the @interface as
4589 // the definition; when we were provided with the interface,
4590 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004591 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004592 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004593 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004594 return MakeCXCursor(Def, TU);
4595 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4596 return MakeCXCursor(Impl, TU);
4597 return clang_getNullCursor();
4598 }
4599
4600 case Decl::ObjCProperty:
4601 // FIXME: We don't really know where to find the
4602 // ObjCPropertyImplDecls that implement this property.
4603 return clang_getNullCursor();
4604
4605 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004606 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004607 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004608 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004609 return MakeCXCursor(Def, TU);
4610
4611 return clang_getNullCursor();
4612
4613 case Decl::Friend:
4614 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4615 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4616 return clang_getNullCursor();
4617
4618 case Decl::FriendTemplate:
4619 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4620 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4621 return clang_getNullCursor();
4622 }
4623
4624 return clang_getNullCursor();
4625}
4626
4627unsigned clang_isCursorDefinition(CXCursor C) {
4628 if (!clang_isDeclaration(C.kind))
4629 return 0;
4630
4631 return clang_getCursorDefinition(C) == C;
4632}
4633
4634CXCursor clang_getCanonicalCursor(CXCursor C) {
4635 if (!clang_isDeclaration(C.kind))
4636 return C;
4637
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004638 if (const Decl *D = getCursorDecl(C)) {
4639 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004640 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4641 return MakeCXCursor(CatD, getCursorTU(C));
4642
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004643 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4644 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004645 return MakeCXCursor(IFD, getCursorTU(C));
4646
4647 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4648 }
4649
4650 return C;
4651}
4652
4653int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4654 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4655}
4656
4657unsigned clang_getNumOverloadedDecls(CXCursor C) {
4658 if (C.kind != CXCursor_OverloadedDeclRef)
4659 return 0;
4660
4661 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004662 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004663 return E->getNumDecls();
4664
4665 if (OverloadedTemplateStorage *S
4666 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4667 return S->size();
4668
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004669 const Decl *D = Storage.get<const Decl *>();
4670 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004671 return Using->shadow_size();
4672
4673 return 0;
4674}
4675
4676CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4677 if (cursor.kind != CXCursor_OverloadedDeclRef)
4678 return clang_getNullCursor();
4679
4680 if (index >= clang_getNumOverloadedDecls(cursor))
4681 return clang_getNullCursor();
4682
4683 CXTranslationUnit TU = getCursorTU(cursor);
4684 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004685 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004686 return MakeCXCursor(E->decls_begin()[index], TU);
4687
4688 if (OverloadedTemplateStorage *S
4689 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4690 return MakeCXCursor(S->begin()[index], TU);
4691
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004692 const Decl *D = Storage.get<const Decl *>();
4693 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004694 // FIXME: This is, unfortunately, linear time.
4695 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4696 std::advance(Pos, index);
4697 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4698 }
4699
4700 return clang_getNullCursor();
4701}
4702
4703void clang_getDefinitionSpellingAndExtent(CXCursor C,
4704 const char **startBuf,
4705 const char **endBuf,
4706 unsigned *startLine,
4707 unsigned *startColumn,
4708 unsigned *endLine,
4709 unsigned *endColumn) {
4710 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004711 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004712 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4713
4714 SourceManager &SM = FD->getASTContext().getSourceManager();
4715 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4716 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4717 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4718 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4719 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4720 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4721}
4722
4723
4724CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4725 unsigned PieceIndex) {
4726 RefNamePieces Pieces;
4727
4728 switch (C.kind) {
4729 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004730 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004731 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4732 E->getQualifierLoc().getSourceRange());
4733 break;
4734
4735 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004736 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004737 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4738 E->getQualifierLoc().getSourceRange(),
4739 E->getOptionalExplicitTemplateArgs());
4740 break;
4741
4742 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004743 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004744 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004745 const Expr *Callee = OCE->getCallee();
4746 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004747 Callee = ICE->getSubExpr();
4748
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004749 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004750 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4751 DRE->getQualifierLoc().getSourceRange());
4752 }
4753 break;
4754
4755 default:
4756 break;
4757 }
4758
4759 if (Pieces.empty()) {
4760 if (PieceIndex == 0)
4761 return clang_getCursorExtent(C);
4762 } else if (PieceIndex < Pieces.size()) {
4763 SourceRange R = Pieces[PieceIndex];
4764 if (R.isValid())
4765 return cxloc::translateSourceRange(getCursorContext(C), R);
4766 }
4767
4768 return clang_getNullRange();
4769}
4770
4771void clang_enableStackTraces(void) {
4772 llvm::sys::PrintStackTraceOnErrorSignal();
4773}
4774
4775void clang_executeOnThread(void (*fn)(void*), void *user_data,
4776 unsigned stack_size) {
4777 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4778}
4779
4780} // end: extern "C"
4781
4782//===----------------------------------------------------------------------===//
4783// Token-based Operations.
4784//===----------------------------------------------------------------------===//
4785
4786/* CXToken layout:
4787 * int_data[0]: a CXTokenKind
4788 * int_data[1]: starting token location
4789 * int_data[2]: token length
4790 * int_data[3]: reserved
4791 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4792 * otherwise unused.
4793 */
4794extern "C" {
4795
4796CXTokenKind clang_getTokenKind(CXToken CXTok) {
4797 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4798}
4799
4800CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4801 switch (clang_getTokenKind(CXTok)) {
4802 case CXToken_Identifier:
4803 case CXToken_Keyword:
4804 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004805 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004806 ->getNameStart());
4807
4808 case CXToken_Literal: {
4809 // We have stashed the starting pointer in the ptr_data field. Use it.
4810 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004811 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004812 }
4813
4814 case CXToken_Punctuation:
4815 case CXToken_Comment:
4816 break;
4817 }
4818
4819 // We have to find the starting buffer pointer the hard way, by
4820 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004821 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004822 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004823 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004824
4825 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4826 std::pair<FileID, unsigned> LocInfo
4827 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4828 bool Invalid = false;
4829 StringRef Buffer
4830 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4831 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004832 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004833
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004834 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004835}
4836
4837CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004838 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004839 if (!CXXUnit)
4840 return clang_getNullLocation();
4841
4842 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4843 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4844}
4845
4846CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004847 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004848 if (!CXXUnit)
4849 return clang_getNullRange();
4850
4851 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4852 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4853}
4854
4855static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4856 SmallVectorImpl<CXToken> &CXTokens) {
4857 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4858 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004859 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004860 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004861 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004862
4863 // Cannot tokenize across files.
4864 if (BeginLocInfo.first != EndLocInfo.first)
4865 return;
4866
4867 // Create a lexer
4868 bool Invalid = false;
4869 StringRef Buffer
4870 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4871 if (Invalid)
4872 return;
4873
4874 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4875 CXXUnit->getASTContext().getLangOpts(),
4876 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4877 Lex.SetCommentRetentionState(true);
4878
4879 // Lex tokens until we hit the end of the range.
4880 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4881 Token Tok;
4882 bool previousWasAt = false;
4883 do {
4884 // Lex the next token
4885 Lex.LexFromRawLexer(Tok);
4886 if (Tok.is(tok::eof))
4887 break;
4888
4889 // Initialize the CXToken.
4890 CXToken CXTok;
4891
4892 // - Common fields
4893 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4894 CXTok.int_data[2] = Tok.getLength();
4895 CXTok.int_data[3] = 0;
4896
4897 // - Kind-specific fields
4898 if (Tok.isLiteral()) {
4899 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004900 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004901 } else if (Tok.is(tok::raw_identifier)) {
4902 // Lookup the identifier to determine whether we have a keyword.
4903 IdentifierInfo *II
4904 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4905
4906 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4907 CXTok.int_data[0] = CXToken_Keyword;
4908 }
4909 else {
4910 CXTok.int_data[0] = Tok.is(tok::identifier)
4911 ? CXToken_Identifier
4912 : CXToken_Keyword;
4913 }
4914 CXTok.ptr_data = II;
4915 } else if (Tok.is(tok::comment)) {
4916 CXTok.int_data[0] = CXToken_Comment;
4917 CXTok.ptr_data = 0;
4918 } else {
4919 CXTok.int_data[0] = CXToken_Punctuation;
4920 CXTok.ptr_data = 0;
4921 }
4922 CXTokens.push_back(CXTok);
4923 previousWasAt = Tok.is(tok::at);
4924 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4925}
4926
4927void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4928 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004929 LOG_FUNC_SECTION {
4930 *Log << TU << ' ' << Range;
4931 }
4932
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004933 if (Tokens)
4934 *Tokens = 0;
4935 if (NumTokens)
4936 *NumTokens = 0;
4937
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004938 if (!TU)
4939 return;
4940
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004941 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004942 if (!CXXUnit || !Tokens || !NumTokens)
4943 return;
4944
4945 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4946
4947 SourceRange R = cxloc::translateCXSourceRange(Range);
4948 if (R.isInvalid())
4949 return;
4950
4951 SmallVector<CXToken, 32> CXTokens;
4952 getTokens(CXXUnit, R, CXTokens);
4953
4954 if (CXTokens.empty())
4955 return;
4956
4957 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4958 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4959 *NumTokens = CXTokens.size();
4960}
4961
4962void clang_disposeTokens(CXTranslationUnit TU,
4963 CXToken *Tokens, unsigned NumTokens) {
4964 free(Tokens);
4965}
4966
4967} // end: extern "C"
4968
4969//===----------------------------------------------------------------------===//
4970// Token annotation APIs.
4971//===----------------------------------------------------------------------===//
4972
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004973static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4974 CXCursor parent,
4975 CXClientData client_data);
4976static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4977 CXClientData client_data);
4978
4979namespace {
4980class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004981 CXToken *Tokens;
4982 CXCursor *Cursors;
4983 unsigned NumTokens;
4984 unsigned TokIdx;
4985 unsigned PreprocessingTokIdx;
4986 CursorVisitor AnnotateVis;
4987 SourceManager &SrcMgr;
4988 bool HasContextSensitiveKeywords;
4989
4990 struct PostChildrenInfo {
4991 CXCursor Cursor;
4992 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004993 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004994 unsigned BeforeChildrenTokenIdx;
4995 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004996 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004997
4998 bool MoreTokens() const { return TokIdx < NumTokens; }
4999 unsigned NextToken() const { return TokIdx; }
5000 void AdvanceToken() { ++TokIdx; }
5001 SourceLocation GetTokenLoc(unsigned tokI) {
5002 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5003 }
5004 bool isFunctionMacroToken(unsigned tokI) const {
5005 return Tokens[tokI].int_data[3] != 0;
5006 }
5007 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5008 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5009 }
5010
5011 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005012 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005013 SourceRange);
5014
5015public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005016 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005017 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005018 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005019 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005020 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005021 AnnotateTokensVisitor, this,
5022 /*VisitPreprocessorLast=*/true,
5023 /*VisitIncludedEntities=*/false,
5024 RegionOfInterest,
5025 /*VisitDeclsOnly=*/false,
5026 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005027 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005028 HasContextSensitiveKeywords(false) { }
5029
5030 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5031 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5032 bool postVisitChildren(CXCursor cursor);
5033 void AnnotateTokens();
5034
5035 /// \brief Determine whether the annotator saw any cursors that have
5036 /// context-sensitive keywords.
5037 bool hasContextSensitiveKeywords() const {
5038 return HasContextSensitiveKeywords;
5039 }
5040
5041 ~AnnotateTokensWorker() {
5042 assert(PostChildrenInfos.empty());
5043 }
5044};
5045}
5046
5047void AnnotateTokensWorker::AnnotateTokens() {
5048 // Walk the AST within the region of interest, annotating tokens
5049 // along the way.
5050 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005051}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005052
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005053static inline void updateCursorAnnotation(CXCursor &Cursor,
5054 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005055 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005056 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005057 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005058}
5059
5060/// \brief It annotates and advances tokens with a cursor until the comparison
5061//// between the cursor location and the source range is the same as
5062/// \arg compResult.
5063///
5064/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5065/// Pass RangeOverlap to annotate tokens inside a range.
5066void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5067 RangeComparisonResult compResult,
5068 SourceRange range) {
5069 while (MoreTokens()) {
5070 const unsigned I = NextToken();
5071 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005072 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5073 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005074
5075 SourceLocation TokLoc = GetTokenLoc(I);
5076 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005077 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005078 AdvanceToken();
5079 continue;
5080 }
5081 break;
5082 }
5083}
5084
5085/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005086/// \returns true if it advanced beyond all macro tokens, false otherwise.
5087bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005088 CXCursor updateC,
5089 RangeComparisonResult compResult,
5090 SourceRange range) {
5091 assert(MoreTokens());
5092 assert(isFunctionMacroToken(NextToken()) &&
5093 "Should be called only for macro arg tokens");
5094
5095 // This works differently than annotateAndAdvanceTokens; because expanded
5096 // macro arguments can have arbitrary translation-unit source order, we do not
5097 // advance the token index one by one until a token fails the range test.
5098 // We only advance once past all of the macro arg tokens if all of them
5099 // pass the range test. If one of them fails we keep the token index pointing
5100 // at the start of the macro arg tokens so that the failing token will be
5101 // annotated by a subsequent annotation try.
5102
5103 bool atLeastOneCompFail = false;
5104
5105 unsigned I = NextToken();
5106 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5107 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5108 if (TokLoc.isFileID())
5109 continue; // not macro arg token, it's parens or comma.
5110 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5111 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5112 Cursors[I] = updateC;
5113 } else
5114 atLeastOneCompFail = true;
5115 }
5116
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005117 if (atLeastOneCompFail)
5118 return false;
5119
5120 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5121 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005122}
5123
5124enum CXChildVisitResult
5125AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005126 SourceRange cursorRange = getRawCursorExtent(cursor);
5127 if (cursorRange.isInvalid())
5128 return CXChildVisit_Recurse;
5129
5130 if (!HasContextSensitiveKeywords) {
5131 // Objective-C properties can have context-sensitive keywords.
5132 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005133 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005134 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5135 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5136 }
5137 // Objective-C methods can have context-sensitive keywords.
5138 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5139 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005140 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005141 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5142 if (Method->getObjCDeclQualifier())
5143 HasContextSensitiveKeywords = true;
5144 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005145 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5146 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005147 P != PEnd; ++P) {
5148 if ((*P)->getObjCDeclQualifier()) {
5149 HasContextSensitiveKeywords = true;
5150 break;
5151 }
5152 }
5153 }
5154 }
5155 }
5156 // C++ methods can have context-sensitive keywords.
5157 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005158 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005159 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5160 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5161 HasContextSensitiveKeywords = true;
5162 }
5163 }
5164 // C++ classes can have context-sensitive keywords.
5165 else if (cursor.kind == CXCursor_StructDecl ||
5166 cursor.kind == CXCursor_ClassDecl ||
5167 cursor.kind == CXCursor_ClassTemplate ||
5168 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005169 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005170 if (D->hasAttr<FinalAttr>())
5171 HasContextSensitiveKeywords = true;
5172 }
5173 }
5174
5175 if (clang_isPreprocessing(cursor.kind)) {
5176 // Items in the preprocessing record are kept separate from items in
5177 // declarations, so we keep a separate token index.
5178 unsigned SavedTokIdx = TokIdx;
5179 TokIdx = PreprocessingTokIdx;
5180
5181 // Skip tokens up until we catch up to the beginning of the preprocessing
5182 // entry.
5183 while (MoreTokens()) {
5184 const unsigned I = NextToken();
5185 SourceLocation TokLoc = GetTokenLoc(I);
5186 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5187 case RangeBefore:
5188 AdvanceToken();
5189 continue;
5190 case RangeAfter:
5191 case RangeOverlap:
5192 break;
5193 }
5194 break;
5195 }
5196
5197 // Look at all of the tokens within this range.
5198 while (MoreTokens()) {
5199 const unsigned I = NextToken();
5200 SourceLocation TokLoc = GetTokenLoc(I);
5201 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5202 case RangeBefore:
5203 llvm_unreachable("Infeasible");
5204 case RangeAfter:
5205 break;
5206 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005207 // For macro expansions, just note where the beginning of the macro
5208 // expansion occurs.
5209 if (cursor.kind == CXCursor_MacroExpansion) {
5210 if (TokLoc == cursorRange.getBegin())
5211 Cursors[I] = cursor;
5212 AdvanceToken();
5213 break;
5214 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005215 // We may have already annotated macro names inside macro definitions.
5216 if (Cursors[I].kind != CXCursor_MacroExpansion)
5217 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005218 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005219 continue;
5220 }
5221 break;
5222 }
5223
5224 // Save the preprocessing token index; restore the non-preprocessing
5225 // token index.
5226 PreprocessingTokIdx = TokIdx;
5227 TokIdx = SavedTokIdx;
5228 return CXChildVisit_Recurse;
5229 }
5230
5231 if (cursorRange.isInvalid())
5232 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005233
5234 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005235 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005236 const enum CXCursorKind K = clang_getCursorKind(parent);
5237 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005238 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5239 // Attributes are annotated out-of-order, skip tokens until we reach it.
5240 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005241 ? clang_getNullCursor() : parent;
5242
5243 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5244
5245 // Avoid having the cursor of an expression "overwrite" the annotation of the
5246 // variable declaration that it belongs to.
5247 // This can happen for C++ constructor expressions whose range generally
5248 // include the variable declaration, e.g.:
5249 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5250 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005251 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005252 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005253 const unsigned I = NextToken();
5254 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5255 E->getLocStart() == D->getLocation() &&
5256 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005257 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005258 AdvanceToken();
5259 }
5260 }
5261 }
5262
5263 // Before recursing into the children keep some state that we are going
5264 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5265 // extra work after the child nodes are visited.
5266 // Note that we don't call VisitChildren here to avoid traversing statements
5267 // code-recursively which can blow the stack.
5268
5269 PostChildrenInfo Info;
5270 Info.Cursor = cursor;
5271 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005272 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005273 Info.BeforeChildrenTokenIdx = NextToken();
5274 PostChildrenInfos.push_back(Info);
5275
5276 return CXChildVisit_Recurse;
5277}
5278
5279bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5280 if (PostChildrenInfos.empty())
5281 return false;
5282 const PostChildrenInfo &Info = PostChildrenInfos.back();
5283 if (!clang_equalCursors(Info.Cursor, cursor))
5284 return false;
5285
5286 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5287 const unsigned AfterChildren = NextToken();
5288 SourceRange cursorRange = Info.CursorRange;
5289
5290 // Scan the tokens that are at the end of the cursor, but are not captured
5291 // but the child cursors.
5292 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5293
5294 // Scan the tokens that are at the beginning of the cursor, but are not
5295 // capture by the child cursors.
5296 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5297 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5298 break;
5299
5300 Cursors[I] = cursor;
5301 }
5302
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005303 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5304 // encountered the attribute cursor.
5305 if (clang_isAttribute(cursor.kind))
5306 TokIdx = Info.BeforeReachingCursorIdx;
5307
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005308 PostChildrenInfos.pop_back();
5309 return false;
5310}
5311
5312static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5313 CXCursor parent,
5314 CXClientData client_data) {
5315 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5316}
5317
5318static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5319 CXClientData client_data) {
5320 return static_cast<AnnotateTokensWorker*>(client_data)->
5321 postVisitChildren(cursor);
5322}
5323
5324namespace {
5325
5326/// \brief Uses the macro expansions in the preprocessing record to find
5327/// and mark tokens that are macro arguments. This info is used by the
5328/// AnnotateTokensWorker.
5329class MarkMacroArgTokensVisitor {
5330 SourceManager &SM;
5331 CXToken *Tokens;
5332 unsigned NumTokens;
5333 unsigned CurIdx;
5334
5335public:
5336 MarkMacroArgTokensVisitor(SourceManager &SM,
5337 CXToken *tokens, unsigned numTokens)
5338 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5339
5340 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5341 if (cursor.kind != CXCursor_MacroExpansion)
5342 return CXChildVisit_Continue;
5343
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005344 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005345 if (macroRange.getBegin() == macroRange.getEnd())
5346 return CXChildVisit_Continue; // it's not a function macro.
5347
5348 for (; CurIdx < NumTokens; ++CurIdx) {
5349 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5350 macroRange.getBegin()))
5351 break;
5352 }
5353
5354 if (CurIdx == NumTokens)
5355 return CXChildVisit_Break;
5356
5357 for (; CurIdx < NumTokens; ++CurIdx) {
5358 SourceLocation tokLoc = getTokenLoc(CurIdx);
5359 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5360 break;
5361
5362 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5363 }
5364
5365 if (CurIdx == NumTokens)
5366 return CXChildVisit_Break;
5367
5368 return CXChildVisit_Continue;
5369 }
5370
5371private:
5372 SourceLocation getTokenLoc(unsigned tokI) {
5373 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5374 }
5375
5376 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5377 // The third field is reserved and currently not used. Use it here
5378 // to mark macro arg expanded tokens with their expanded locations.
5379 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5380 }
5381};
5382
5383} // end anonymous namespace
5384
5385static CXChildVisitResult
5386MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5387 CXClientData client_data) {
5388 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5389 parent);
5390}
5391
5392namespace {
5393 struct clang_annotateTokens_Data {
5394 CXTranslationUnit TU;
5395 ASTUnit *CXXUnit;
5396 CXToken *Tokens;
5397 unsigned NumTokens;
5398 CXCursor *Cursors;
5399 };
5400}
5401
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005402/// \brief Used by \c annotatePreprocessorTokens.
5403/// \returns true if lexing was finished, false otherwise.
5404static bool lexNext(Lexer &Lex, Token &Tok,
5405 unsigned &NextIdx, unsigned NumTokens) {
5406 if (NextIdx >= NumTokens)
5407 return true;
5408
5409 ++NextIdx;
5410 Lex.LexFromRawLexer(Tok);
5411 if (Tok.is(tok::eof))
5412 return true;
5413
5414 return false;
5415}
5416
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005417static void annotatePreprocessorTokens(CXTranslationUnit TU,
5418 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005419 CXCursor *Cursors,
5420 CXToken *Tokens,
5421 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005422 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005423
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005424 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005425 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5426 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005427 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005428 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005429 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005430
5431 if (BeginLocInfo.first != EndLocInfo.first)
5432 return;
5433
5434 StringRef Buffer;
5435 bool Invalid = false;
5436 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5437 if (Buffer.empty() || Invalid)
5438 return;
5439
5440 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5441 CXXUnit->getASTContext().getLangOpts(),
5442 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5443 Buffer.end());
5444 Lex.SetCommentRetentionState(true);
5445
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005446 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005447 // Lex tokens in raw mode until we hit the end of the range, to avoid
5448 // entering #includes or expanding macros.
5449 while (true) {
5450 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005451 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5452 break;
5453 unsigned TokIdx = NextIdx-1;
5454 assert(Tok.getLocation() ==
5455 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005456
5457 reprocess:
5458 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005459 // We have found a preprocessing directive. Annotate the tokens
5460 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005461 //
5462 // FIXME: Some simple tests here could identify macro definitions and
5463 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005464
5465 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005466 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5467 break;
5468
5469 MacroInfo *MI = 0;
5470 if (Tok.is(tok::raw_identifier) &&
5471 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5472 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5473 break;
5474
5475 if (Tok.is(tok::raw_identifier)) {
5476 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5477 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5478 SourceLocation MappedTokLoc =
5479 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5480 MI = getMacroInfo(II, MappedTokLoc, TU);
5481 }
5482 }
5483
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005484 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005485 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005486 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5487 finished = true;
5488 break;
5489 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005490 // If we are in a macro definition, check if the token was ever a
5491 // macro name and annotate it if that's the case.
5492 if (MI) {
5493 SourceLocation SaveLoc = Tok.getLocation();
5494 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5495 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5496 Tok.setLocation(SaveLoc);
5497 if (MacroDef)
5498 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5499 Tok.getLocation(), TU);
5500 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005501 } while (!Tok.isAtStartOfLine());
5502
5503 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5504 assert(TokIdx <= LastIdx);
5505 SourceLocation EndLoc =
5506 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5507 CXCursor Cursor =
5508 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5509
5510 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005511 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005512
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005513 if (finished)
5514 break;
5515 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005516 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005517 }
5518}
5519
5520// This gets run a separate thread to avoid stack blowout.
5521static void clang_annotateTokensImpl(void *UserData) {
5522 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5523 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5524 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5525 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5526 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5527
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005528 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005529 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5530 setThreadBackgroundPriority();
5531
5532 // Determine the region of interest, which contains all of the tokens.
5533 SourceRange RegionOfInterest;
5534 RegionOfInterest.setBegin(
5535 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5536 RegionOfInterest.setEnd(
5537 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5538 Tokens[NumTokens-1])));
5539
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005540 // Relex the tokens within the source range to look for preprocessing
5541 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005542 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005543
5544 // If begin location points inside a macro argument, set it to the expansion
5545 // location so we can have the full context when annotating semantically.
5546 {
5547 SourceManager &SM = CXXUnit->getSourceManager();
5548 SourceLocation Loc =
5549 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5550 if (Loc.isMacroID())
5551 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5552 }
5553
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005554 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5555 // Search and mark tokens that are macro argument expansions.
5556 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5557 Tokens, NumTokens);
5558 CursorVisitor MacroArgMarker(TU,
5559 MarkMacroArgTokensVisitorDelegate, &Visitor,
5560 /*VisitPreprocessorLast=*/true,
5561 /*VisitIncludedEntities=*/false,
5562 RegionOfInterest);
5563 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5564 }
5565
5566 // Annotate all of the source locations in the region of interest that map to
5567 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005568 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005569
5570 // FIXME: We use a ridiculous stack size here because the data-recursion
5571 // algorithm uses a large stack frame than the non-data recursive version,
5572 // and AnnotationTokensWorker currently transforms the data-recursion
5573 // algorithm back into a traditional recursion by explicitly calling
5574 // VisitChildren(). We will need to remove this explicit recursive call.
5575 W.AnnotateTokens();
5576
5577 // If we ran into any entities that involve context-sensitive keywords,
5578 // take another pass through the tokens to mark them as such.
5579 if (W.hasContextSensitiveKeywords()) {
5580 for (unsigned I = 0; I != NumTokens; ++I) {
5581 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5582 continue;
5583
5584 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5585 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005586 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005587 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5588 if (Property->getPropertyAttributesAsWritten() != 0 &&
5589 llvm::StringSwitch<bool>(II->getName())
5590 .Case("readonly", true)
5591 .Case("assign", true)
5592 .Case("unsafe_unretained", true)
5593 .Case("readwrite", true)
5594 .Case("retain", true)
5595 .Case("copy", true)
5596 .Case("nonatomic", true)
5597 .Case("atomic", true)
5598 .Case("getter", true)
5599 .Case("setter", true)
5600 .Case("strong", true)
5601 .Case("weak", true)
5602 .Default(false))
5603 Tokens[I].int_data[0] = CXToken_Keyword;
5604 }
5605 continue;
5606 }
5607
5608 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5609 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5610 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5611 if (llvm::StringSwitch<bool>(II->getName())
5612 .Case("in", true)
5613 .Case("out", true)
5614 .Case("inout", true)
5615 .Case("oneway", true)
5616 .Case("bycopy", true)
5617 .Case("byref", true)
5618 .Default(false))
5619 Tokens[I].int_data[0] = CXToken_Keyword;
5620 continue;
5621 }
5622
5623 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5624 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5625 Tokens[I].int_data[0] = CXToken_Keyword;
5626 continue;
5627 }
5628 }
5629 }
5630}
5631
5632extern "C" {
5633
5634void clang_annotateTokens(CXTranslationUnit TU,
5635 CXToken *Tokens, unsigned NumTokens,
5636 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005637 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005638 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005639 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005640 }
5641
5642 LOG_FUNC_SECTION {
5643 *Log << TU << ' ';
5644 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5645 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5646 *Log << clang_getRange(bloc, eloc);
5647 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005648
5649 // Any token we don't specifically annotate will have a NULL cursor.
5650 CXCursor C = clang_getNullCursor();
5651 for (unsigned I = 0; I != NumTokens; ++I)
5652 Cursors[I] = C;
5653
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005654 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005655 if (!CXXUnit)
5656 return;
5657
5658 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5659
5660 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5661 llvm::CrashRecoveryContext CRC;
5662 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5663 GetSafetyThreadStackSize() * 2)) {
5664 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5665 }
5666}
5667
5668} // end: extern "C"
5669
5670//===----------------------------------------------------------------------===//
5671// Operations for querying linkage of a cursor.
5672//===----------------------------------------------------------------------===//
5673
5674extern "C" {
5675CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5676 if (!clang_isDeclaration(cursor.kind))
5677 return CXLinkage_Invalid;
5678
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005679 const Decl *D = cxcursor::getCursorDecl(cursor);
5680 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005681 switch (ND->getLinkage()) {
5682 case NoLinkage: return CXLinkage_NoLinkage;
5683 case InternalLinkage: return CXLinkage_Internal;
5684 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5685 case ExternalLinkage: return CXLinkage_External;
5686 };
5687
5688 return CXLinkage_Invalid;
5689}
5690} // end: extern "C"
5691
5692//===----------------------------------------------------------------------===//
5693// Operations for querying language of a cursor.
5694//===----------------------------------------------------------------------===//
5695
5696static CXLanguageKind getDeclLanguage(const Decl *D) {
5697 if (!D)
5698 return CXLanguage_C;
5699
5700 switch (D->getKind()) {
5701 default:
5702 break;
5703 case Decl::ImplicitParam:
5704 case Decl::ObjCAtDefsField:
5705 case Decl::ObjCCategory:
5706 case Decl::ObjCCategoryImpl:
5707 case Decl::ObjCCompatibleAlias:
5708 case Decl::ObjCImplementation:
5709 case Decl::ObjCInterface:
5710 case Decl::ObjCIvar:
5711 case Decl::ObjCMethod:
5712 case Decl::ObjCProperty:
5713 case Decl::ObjCPropertyImpl:
5714 case Decl::ObjCProtocol:
5715 return CXLanguage_ObjC;
5716 case Decl::CXXConstructor:
5717 case Decl::CXXConversion:
5718 case Decl::CXXDestructor:
5719 case Decl::CXXMethod:
5720 case Decl::CXXRecord:
5721 case Decl::ClassTemplate:
5722 case Decl::ClassTemplatePartialSpecialization:
5723 case Decl::ClassTemplateSpecialization:
5724 case Decl::Friend:
5725 case Decl::FriendTemplate:
5726 case Decl::FunctionTemplate:
5727 case Decl::LinkageSpec:
5728 case Decl::Namespace:
5729 case Decl::NamespaceAlias:
5730 case Decl::NonTypeTemplateParm:
5731 case Decl::StaticAssert:
5732 case Decl::TemplateTemplateParm:
5733 case Decl::TemplateTypeParm:
5734 case Decl::UnresolvedUsingTypename:
5735 case Decl::UnresolvedUsingValue:
5736 case Decl::Using:
5737 case Decl::UsingDirective:
5738 case Decl::UsingShadow:
5739 return CXLanguage_CPlusPlus;
5740 }
5741
5742 return CXLanguage_C;
5743}
5744
5745extern "C" {
5746
5747enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5748 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005749 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005750 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5751 return CXAvailability_Available;
5752
5753 switch (D->getAvailability()) {
5754 case AR_Available:
5755 case AR_NotYetIntroduced:
5756 return CXAvailability_Available;
5757
5758 case AR_Deprecated:
5759 return CXAvailability_Deprecated;
5760
5761 case AR_Unavailable:
5762 return CXAvailability_NotAvailable;
5763 }
5764 }
5765
5766 return CXAvailability_Available;
5767}
5768
5769static CXVersion convertVersion(VersionTuple In) {
5770 CXVersion Out = { -1, -1, -1 };
5771 if (In.empty())
5772 return Out;
5773
5774 Out.Major = In.getMajor();
5775
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005776 Optional<unsigned> Minor = In.getMinor();
5777 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005778 Out.Minor = *Minor;
5779 else
5780 return Out;
5781
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005782 Optional<unsigned> Subminor = In.getSubminor();
5783 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005784 Out.Subminor = *Subminor;
5785
5786 return Out;
5787}
5788
5789int clang_getCursorPlatformAvailability(CXCursor cursor,
5790 int *always_deprecated,
5791 CXString *deprecated_message,
5792 int *always_unavailable,
5793 CXString *unavailable_message,
5794 CXPlatformAvailability *availability,
5795 int availability_size) {
5796 if (always_deprecated)
5797 *always_deprecated = 0;
5798 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005799 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005800 if (always_unavailable)
5801 *always_unavailable = 0;
5802 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005803 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005804
5805 if (!clang_isDeclaration(cursor.kind))
5806 return 0;
5807
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005808 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005809 if (!D)
5810 return 0;
5811
5812 int N = 0;
5813 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5814 ++A) {
5815 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5816 if (always_deprecated)
5817 *always_deprecated = 1;
5818 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005819 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005820 continue;
5821 }
5822
5823 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5824 if (always_unavailable)
5825 *always_unavailable = 1;
5826 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005827 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005828 }
5829 continue;
5830 }
5831
5832 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5833 if (N < availability_size) {
5834 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005835 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005836 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5837 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5838 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5839 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005840 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005841 }
5842 ++N;
5843 }
5844 }
5845
5846 return N;
5847}
5848
5849void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5850 clang_disposeString(availability->Platform);
5851 clang_disposeString(availability->Message);
5852}
5853
5854CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5855 if (clang_isDeclaration(cursor.kind))
5856 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5857
5858 return CXLanguage_Invalid;
5859}
5860
5861 /// \brief If the given cursor is the "templated" declaration
5862 /// descibing a class or function template, return the class or
5863 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005864static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005865 if (!D)
5866 return 0;
5867
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005868 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005869 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5870 return FunTmpl;
5871
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005872 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005873 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5874 return ClassTmpl;
5875
5876 return D;
5877}
5878
5879CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5880 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005881 if (const Decl *D = getCursorDecl(cursor)) {
5882 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005883 if (!DC)
5884 return clang_getNullCursor();
5885
5886 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5887 getCursorTU(cursor));
5888 }
5889 }
5890
5891 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005892 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005893 return MakeCXCursor(D, getCursorTU(cursor));
5894 }
5895
5896 return clang_getNullCursor();
5897}
5898
5899CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5900 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005901 if (const Decl *D = getCursorDecl(cursor)) {
5902 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005903 if (!DC)
5904 return clang_getNullCursor();
5905
5906 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5907 getCursorTU(cursor));
5908 }
5909 }
5910
5911 // FIXME: Note that we can't easily compute the lexical context of a
5912 // statement or expression, so we return nothing.
5913 return clang_getNullCursor();
5914}
5915
5916CXFile clang_getIncludedFile(CXCursor cursor) {
5917 if (cursor.kind != CXCursor_InclusionDirective)
5918 return 0;
5919
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005920 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005921 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005922}
5923
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005924unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5925 if (C.kind != CXCursor_ObjCPropertyDecl)
5926 return CXObjCPropertyAttr_noattr;
5927
5928 unsigned Result = CXObjCPropertyAttr_noattr;
5929 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
5930 ObjCPropertyDecl::PropertyAttributeKind Attr =
5931 PD->getPropertyAttributesAsWritten();
5932
5933#define SET_CXOBJCPROP_ATTR(A) \
5934 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
5935 Result |= CXObjCPropertyAttr_##A
5936 SET_CXOBJCPROP_ATTR(readonly);
5937 SET_CXOBJCPROP_ATTR(getter);
5938 SET_CXOBJCPROP_ATTR(assign);
5939 SET_CXOBJCPROP_ATTR(readwrite);
5940 SET_CXOBJCPROP_ATTR(retain);
5941 SET_CXOBJCPROP_ATTR(copy);
5942 SET_CXOBJCPROP_ATTR(nonatomic);
5943 SET_CXOBJCPROP_ATTR(setter);
5944 SET_CXOBJCPROP_ATTR(atomic);
5945 SET_CXOBJCPROP_ATTR(weak);
5946 SET_CXOBJCPROP_ATTR(strong);
5947 SET_CXOBJCPROP_ATTR(unsafe_unretained);
5948#undef SET_CXOBJCPROP_ATTR
5949
5950 return Result;
5951}
5952
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00005953unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
5954 if (!clang_isDeclaration(C.kind))
5955 return CXObjCDeclQualifier_None;
5956
5957 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
5958 const Decl *D = getCursorDecl(C);
5959 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5960 QT = MD->getObjCDeclQualifier();
5961 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
5962 QT = PD->getObjCDeclQualifier();
5963 if (QT == Decl::OBJC_TQ_None)
5964 return CXObjCDeclQualifier_None;
5965
5966 unsigned Result = CXObjCDeclQualifier_None;
5967 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
5968 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
5969 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
5970 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
5971 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
5972 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
5973
5974 return Result;
5975}
5976
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00005977unsigned clang_Cursor_isVariadic(CXCursor C) {
5978 if (!clang_isDeclaration(C.kind))
5979 return 0;
5980
5981 const Decl *D = getCursorDecl(C);
5982 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5983 return FD->isVariadic();
5984 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5985 return MD->isVariadic();
5986
5987 return 0;
5988}
5989
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005990CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5991 if (!clang_isDeclaration(C.kind))
5992 return clang_getNullRange();
5993
5994 const Decl *D = getCursorDecl(C);
5995 ASTContext &Context = getCursorContext(C);
5996 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5997 if (!RC)
5998 return clang_getNullRange();
5999
6000 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6001}
6002
6003CXString clang_Cursor_getRawCommentText(CXCursor C) {
6004 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006005 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006006
6007 const Decl *D = getCursorDecl(C);
6008 ASTContext &Context = getCursorContext(C);
6009 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6010 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6011 StringRef();
6012
6013 // Don't duplicate the string because RawText points directly into source
6014 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006015 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006016}
6017
6018CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6019 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006020 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006021
6022 const Decl *D = getCursorDecl(C);
6023 const ASTContext &Context = getCursorContext(C);
6024 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6025
6026 if (RC) {
6027 StringRef BriefText = RC->getBriefText(Context);
6028
6029 // Don't duplicate the string because RawComment ensures that this memory
6030 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006031 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006032 }
6033
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006034 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006035}
6036
6037CXComment clang_Cursor_getParsedComment(CXCursor C) {
6038 if (!clang_isDeclaration(C.kind))
6039 return cxcomment::createCXComment(NULL, NULL);
6040
6041 const Decl *D = getCursorDecl(C);
6042 const ASTContext &Context = getCursorContext(C);
6043 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6044
6045 return cxcomment::createCXComment(FC, getCursorTU(C));
6046}
6047
6048CXModule clang_Cursor_getModule(CXCursor C) {
6049 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006050 if (const ImportDecl *ImportD =
6051 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006052 return ImportD->getImportedModule();
6053 }
6054
6055 return 0;
6056}
6057
6058CXModule clang_Module_getParent(CXModule CXMod) {
6059 if (!CXMod)
6060 return 0;
6061 Module *Mod = static_cast<Module*>(CXMod);
6062 return Mod->Parent;
6063}
6064
6065CXString clang_Module_getName(CXModule CXMod) {
6066 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006067 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006068 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006069 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006070}
6071
6072CXString clang_Module_getFullName(CXModule CXMod) {
6073 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006074 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006075 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006076 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006077}
6078
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006079unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6080 CXModule CXMod) {
6081 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006082 return 0;
6083 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006084 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6085 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6086 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006087}
6088
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006089CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6090 CXModule CXMod, unsigned Index) {
6091 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006092 return 0;
6093 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006094 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006095
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006096 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6097 if (Index < TopHeaders.size())
6098 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006099
6100 return 0;
6101}
6102
6103} // end: extern "C"
6104
6105//===----------------------------------------------------------------------===//
6106// C++ AST instrospection.
6107//===----------------------------------------------------------------------===//
6108
6109extern "C" {
6110unsigned clang_CXXMethod_isStatic(CXCursor C) {
6111 if (!clang_isDeclaration(C.kind))
6112 return 0;
6113
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006114 const CXXMethodDecl *Method = 0;
6115 const Decl *D = cxcursor::getCursorDecl(C);
6116 if (const FunctionTemplateDecl *FunTmpl =
6117 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006118 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6119 else
6120 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6121 return (Method && Method->isStatic()) ? 1 : 0;
6122}
6123
6124unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6125 if (!clang_isDeclaration(C.kind))
6126 return 0;
6127
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006128 const CXXMethodDecl *Method = 0;
6129 const Decl *D = cxcursor::getCursorDecl(C);
6130 if (const FunctionTemplateDecl *FunTmpl =
6131 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006132 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6133 else
6134 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6135 return (Method && Method->isVirtual()) ? 1 : 0;
6136}
6137} // end: extern "C"
6138
6139//===----------------------------------------------------------------------===//
6140// Attribute introspection.
6141//===----------------------------------------------------------------------===//
6142
6143extern "C" {
6144CXType clang_getIBOutletCollectionType(CXCursor C) {
6145 if (C.kind != CXCursor_IBOutletCollectionAttr)
6146 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6147
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006148 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006149 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6150
6151 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6152}
6153} // end: extern "C"
6154
6155//===----------------------------------------------------------------------===//
6156// Inspecting memory usage.
6157//===----------------------------------------------------------------------===//
6158
6159typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6160
6161static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6162 enum CXTUResourceUsageKind k,
6163 unsigned long amount) {
6164 CXTUResourceUsageEntry entry = { k, amount };
6165 entries.push_back(entry);
6166}
6167
6168extern "C" {
6169
6170const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6171 const char *str = "";
6172 switch (kind) {
6173 case CXTUResourceUsage_AST:
6174 str = "ASTContext: expressions, declarations, and types";
6175 break;
6176 case CXTUResourceUsage_Identifiers:
6177 str = "ASTContext: identifiers";
6178 break;
6179 case CXTUResourceUsage_Selectors:
6180 str = "ASTContext: selectors";
6181 break;
6182 case CXTUResourceUsage_GlobalCompletionResults:
6183 str = "Code completion: cached global results";
6184 break;
6185 case CXTUResourceUsage_SourceManagerContentCache:
6186 str = "SourceManager: content cache allocator";
6187 break;
6188 case CXTUResourceUsage_AST_SideTables:
6189 str = "ASTContext: side tables";
6190 break;
6191 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6192 str = "SourceManager: malloc'ed memory buffers";
6193 break;
6194 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6195 str = "SourceManager: mmap'ed memory buffers";
6196 break;
6197 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6198 str = "ExternalASTSource: malloc'ed memory buffers";
6199 break;
6200 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6201 str = "ExternalASTSource: mmap'ed memory buffers";
6202 break;
6203 case CXTUResourceUsage_Preprocessor:
6204 str = "Preprocessor: malloc'ed memory";
6205 break;
6206 case CXTUResourceUsage_PreprocessingRecord:
6207 str = "Preprocessor: PreprocessingRecord";
6208 break;
6209 case CXTUResourceUsage_SourceManager_DataStructures:
6210 str = "SourceManager: data structures and tables";
6211 break;
6212 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6213 str = "Preprocessor: header search tables";
6214 break;
6215 }
6216 return str;
6217}
6218
6219CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6220 if (!TU) {
6221 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6222 return usage;
6223 }
6224
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006225 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006226 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6227 ASTContext &astContext = astUnit->getASTContext();
6228
6229 // How much memory is used by AST nodes and types?
6230 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6231 (unsigned long) astContext.getASTAllocatedMemory());
6232
6233 // How much memory is used by identifiers?
6234 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6235 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6236
6237 // How much memory is used for selectors?
6238 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6239 (unsigned long) astContext.Selectors.getTotalMemory());
6240
6241 // How much memory is used by ASTContext's side tables?
6242 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6243 (unsigned long) astContext.getSideTableAllocatedMemory());
6244
6245 // How much memory is used for caching global code completion results?
6246 unsigned long completionBytes = 0;
6247 if (GlobalCodeCompletionAllocator *completionAllocator =
6248 astUnit->getCachedCompletionAllocator().getPtr()) {
6249 completionBytes = completionAllocator->getTotalMemory();
6250 }
6251 createCXTUResourceUsageEntry(*entries,
6252 CXTUResourceUsage_GlobalCompletionResults,
6253 completionBytes);
6254
6255 // How much memory is being used by SourceManager's content cache?
6256 createCXTUResourceUsageEntry(*entries,
6257 CXTUResourceUsage_SourceManagerContentCache,
6258 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6259
6260 // How much memory is being used by the MemoryBuffer's in SourceManager?
6261 const SourceManager::MemoryBufferSizes &srcBufs =
6262 astUnit->getSourceManager().getMemoryBufferSizes();
6263
6264 createCXTUResourceUsageEntry(*entries,
6265 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6266 (unsigned long) srcBufs.malloc_bytes);
6267 createCXTUResourceUsageEntry(*entries,
6268 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6269 (unsigned long) srcBufs.mmap_bytes);
6270 createCXTUResourceUsageEntry(*entries,
6271 CXTUResourceUsage_SourceManager_DataStructures,
6272 (unsigned long) astContext.getSourceManager()
6273 .getDataStructureSizes());
6274
6275 // How much memory is being used by the ExternalASTSource?
6276 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6277 const ExternalASTSource::MemoryBufferSizes &sizes =
6278 esrc->getMemoryBufferSizes();
6279
6280 createCXTUResourceUsageEntry(*entries,
6281 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6282 (unsigned long) sizes.malloc_bytes);
6283 createCXTUResourceUsageEntry(*entries,
6284 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6285 (unsigned long) sizes.mmap_bytes);
6286 }
6287
6288 // How much memory is being used by the Preprocessor?
6289 Preprocessor &pp = astUnit->getPreprocessor();
6290 createCXTUResourceUsageEntry(*entries,
6291 CXTUResourceUsage_Preprocessor,
6292 pp.getTotalMemory());
6293
6294 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6295 createCXTUResourceUsageEntry(*entries,
6296 CXTUResourceUsage_PreprocessingRecord,
6297 pRec->getTotalMemory());
6298 }
6299
6300 createCXTUResourceUsageEntry(*entries,
6301 CXTUResourceUsage_Preprocessor_HeaderSearch,
6302 pp.getHeaderSearchInfo().getTotalMemory());
6303
6304 CXTUResourceUsage usage = { (void*) entries.get(),
6305 (unsigned) entries->size(),
6306 entries->size() ? &(*entries)[0] : 0 };
6307 entries.take();
6308 return usage;
6309}
6310
6311void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6312 if (usage.data)
6313 delete (MemUsageEntries*) usage.data;
6314}
6315
6316} // end extern "C"
6317
6318void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6319 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6320 for (unsigned I = 0; I != Usage.numEntries; ++I)
6321 fprintf(stderr, " %s: %lu\n",
6322 clang_getTUResourceUsageName(Usage.entries[I].kind),
6323 Usage.entries[I].amount);
6324
6325 clang_disposeCXTUResourceUsage(Usage);
6326}
6327
6328//===----------------------------------------------------------------------===//
6329// Misc. utility functions.
6330//===----------------------------------------------------------------------===//
6331
6332/// Default to using an 8 MB stack size on "safety" threads.
6333static unsigned SafetyStackThreadSize = 8 << 20;
6334
6335namespace clang {
6336
6337bool RunSafely(llvm::CrashRecoveryContext &CRC,
6338 void (*Fn)(void*), void *UserData,
6339 unsigned Size) {
6340 if (!Size)
6341 Size = GetSafetyThreadStackSize();
6342 if (Size)
6343 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6344 return CRC.RunSafely(Fn, UserData);
6345}
6346
6347unsigned GetSafetyThreadStackSize() {
6348 return SafetyStackThreadSize;
6349}
6350
6351void SetSafetyThreadStackSize(unsigned Value) {
6352 SafetyStackThreadSize = Value;
6353}
6354
6355}
6356
6357void clang::setThreadBackgroundPriority() {
6358 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6359 return;
6360
6361 // FIXME: Move to llvm/Support and make it cross-platform.
6362#ifdef __APPLE__
6363 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6364#endif
6365}
6366
6367void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6368 if (!Unit)
6369 return;
6370
6371 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6372 DEnd = Unit->stored_diag_end();
6373 D != DEnd; ++D) {
6374 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6375 CXString Msg = clang_formatDiagnostic(&Diag,
6376 clang_defaultDiagnosticDisplayOptions());
6377 fprintf(stderr, "%s\n", clang_getCString(Msg));
6378 clang_disposeString(Msg);
6379 }
6380#ifdef LLVM_ON_WIN32
6381 // On Windows, force a flush, since there may be multiple copies of
6382 // stderr and stdout in the file system, all with different buffers
6383 // but writing to the same device.
6384 fflush(stderr);
6385#endif
6386}
6387
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006388MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6389 SourceLocation MacroDefLoc,
6390 CXTranslationUnit TU){
6391 if (MacroDefLoc.isInvalid() || !TU)
6392 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006393 if (!II.hadMacroDefinition())
6394 return 0;
6395
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006396 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006397 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006398 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006399 if (MD) {
6400 for (MacroDirective::DefInfo
6401 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6402 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6403 return Def.getMacroInfo();
6404 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006405 }
6406
6407 return 0;
6408}
6409
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006410const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6411 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006412 if (!MacroDef || !TU)
6413 return 0;
6414 const IdentifierInfo *II = MacroDef->getName();
6415 if (!II)
6416 return 0;
6417
6418 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6419}
6420
6421MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6422 const Token &Tok,
6423 CXTranslationUnit TU) {
6424 if (!MI || !TU)
6425 return 0;
6426 if (Tok.isNot(tok::raw_identifier))
6427 return 0;
6428
6429 if (MI->getNumTokens() == 0)
6430 return 0;
6431 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6432 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006433 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006434
6435 // Check that the token is inside the definition and not its argument list.
6436 SourceManager &SM = Unit->getSourceManager();
6437 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6438 return 0;
6439 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6440 return 0;
6441
6442 Preprocessor &PP = Unit->getPreprocessor();
6443 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6444 if (!PPRec)
6445 return 0;
6446
6447 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6448 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6449 if (!II.hadMacroDefinition())
6450 return 0;
6451
6452 // Check that the identifier is not one of the macro arguments.
6453 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6454 return 0;
6455
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006456 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6457 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006458 return 0;
6459
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006460 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006461}
6462
6463MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6464 SourceLocation Loc,
6465 CXTranslationUnit TU) {
6466 if (Loc.isInvalid() || !MI || !TU)
6467 return 0;
6468
6469 if (MI->getNumTokens() == 0)
6470 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006471 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006472 Preprocessor &PP = Unit->getPreprocessor();
6473 if (!PP.getPreprocessingRecord())
6474 return 0;
6475 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6476 Token Tok;
6477 if (PP.getRawToken(Loc, Tok))
6478 return 0;
6479
6480 return checkForMacroInMacroDefinition(MI, Tok, TU);
6481}
6482
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006483extern "C" {
6484
6485CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006486 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006487}
6488
6489} // end: extern "C"
6490
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006491Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6492 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006493 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006494 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006495 if (Unit->isMainFileAST())
6496 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006497 return *this;
6498 }
6499 }
6500
6501 LogOS << "<NULL TU>";
6502 return *this;
6503}
6504
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006505Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6506 *this << FE->getName();
6507 return *this;
6508}
6509
6510Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6511 CXString cursorName = clang_getCursorDisplayName(cursor);
6512 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6513 clang_disposeString(cursorName);
6514 return *this;
6515}
6516
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006517Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6518 CXFile File;
6519 unsigned Line, Column;
6520 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6521 CXString FileName = clang_getFileName(File);
6522 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6523 clang_disposeString(FileName);
6524 return *this;
6525}
6526
6527Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6528 CXSourceLocation BLoc = clang_getRangeStart(range);
6529 CXSourceLocation ELoc = clang_getRangeEnd(range);
6530
6531 CXFile BFile;
6532 unsigned BLine, BColumn;
6533 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6534
6535 CXFile EFile;
6536 unsigned ELine, EColumn;
6537 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6538
6539 CXString BFileName = clang_getFileName(BFile);
6540 if (BFile == EFile) {
6541 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6542 BLine, BColumn, ELine, EColumn);
6543 } else {
6544 CXString EFileName = clang_getFileName(EFile);
6545 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6546 BLine, BColumn)
6547 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6548 ELine, EColumn);
6549 clang_disposeString(EFileName);
6550 }
6551 clang_disposeString(BFileName);
6552 return *this;
6553}
6554
6555Logger &cxindex::Logger::operator<<(CXString Str) {
6556 *this << clang_getCString(Str);
6557 return *this;
6558}
6559
6560Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6561 LogOS << Fmt;
6562 return *this;
6563}
6564
6565cxindex::Logger::~Logger() {
6566 LogOS.flush();
6567
6568 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6569
6570 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6571
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006572 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006573 OS << "[libclang:" << Name << ':';
6574
6575 // FIXME: Portability.
6576#if HAVE_PTHREAD_H && __APPLE__
6577 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6578 OS << tid << ':';
6579#endif
6580
6581 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6582 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6583 OS << Msg.str() << '\n';
6584
6585 if (Trace) {
6586 llvm::sys::PrintStackTrace(stderr);
6587 OS << "--------------------------------------------------\n";
6588 }
6589}