blob: a2449bdc3f1030cff4e0d332cee3e94ac748f785 [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) {
726 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
727 if (Visit(TSInfo->getTypeLoc()))
728 return true;
729
730 // Visit the nested-name-specifier, if present.
731 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
732 if (VisitNestedNameSpecifierLoc(QualifierLoc))
733 return true;
734
735 return false;
736}
737
738/// \brief Compare two base or member initializers based on their source order.
739static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
740 CXXCtorInitializer const * const *X
741 = static_cast<CXXCtorInitializer const * const *>(Xp);
742 CXXCtorInitializer const * const *Y
743 = static_cast<CXXCtorInitializer const * const *>(Yp);
744
745 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
746 return -1;
747 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
748 return 1;
749 else
750 return 0;
751}
752
753bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
754 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
755 // Visit the function declaration's syntactic components in the order
756 // written. This requires a bit of work.
757 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000758 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000759
760 // If we have a function declared directly (without the use of a typedef),
761 // visit just the return type. Otherwise, just visit the function's type
762 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000763 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000764 (!FTL && Visit(TL)))
765 return true;
766
767 // Visit the nested-name-specifier, if present.
768 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
769 if (VisitNestedNameSpecifierLoc(QualifierLoc))
770 return true;
771
772 // Visit the declaration name.
773 if (VisitDeclarationNameInfo(ND->getNameInfo()))
774 return true;
775
776 // FIXME: Visit explicitly-specified template arguments!
777
778 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000779 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000780 return true;
781
Bill Wendlingad017fa2012-12-20 19:22:21 +0000782 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000783 }
784
785 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
786 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
787 // Find the initializers that were written in the source.
788 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
789 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
790 IEnd = Constructor->init_end();
791 I != IEnd; ++I) {
792 if (!(*I)->isWritten())
793 continue;
794
795 WrittenInits.push_back(*I);
796 }
797
798 // Sort the initializers in source order
799 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
800 &CompareCXXCtorInitializers);
801
802 // Visit the initializers in source order
803 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
804 CXXCtorInitializer *Init = WrittenInits[I];
805 if (Init->isAnyMemberInitializer()) {
806 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
807 Init->getMemberLocation(), TU)))
808 return true;
809 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
810 if (Visit(TInfo->getTypeLoc()))
811 return true;
812 }
813
814 // Visit the initializer value.
815 if (Expr *Initializer = Init->getInit())
816 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
817 return true;
818 }
819 }
820
821 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
822 return true;
823 }
824
825 return false;
826}
827
828bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
829 if (VisitDeclaratorDecl(D))
830 return true;
831
832 if (Expr *BitWidth = D->getBitWidth())
833 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
834
835 return false;
836}
837
838bool CursorVisitor::VisitVarDecl(VarDecl *D) {
839 if (VisitDeclaratorDecl(D))
840 return true;
841
842 if (Expr *Init = D->getInit())
843 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
844
845 return false;
846}
847
848bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
849 if (VisitDeclaratorDecl(D))
850 return true;
851
852 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
853 if (Expr *DefArg = D->getDefaultArgument())
854 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
855
856 return false;
857}
858
859bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
860 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
861 // before visiting these template parameters.
862 if (VisitTemplateParameters(D->getTemplateParameters()))
863 return true;
864
865 return VisitFunctionDecl(D->getTemplatedDecl());
866}
867
868bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
869 // FIXME: Visit the "outer" template parameter lists on the TagDecl
870 // before visiting these template parameters.
871 if (VisitTemplateParameters(D->getTemplateParameters()))
872 return true;
873
874 return VisitCXXRecordDecl(D->getTemplatedDecl());
875}
876
877bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
878 if (VisitTemplateParameters(D->getTemplateParameters()))
879 return true;
880
881 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
882 VisitTemplateArgumentLoc(D->getDefaultArgument()))
883 return true;
884
885 return false;
886}
887
888bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
889 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
890 if (Visit(TSInfo->getTypeLoc()))
891 return true;
892
893 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
894 PEnd = ND->param_end();
895 P != PEnd; ++P) {
896 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
897 return true;
898 }
899
900 if (ND->isThisDeclarationADefinition() &&
901 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
902 return true;
903
904 return false;
905}
906
907template <typename DeclIt>
908static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
909 SourceManager &SM, SourceLocation EndLoc,
910 SmallVectorImpl<Decl *> &Decls) {
911 DeclIt next = *DI_current;
912 while (++next != DE_current) {
913 Decl *D_next = *next;
914 if (!D_next)
915 break;
916 SourceLocation L = D_next->getLocStart();
917 if (!L.isValid())
918 break;
919 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
920 *DI_current = next;
921 Decls.push_back(D_next);
922 continue;
923 }
924 break;
925 }
926}
927
928namespace {
929 struct ContainerDeclsSort {
930 SourceManager &SM;
931 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
932 bool operator()(Decl *A, Decl *B) {
933 SourceLocation L_A = A->getLocStart();
934 SourceLocation L_B = B->getLocStart();
935 assert(L_A.isValid() && L_B.isValid());
936 return SM.isBeforeInTranslationUnit(L_A, L_B);
937 }
938 };
939}
940
941bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
942 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
943 // an @implementation can lexically contain Decls that are not properly
944 // nested in the AST. When we identify such cases, we need to retrofit
945 // this nesting here.
946 if (!DI_current && !FileDI_current)
947 return VisitDeclContext(D);
948
949 // Scan the Decls that immediately come after the container
950 // in the current DeclContext. If any fall within the
951 // container's lexical region, stash them into a vector
952 // for later processing.
953 SmallVector<Decl *, 24> DeclsInContainer;
954 SourceLocation EndLoc = D->getSourceRange().getEnd();
955 SourceManager &SM = AU->getSourceManager();
956 if (EndLoc.isValid()) {
957 if (DI_current) {
958 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
959 DeclsInContainer);
960 } else {
961 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
962 DeclsInContainer);
963 }
964 }
965
966 // The common case.
967 if (DeclsInContainer.empty())
968 return VisitDeclContext(D);
969
970 // Get all the Decls in the DeclContext, and sort them with the
971 // additional ones we've collected. Then visit them.
972 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
973 I!=E; ++I) {
974 Decl *subDecl = *I;
975 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
976 subDecl->getLocStart().isInvalid())
977 continue;
978 DeclsInContainer.push_back(subDecl);
979 }
980
981 // Now sort the Decls so that they appear in lexical order.
982 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
983 ContainerDeclsSort(SM));
984
985 // Now visit the decls.
986 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
987 E = DeclsInContainer.end(); I != E; ++I) {
988 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +0000989 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000990 if (!V.hasValue())
991 continue;
992 if (!V.getValue())
993 return false;
994 if (Visit(Cursor, true))
995 return true;
996 }
997 return false;
998}
999
1000bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1001 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1002 TU)))
1003 return true;
1004
1005 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1006 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1007 E = ND->protocol_end(); I != E; ++I, ++PL)
1008 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1009 return true;
1010
1011 return VisitObjCContainerDecl(ND);
1012}
1013
1014bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1015 if (!PID->isThisDeclarationADefinition())
1016 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1017
1018 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1019 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1020 E = PID->protocol_end(); I != E; ++I, ++PL)
1021 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1022 return true;
1023
1024 return VisitObjCContainerDecl(PID);
1025}
1026
1027bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1028 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1029 return true;
1030
1031 // FIXME: This implements a workaround with @property declarations also being
1032 // installed in the DeclContext for the @interface. Eventually this code
1033 // should be removed.
1034 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1035 if (!CDecl || !CDecl->IsClassExtension())
1036 return false;
1037
1038 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1039 if (!ID)
1040 return false;
1041
1042 IdentifierInfo *PropertyId = PD->getIdentifier();
1043 ObjCPropertyDecl *prevDecl =
1044 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1045
1046 if (!prevDecl)
1047 return false;
1048
1049 // Visit synthesized methods since they will be skipped when visiting
1050 // the @interface.
1051 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1052 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1053 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1054 return true;
1055
1056 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1057 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1058 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1059 return true;
1060
1061 return false;
1062}
1063
1064bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1065 if (!D->isThisDeclarationADefinition()) {
1066 // Forward declaration is treated like a reference.
1067 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1068 }
1069
1070 // Issue callbacks for super class.
1071 if (D->getSuperClass() &&
1072 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1073 D->getSuperClassLoc(),
1074 TU)))
1075 return true;
1076
1077 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1078 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1079 E = D->protocol_end(); I != E; ++I, ++PL)
1080 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1081 return true;
1082
1083 return VisitObjCContainerDecl(D);
1084}
1085
1086bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1087 return VisitObjCContainerDecl(D);
1088}
1089
1090bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1091 // 'ID' could be null when dealing with invalid code.
1092 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1093 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1094 return true;
1095
1096 return VisitObjCImplDecl(D);
1097}
1098
1099bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1100#if 0
1101 // Issue callbacks for super class.
1102 // FIXME: No source location information!
1103 if (D->getSuperClass() &&
1104 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1105 D->getSuperClassLoc(),
1106 TU)))
1107 return true;
1108#endif
1109
1110 return VisitObjCImplDecl(D);
1111}
1112
1113bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1114 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1115 if (PD->isIvarNameSpecified())
1116 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1117
1118 return false;
1119}
1120
1121bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1122 return VisitDeclContext(D);
1123}
1124
1125bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1126 // Visit nested-name-specifier.
1127 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1128 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1129 return true;
1130
1131 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1132 D->getTargetNameLoc(), TU));
1133}
1134
1135bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1136 // Visit nested-name-specifier.
1137 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1138 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1139 return true;
1140 }
1141
1142 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1143 return true;
1144
1145 return VisitDeclarationNameInfo(D->getNameInfo());
1146}
1147
1148bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1149 // Visit nested-name-specifier.
1150 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1151 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1152 return true;
1153
1154 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1155 D->getIdentLocation(), TU));
1156}
1157
1158bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1159 // Visit nested-name-specifier.
1160 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1161 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1162 return true;
1163 }
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1169 UnresolvedUsingTypenameDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174
1175 return false;
1176}
1177
1178bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1179 switch (Name.getName().getNameKind()) {
1180 case clang::DeclarationName::Identifier:
1181 case clang::DeclarationName::CXXLiteralOperatorName:
1182 case clang::DeclarationName::CXXOperatorName:
1183 case clang::DeclarationName::CXXUsingDirective:
1184 return false;
1185
1186 case clang::DeclarationName::CXXConstructorName:
1187 case clang::DeclarationName::CXXDestructorName:
1188 case clang::DeclarationName::CXXConversionFunctionName:
1189 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1190 return Visit(TSInfo->getTypeLoc());
1191 return false;
1192
1193 case clang::DeclarationName::ObjCZeroArgSelector:
1194 case clang::DeclarationName::ObjCOneArgSelector:
1195 case clang::DeclarationName::ObjCMultiArgSelector:
1196 // FIXME: Per-identifier location info?
1197 return false;
1198 }
1199
1200 llvm_unreachable("Invalid DeclarationName::Kind!");
1201}
1202
1203bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1204 SourceRange Range) {
1205 // FIXME: This whole routine is a hack to work around the lack of proper
1206 // source information in nested-name-specifiers (PR5791). Since we do have
1207 // a beginning source location, we can visit the first component of the
1208 // nested-name-specifier, if it's a single-token component.
1209 if (!NNS)
1210 return false;
1211
1212 // Get the first component in the nested-name-specifier.
1213 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1214 NNS = Prefix;
1215
1216 switch (NNS->getKind()) {
1217 case NestedNameSpecifier::Namespace:
1218 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1219 TU));
1220
1221 case NestedNameSpecifier::NamespaceAlias:
1222 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1223 Range.getBegin(), TU));
1224
1225 case NestedNameSpecifier::TypeSpec: {
1226 // If the type has a form where we know that the beginning of the source
1227 // range matches up with a reference cursor. Visit the appropriate reference
1228 // cursor.
1229 const Type *T = NNS->getAsType();
1230 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1231 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1232 if (const TagType *Tag = dyn_cast<TagType>(T))
1233 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1234 if (const TemplateSpecializationType *TST
1235 = dyn_cast<TemplateSpecializationType>(T))
1236 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1237 break;
1238 }
1239
1240 case NestedNameSpecifier::TypeSpecWithTemplate:
1241 case NestedNameSpecifier::Global:
1242 case NestedNameSpecifier::Identifier:
1243 break;
1244 }
1245
1246 return false;
1247}
1248
1249bool
1250CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1251 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1252 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1253 Qualifiers.push_back(Qualifier);
1254
1255 while (!Qualifiers.empty()) {
1256 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1257 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1258 switch (NNS->getKind()) {
1259 case NestedNameSpecifier::Namespace:
1260 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1261 Q.getLocalBeginLoc(),
1262 TU)))
1263 return true;
1264
1265 break;
1266
1267 case NestedNameSpecifier::NamespaceAlias:
1268 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1269 Q.getLocalBeginLoc(),
1270 TU)))
1271 return true;
1272
1273 break;
1274
1275 case NestedNameSpecifier::TypeSpec:
1276 case NestedNameSpecifier::TypeSpecWithTemplate:
1277 if (Visit(Q.getTypeLoc()))
1278 return true;
1279
1280 break;
1281
1282 case NestedNameSpecifier::Global:
1283 case NestedNameSpecifier::Identifier:
1284 break;
1285 }
1286 }
1287
1288 return false;
1289}
1290
1291bool CursorVisitor::VisitTemplateParameters(
1292 const TemplateParameterList *Params) {
1293 if (!Params)
1294 return false;
1295
1296 for (TemplateParameterList::const_iterator P = Params->begin(),
1297 PEnd = Params->end();
1298 P != PEnd; ++P) {
1299 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1300 return true;
1301 }
1302
1303 return false;
1304}
1305
1306bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1307 switch (Name.getKind()) {
1308 case TemplateName::Template:
1309 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1310
1311 case TemplateName::OverloadedTemplate:
1312 // Visit the overloaded template set.
1313 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1314 return true;
1315
1316 return false;
1317
1318 case TemplateName::DependentTemplate:
1319 // FIXME: Visit nested-name-specifier.
1320 return false;
1321
1322 case TemplateName::QualifiedTemplate:
1323 // FIXME: Visit nested-name-specifier.
1324 return Visit(MakeCursorTemplateRef(
1325 Name.getAsQualifiedTemplateName()->getDecl(),
1326 Loc, TU));
1327
1328 case TemplateName::SubstTemplateTemplateParm:
1329 return Visit(MakeCursorTemplateRef(
1330 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1331 Loc, TU));
1332
1333 case TemplateName::SubstTemplateTemplateParmPack:
1334 return Visit(MakeCursorTemplateRef(
1335 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1336 Loc, TU));
1337 }
1338
1339 llvm_unreachable("Invalid TemplateName::Kind!");
1340}
1341
1342bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1343 switch (TAL.getArgument().getKind()) {
1344 case TemplateArgument::Null:
1345 case TemplateArgument::Integral:
1346 case TemplateArgument::Pack:
1347 return false;
1348
1349 case TemplateArgument::Type:
1350 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1351 return Visit(TSInfo->getTypeLoc());
1352 return false;
1353
1354 case TemplateArgument::Declaration:
1355 if (Expr *E = TAL.getSourceDeclExpression())
1356 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1357 return false;
1358
1359 case TemplateArgument::NullPtr:
1360 if (Expr *E = TAL.getSourceNullPtrExpression())
1361 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1362 return false;
1363
1364 case TemplateArgument::Expression:
1365 if (Expr *E = TAL.getSourceExpression())
1366 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1367 return false;
1368
1369 case TemplateArgument::Template:
1370 case TemplateArgument::TemplateExpansion:
1371 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1372 return true;
1373
1374 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1375 TAL.getTemplateNameLoc());
1376 }
1377
1378 llvm_unreachable("Invalid TemplateArgument::Kind!");
1379}
1380
1381bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1382 return VisitDeclContext(D);
1383}
1384
1385bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1386 return Visit(TL.getUnqualifiedLoc());
1387}
1388
1389bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1390 ASTContext &Context = AU->getASTContext();
1391
1392 // Some builtin types (such as Objective-C's "id", "sel", and
1393 // "Class") have associated declarations. Create cursors for those.
1394 QualType VisitType;
1395 switch (TL.getTypePtr()->getKind()) {
1396
1397 case BuiltinType::Void:
1398 case BuiltinType::NullPtr:
1399 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001400 case BuiltinType::OCLImage1d:
1401 case BuiltinType::OCLImage1dArray:
1402 case BuiltinType::OCLImage1dBuffer:
1403 case BuiltinType::OCLImage2d:
1404 case BuiltinType::OCLImage2dArray:
1405 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001406 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001407 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001408#define BUILTIN_TYPE(Id, SingletonId)
1409#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1410#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1411#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1412#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1413#include "clang/AST/BuiltinTypes.def"
1414 break;
1415
1416 case BuiltinType::ObjCId:
1417 VisitType = Context.getObjCIdType();
1418 break;
1419
1420 case BuiltinType::ObjCClass:
1421 VisitType = Context.getObjCClassType();
1422 break;
1423
1424 case BuiltinType::ObjCSel:
1425 VisitType = Context.getObjCSelType();
1426 break;
1427 }
1428
1429 if (!VisitType.isNull()) {
1430 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1431 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1432 TU));
1433 }
1434
1435 return false;
1436}
1437
1438bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1439 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1440}
1441
1442bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1443 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1444}
1445
1446bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1447 if (TL.isDefinition())
1448 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1449
1450 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1458 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1459 return true;
1460
1461 return false;
1462}
1463
1464bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1465 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1466 return true;
1467
1468 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1469 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1470 TU)))
1471 return true;
1472 }
1473
1474 return false;
1475}
1476
1477bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1478 return Visit(TL.getPointeeLoc());
1479}
1480
1481bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1482 return Visit(TL.getInnerLoc());
1483}
1484
1485bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1486 return Visit(TL.getPointeeLoc());
1487}
1488
1489bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1506 return Visit(TL.getModifiedLoc());
1507}
1508
1509bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1510 bool SkipResultType) {
1511 if (!SkipResultType && Visit(TL.getResultLoc()))
1512 return true;
1513
1514 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1515 if (Decl *D = TL.getArg(I))
1516 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1517 return true;
1518
1519 return false;
1520}
1521
1522bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1523 if (Visit(TL.getElementLoc()))
1524 return true;
1525
1526 if (Expr *Size = TL.getSizeExpr())
1527 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1533 TemplateSpecializationTypeLoc TL) {
1534 // Visit the template name.
1535 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1536 TL.getTemplateNameLoc()))
1537 return true;
1538
1539 // Visit the template arguments.
1540 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1541 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1542 return true;
1543
1544 return false;
1545}
1546
1547bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1548 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1549}
1550
1551bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1552 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1553 return Visit(TSInfo->getTypeLoc());
1554
1555 return false;
1556}
1557
1558bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1559 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1560 return Visit(TSInfo->getTypeLoc());
1561
1562 return false;
1563}
1564
1565bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1566 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1567 return true;
1568
1569 return false;
1570}
1571
1572bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1573 DependentTemplateSpecializationTypeLoc TL) {
1574 // Visit the nested-name-specifier, if there is one.
1575 if (TL.getQualifierLoc() &&
1576 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1577 return true;
1578
1579 // Visit the template arguments.
1580 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1581 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1582 return true;
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return Visit(TL.getNamedTypeLoc());
1592}
1593
1594bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1595 return Visit(TL.getPatternLoc());
1596}
1597
1598bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1599 if (Expr *E = TL.getUnderlyingExpr())
1600 return Visit(MakeCXCursor(E, StmtParent, TU));
1601
1602 return false;
1603}
1604
1605bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1606 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1607}
1608
1609bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1610 return Visit(TL.getValueLoc());
1611}
1612
1613#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1614bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1615 return Visit##PARENT##Loc(TL); \
1616}
1617
1618DEFAULT_TYPELOC_IMPL(Complex, Type)
1619DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1620DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1621DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1622DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1623DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1624DEFAULT_TYPELOC_IMPL(Vector, Type)
1625DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1626DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1627DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1628DEFAULT_TYPELOC_IMPL(Record, TagType)
1629DEFAULT_TYPELOC_IMPL(Enum, TagType)
1630DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1631DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1632DEFAULT_TYPELOC_IMPL(Auto, Type)
1633
1634bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1635 // Visit the nested-name-specifier, if present.
1636 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1637 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1638 return true;
1639
1640 if (D->isCompleteDefinition()) {
1641 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1642 E = D->bases_end(); I != E; ++I) {
1643 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1644 return true;
1645 }
1646 }
1647
1648 return VisitTagDecl(D);
1649}
1650
1651bool CursorVisitor::VisitAttributes(Decl *D) {
1652 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1653 i != e; ++i)
1654 if (Visit(MakeCXCursor(*i, D, TU)))
1655 return true;
1656
1657 return false;
1658}
1659
1660//===----------------------------------------------------------------------===//
1661// Data-recursive visitor methods.
1662//===----------------------------------------------------------------------===//
1663
1664namespace {
1665#define DEF_JOB(NAME, DATA, KIND)\
1666class NAME : public VisitorJob {\
1667public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001668 NAME(const DATA *d, CXCursor parent) : \
1669 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001670 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001671 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001672};
1673
1674DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1675DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1676DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1677DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1678DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1679 ExplicitTemplateArgsVisitKind)
1680DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1681DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1682DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1683#undef DEF_JOB
1684
1685class DeclVisit : public VisitorJob {
1686public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001687 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001688 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001689 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001690 static bool classof(const VisitorJob *VJ) {
1691 return VJ->getKind() == DeclVisitKind;
1692 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001693 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001694 bool isFirst() const { return data[1] ? true : false; }
1695};
1696class TypeLocVisit : public VisitorJob {
1697public:
1698 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1699 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1700 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1701
1702 static bool classof(const VisitorJob *VJ) {
1703 return VJ->getKind() == TypeLocVisitKind;
1704 }
1705
1706 TypeLoc get() const {
1707 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001708 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001709 }
1710};
1711
1712class LabelRefVisit : public VisitorJob {
1713public:
1714 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1715 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1716 labelLoc.getPtrEncoding()) {}
1717
1718 static bool classof(const VisitorJob *VJ) {
1719 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1720 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001721 const LabelDecl *get() const {
1722 return static_cast<const LabelDecl *>(data[0]);
1723 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001724 SourceLocation getLoc() const {
1725 return SourceLocation::getFromPtrEncoding(data[1]); }
1726};
1727
1728class NestedNameSpecifierLocVisit : public VisitorJob {
1729public:
1730 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1731 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1732 Qualifier.getNestedNameSpecifier(),
1733 Qualifier.getOpaqueData()) { }
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1737 }
1738
1739 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001740 return NestedNameSpecifierLoc(
1741 const_cast<NestedNameSpecifier *>(
1742 static_cast<const NestedNameSpecifier *>(data[0])),
1743 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001744 }
1745};
1746
1747class DeclarationNameInfoVisit : public VisitorJob {
1748public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001749 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001750 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001751 static bool classof(const VisitorJob *VJ) {
1752 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1753 }
1754 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001755 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001756 switch (S->getStmtClass()) {
1757 default:
1758 llvm_unreachable("Unhandled Stmt");
1759 case clang::Stmt::MSDependentExistsStmtClass:
1760 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1761 case Stmt::CXXDependentScopeMemberExprClass:
1762 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1763 case Stmt::DependentScopeDeclRefExprClass:
1764 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1765 }
1766 }
1767};
1768class MemberRefVisit : public VisitorJob {
1769public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001770 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001771 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1772 L.getPtrEncoding()) {}
1773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1775 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001776 const FieldDecl *get() const {
1777 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001778 }
1779 SourceLocation getLoc() const {
1780 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1781 }
1782};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001783class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001784 VisitorWorkList &WL;
1785 CXCursor Parent;
1786public:
1787 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1788 : WL(wl), Parent(parent) {}
1789
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001790 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1791 void VisitBlockExpr(const BlockExpr *B);
1792 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1793 void VisitCompoundStmt(const CompoundStmt *S);
1794 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1795 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1796 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1797 void VisitCXXNewExpr(const CXXNewExpr *E);
1798 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1799 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1800 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1801 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1802 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1803 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1804 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1805 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1806 void VisitDeclRefExpr(const DeclRefExpr *D);
1807 void VisitDeclStmt(const DeclStmt *S);
1808 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1809 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1810 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1811 void VisitForStmt(const ForStmt *FS);
1812 void VisitGotoStmt(const GotoStmt *GS);
1813 void VisitIfStmt(const IfStmt *If);
1814 void VisitInitListExpr(const InitListExpr *IE);
1815 void VisitMemberExpr(const MemberExpr *M);
1816 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1817 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1818 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1819 void VisitOverloadExpr(const OverloadExpr *E);
1820 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1821 void VisitStmt(const Stmt *S);
1822 void VisitSwitchStmt(const SwitchStmt *S);
1823 void VisitWhileStmt(const WhileStmt *W);
1824 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1825 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1826 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1827 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1828 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1829 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1830 void VisitVAArgExpr(const VAArgExpr *E);
1831 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1832 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1833 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1834 void VisitLambdaExpr(const LambdaExpr *E);
1835
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001836private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001837 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001838 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1839 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001840 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1841 void AddStmt(const Stmt *S);
1842 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001843 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001844 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001845};
1846} // end anonyous namespace
1847
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001848void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001849 // 'S' should always be non-null, since it comes from the
1850 // statement we are visiting.
1851 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1852}
1853
1854void
1855EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1856 if (Qualifier)
1857 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1858}
1859
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001860void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001861 if (S)
1862 WL.push_back(StmtVisit(S, Parent));
1863}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001864void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001865 if (D)
1866 WL.push_back(DeclVisit(D, Parent, isFirst));
1867}
1868void EnqueueVisitor::
1869 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1870 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001871 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001872}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001873void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001874 if (D)
1875 WL.push_back(MemberRefVisit(D, L, Parent));
1876}
1877void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1878 if (TI)
1879 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1880 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001881void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001882 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001883 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001884 AddStmt(*Child);
1885 }
1886 if (size == WL.size())
1887 return;
1888 // Now reverse the entries we just added. This will match the DFS
1889 // ordering performed by the worklist.
1890 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1891 std::reverse(I, E);
1892}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001893void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001894 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1895}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001896void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001897 AddDecl(B->getBlockDecl());
1898}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001899void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 EnqueueChildren(E);
1901 AddTypeLoc(E->getTypeSourceInfo());
1902}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001903void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1904 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001905 E = S->body_rend(); I != E; ++I) {
1906 AddStmt(*I);
1907 }
1908}
1909void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001910VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001911 AddStmt(S->getSubStmt());
1912 AddDeclarationNameInfo(S);
1913 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1914 AddNestedNameSpecifierLoc(QualifierLoc);
1915}
1916
1917void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001918VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001919 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1920 AddDeclarationNameInfo(E);
1921 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1922 AddNestedNameSpecifierLoc(QualifierLoc);
1923 if (!E->isImplicitAccess())
1924 AddStmt(E->getBase());
1925}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001926void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001927 // Enqueue the initializer , if any.
1928 AddStmt(E->getInitializer());
1929 // Enqueue the array size, if any.
1930 AddStmt(E->getArraySize());
1931 // Enqueue the allocated type.
1932 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1933 // Enqueue the placement arguments.
1934 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1935 AddStmt(E->getPlacementArg(I-1));
1936}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001937void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001938 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1939 AddStmt(CE->getArg(I-1));
1940 AddStmt(CE->getCallee());
1941 AddStmt(CE->getArg(0));
1942}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001943void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1944 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001945 // Visit the name of the type being destroyed.
1946 AddTypeLoc(E->getDestroyedTypeInfo());
1947 // Visit the scope type that looks disturbingly like the nested-name-specifier
1948 // but isn't.
1949 AddTypeLoc(E->getScopeTypeInfo());
1950 // Visit the nested-name-specifier.
1951 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1952 AddNestedNameSpecifierLoc(QualifierLoc);
1953 // Visit base expression.
1954 AddStmt(E->getBase());
1955}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001956void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1957 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001958 AddTypeLoc(E->getTypeSourceInfo());
1959}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1961 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001962 EnqueueChildren(E);
1963 AddTypeLoc(E->getTypeSourceInfo());
1964}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001965void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001966 EnqueueChildren(E);
1967 if (E->isTypeOperand())
1968 AddTypeLoc(E->getTypeOperandSourceInfo());
1969}
1970
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001971void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1972 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001973 EnqueueChildren(E);
1974 AddTypeLoc(E->getTypeSourceInfo());
1975}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001977 EnqueueChildren(E);
1978 if (E->isTypeOperand())
1979 AddTypeLoc(E->getTypeOperandSourceInfo());
1980}
1981
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 EnqueueChildren(S);
1984 AddDecl(S->getExceptionDecl());
1985}
1986
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001987void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001988 if (DR->hasExplicitTemplateArgs()) {
1989 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1990 }
1991 WL.push_back(DeclRefExprParts(DR, Parent));
1992}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
1994 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001995 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1996 AddDeclarationNameInfo(E);
1997 AddNestedNameSpecifierLoc(E->getQualifierLoc());
1998}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002000 unsigned size = WL.size();
2001 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002002 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002003 D != DEnd; ++D) {
2004 AddDecl(*D, isFirst);
2005 isFirst = false;
2006 }
2007 if (size == WL.size())
2008 return;
2009 // Now reverse the entries we just added. This will match the DFS
2010 // ordering performed by the worklist.
2011 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2012 std::reverse(I, E);
2013}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002015 AddStmt(E->getInit());
2016 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002017 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002018 D = E->designators_rbegin(), DEnd = E->designators_rend();
2019 D != DEnd; ++D) {
2020 if (D->isFieldDesignator()) {
2021 if (FieldDecl *Field = D->getField())
2022 AddMemberRef(Field, D->getFieldLoc());
2023 continue;
2024 }
2025 if (D->isArrayDesignator()) {
2026 AddStmt(E->getArrayIndex(*D));
2027 continue;
2028 }
2029 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2030 AddStmt(E->getArrayRangeEnd(*D));
2031 AddStmt(E->getArrayRangeStart(*D));
2032 }
2033}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002035 EnqueueChildren(E);
2036 AddTypeLoc(E->getTypeInfoAsWritten());
2037}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002039 AddStmt(FS->getBody());
2040 AddStmt(FS->getInc());
2041 AddStmt(FS->getCond());
2042 AddDecl(FS->getConditionVariable());
2043 AddStmt(FS->getInit());
2044}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002046 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2047}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002049 AddStmt(If->getElse());
2050 AddStmt(If->getThen());
2051 AddStmt(If->getCond());
2052 AddDecl(If->getConditionVariable());
2053}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002055 // We care about the syntactic form of the initializer list, only.
2056 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2057 IE = Syntactic;
2058 EnqueueChildren(IE);
2059}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002061 WL.push_back(MemberExprParts(M, Parent));
2062
2063 // If the base of the member access expression is an implicit 'this', don't
2064 // visit it.
2065 // FIXME: If we ever want to show these implicit accesses, this will be
2066 // unfortunate. However, clang_getCursor() relies on this behavior.
2067 if (!M->isImplicitAccess())
2068 AddStmt(M->getBase());
2069}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002071 AddTypeLoc(E->getEncodedTypeSourceInfo());
2072}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002074 EnqueueChildren(M);
2075 AddTypeLoc(M->getClassReceiverTypeInfo());
2076}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002078 // Visit the components of the offsetof expression.
2079 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2080 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2081 const OffsetOfNode &Node = E->getComponent(I-1);
2082 switch (Node.getKind()) {
2083 case OffsetOfNode::Array:
2084 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2085 break;
2086 case OffsetOfNode::Field:
2087 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2088 break;
2089 case OffsetOfNode::Identifier:
2090 case OffsetOfNode::Base:
2091 continue;
2092 }
2093 }
2094 // Visit the type into which we're computing the offset.
2095 AddTypeLoc(E->getTypeSourceInfo());
2096}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002098 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2099 WL.push_back(OverloadExprParts(E, Parent));
2100}
2101void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002102 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002103 EnqueueChildren(E);
2104 if (E->isArgumentType())
2105 AddTypeLoc(E->getArgumentTypeInfo());
2106}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002108 EnqueueChildren(S);
2109}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002111 AddStmt(S->getBody());
2112 AddStmt(S->getCond());
2113 AddDecl(S->getConditionVariable());
2114}
2115
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002117 AddStmt(W->getBody());
2118 AddStmt(W->getCond());
2119 AddDecl(W->getConditionVariable());
2120}
2121
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002123 AddTypeLoc(E->getQueriedTypeSourceInfo());
2124}
2125
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002127 AddTypeLoc(E->getRhsTypeSourceInfo());
2128 AddTypeLoc(E->getLhsTypeSourceInfo());
2129}
2130
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002132 for (unsigned I = E->getNumArgs(); I > 0; --I)
2133 AddTypeLoc(E->getArg(I-1));
2134}
2135
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002137 AddTypeLoc(E->getQueriedTypeSourceInfo());
2138}
2139
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002141 EnqueueChildren(E);
2142}
2143
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002145 VisitOverloadExpr(U);
2146 if (!U->isImplicitAccess())
2147 AddStmt(U->getBase());
2148}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002150 AddStmt(E->getSubExpr());
2151 AddTypeLoc(E->getWrittenTypeInfo());
2152}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002154 WL.push_back(SizeOfPackExprParts(E, Parent));
2155}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002157 // If the opaque value has a source expression, just transparently
2158 // visit that. This is useful for (e.g.) pseudo-object expressions.
2159 if (Expr *SourceExpr = E->getSourceExpr())
2160 return Visit(SourceExpr);
2161}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002163 AddStmt(E->getBody());
2164 WL.push_back(LambdaExprParts(E, Parent));
2165}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 // Treat the expression like its syntactic form.
2168 Visit(E->getSyntacticForm());
2169}
2170
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002171void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002172 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2173}
2174
2175bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2176 if (RegionOfInterest.isValid()) {
2177 SourceRange Range = getRawCursorExtent(C);
2178 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2179 return false;
2180 }
2181 return true;
2182}
2183
2184bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2185 while (!WL.empty()) {
2186 // Dequeue the worklist item.
2187 VisitorJob LI = WL.back();
2188 WL.pop_back();
2189
2190 // Set the Parent field, then back to its old value once we're done.
2191 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2192
2193 switch (LI.getKind()) {
2194 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002195 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002196 if (!D)
2197 continue;
2198
2199 // For now, perform default visitation for Decls.
2200 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2201 cast<DeclVisit>(&LI)->isFirst())))
2202 return true;
2203
2204 continue;
2205 }
2206 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2207 const ASTTemplateArgumentListInfo *ArgList =
2208 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2209 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2210 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2211 Arg != ArgEnd; ++Arg) {
2212 if (VisitTemplateArgumentLoc(*Arg))
2213 return true;
2214 }
2215 continue;
2216 }
2217 case VisitorJob::TypeLocVisitKind: {
2218 // Perform default visitation for TypeLocs.
2219 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2220 return true;
2221 continue;
2222 }
2223 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002224 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002225 if (LabelStmt *stmt = LS->getStmt()) {
2226 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2227 TU))) {
2228 return true;
2229 }
2230 }
2231 continue;
2232 }
2233
2234 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2235 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2236 if (VisitNestedNameSpecifierLoc(V->get()))
2237 return true;
2238 continue;
2239 }
2240
2241 case VisitorJob::DeclarationNameInfoVisitKind: {
2242 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2243 ->get()))
2244 return true;
2245 continue;
2246 }
2247 case VisitorJob::MemberRefVisitKind: {
2248 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2249 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2250 return true;
2251 continue;
2252 }
2253 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002254 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002255 if (!S)
2256 continue;
2257
2258 // Update the current cursor.
2259 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2260 if (!IsInRegionOfInterest(Cursor))
2261 continue;
2262 switch (Visitor(Cursor, Parent, ClientData)) {
2263 case CXChildVisit_Break: return true;
2264 case CXChildVisit_Continue: break;
2265 case CXChildVisit_Recurse:
2266 if (PostChildrenVisitor)
2267 WL.push_back(PostChildrenVisit(0, Cursor));
2268 EnqueueWorkList(WL, S);
2269 break;
2270 }
2271 continue;
2272 }
2273 case VisitorJob::MemberExprPartsKind: {
2274 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002275 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002276
2277 // Visit the nested-name-specifier
2278 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2279 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2280 return true;
2281
2282 // Visit the declaration name.
2283 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2284 return true;
2285
2286 // Visit the explicitly-specified template arguments, if any.
2287 if (M->hasExplicitTemplateArgs()) {
2288 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2289 *ArgEnd = Arg + M->getNumTemplateArgs();
2290 Arg != ArgEnd; ++Arg) {
2291 if (VisitTemplateArgumentLoc(*Arg))
2292 return true;
2293 }
2294 }
2295 continue;
2296 }
2297 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002298 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002299 // Visit nested-name-specifier, if present.
2300 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2301 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2302 return true;
2303 // Visit declaration name.
2304 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2305 return true;
2306 continue;
2307 }
2308 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002309 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002310 // Visit the nested-name-specifier.
2311 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2312 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2313 return true;
2314 // Visit the declaration name.
2315 if (VisitDeclarationNameInfo(O->getNameInfo()))
2316 return true;
2317 // Visit the overloaded declaration reference.
2318 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2319 return true;
2320 continue;
2321 }
2322 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002323 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002324 NamedDecl *Pack = E->getPack();
2325 if (isa<TemplateTypeParmDecl>(Pack)) {
2326 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2327 E->getPackLoc(), TU)))
2328 return true;
2329
2330 continue;
2331 }
2332
2333 if (isa<TemplateTemplateParmDecl>(Pack)) {
2334 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2335 E->getPackLoc(), TU)))
2336 return true;
2337
2338 continue;
2339 }
2340
2341 // Non-type template parameter packs and function parameter packs are
2342 // treated like DeclRefExpr cursors.
2343 continue;
2344 }
2345
2346 case VisitorJob::LambdaExprPartsKind: {
2347 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002348 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002349 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2350 CEnd = E->explicit_capture_end();
2351 C != CEnd; ++C) {
2352 if (C->capturesThis())
2353 continue;
2354
2355 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2356 C->getLocation(),
2357 TU)))
2358 return true;
2359 }
2360
2361 // Visit parameters and return type, if present.
2362 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2363 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2364 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2365 // Visit the whole type.
2366 if (Visit(TL))
2367 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002368 } else if (FunctionProtoTypeLoc Proto =
2369 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002370 if (E->hasExplicitParameters()) {
2371 // Visit parameters.
2372 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2373 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2374 return true;
2375 } else {
2376 // Visit result type.
2377 if (Visit(Proto.getResultLoc()))
2378 return true;
2379 }
2380 }
2381 }
2382 break;
2383 }
2384
2385 case VisitorJob::PostChildrenVisitKind:
2386 if (PostChildrenVisitor(Parent, ClientData))
2387 return true;
2388 break;
2389 }
2390 }
2391 return false;
2392}
2393
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002394bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002395 VisitorWorkList *WL = 0;
2396 if (!WorkListFreeList.empty()) {
2397 WL = WorkListFreeList.back();
2398 WL->clear();
2399 WorkListFreeList.pop_back();
2400 }
2401 else {
2402 WL = new VisitorWorkList();
2403 WorkListCache.push_back(WL);
2404 }
2405 EnqueueWorkList(*WL, S);
2406 bool result = RunVisitorWorkList(*WL);
2407 WorkListFreeList.push_back(WL);
2408 return result;
2409}
2410
2411namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002412typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002413RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2414 const DeclarationNameInfo &NI,
2415 const SourceRange &QLoc,
2416 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2417 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2418 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2419 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2420
2421 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2422
2423 RefNamePieces Pieces;
2424
2425 if (WantQualifier && QLoc.isValid())
2426 Pieces.push_back(QLoc);
2427
2428 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2429 Pieces.push_back(NI.getLoc());
2430
2431 if (WantTemplateArgs && TemplateArgs)
2432 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2433 TemplateArgs->RAngleLoc));
2434
2435 if (Kind == DeclarationName::CXXOperatorName) {
2436 Pieces.push_back(SourceLocation::getFromRawEncoding(
2437 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2438 Pieces.push_back(SourceLocation::getFromRawEncoding(
2439 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2440 }
2441
2442 if (WantSinglePiece) {
2443 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2444 Pieces.clear();
2445 Pieces.push_back(R);
2446 }
2447
2448 return Pieces;
2449}
2450}
2451
2452//===----------------------------------------------------------------------===//
2453// Misc. API hooks.
2454//===----------------------------------------------------------------------===//
2455
2456static llvm::sys::Mutex EnableMultithreadingMutex;
2457static bool EnabledMultithreading;
2458
2459static void fatal_error_handler(void *user_data, const std::string& reason) {
2460 // Write the result out to stderr avoiding errs() because raw_ostreams can
2461 // call report_fatal_error.
2462 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2463 ::abort();
2464}
2465
2466extern "C" {
2467CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2468 int displayDiagnostics) {
2469 // Disable pretty stack trace functionality, which will otherwise be a very
2470 // poor citizen of the world and set up all sorts of signal handlers.
2471 llvm::DisablePrettyStackTrace = true;
2472
2473 // We use crash recovery to make some of our APIs more reliable, implicitly
2474 // enable it.
2475 llvm::CrashRecoveryContext::Enable();
2476
2477 // Enable support for multithreading in LLVM.
2478 {
2479 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2480 if (!EnabledMultithreading) {
2481 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2482 llvm::llvm_start_multithreaded();
2483 EnabledMultithreading = true;
2484 }
2485 }
2486
2487 CIndexer *CIdxr = new CIndexer();
2488 if (excludeDeclarationsFromPCH)
2489 CIdxr->setOnlyLocalDecls();
2490 if (displayDiagnostics)
2491 CIdxr->setDisplayDiagnostics();
2492
2493 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2494 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2495 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2496 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2497 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2498 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2499
2500 return CIdxr;
2501}
2502
2503void clang_disposeIndex(CXIndex CIdx) {
2504 if (CIdx)
2505 delete static_cast<CIndexer *>(CIdx);
2506}
2507
2508void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2509 if (CIdx)
2510 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2511}
2512
2513unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2514 if (CIdx)
2515 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2516 return 0;
2517}
2518
2519void clang_toggleCrashRecovery(unsigned isEnabled) {
2520 if (isEnabled)
2521 llvm::CrashRecoveryContext::Enable();
2522 else
2523 llvm::CrashRecoveryContext::Disable();
2524}
2525
2526CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2527 const char *ast_filename) {
2528 if (!CIdx)
2529 return 0;
2530
2531 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2532 FileSystemOptions FileSystemOpts;
2533
2534 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2535 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2536 CXXIdx->getOnlyLocalDecls(),
2537 0, 0,
2538 /*CaptureDiagnostics=*/true,
2539 /*AllowPCHWithCompilerErrors=*/true,
2540 /*UserFilesAreVolatile=*/true);
2541 return MakeCXTranslationUnit(CXXIdx, TU);
2542}
2543
2544unsigned clang_defaultEditingTranslationUnitOptions() {
2545 return CXTranslationUnit_PrecompiledPreamble |
2546 CXTranslationUnit_CacheCompletionResults;
2547}
2548
2549CXTranslationUnit
2550clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2551 const char *source_filename,
2552 int num_command_line_args,
2553 const char * const *command_line_args,
2554 unsigned num_unsaved_files,
2555 struct CXUnsavedFile *unsaved_files) {
2556 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2557 return clang_parseTranslationUnit(CIdx, source_filename,
2558 command_line_args, num_command_line_args,
2559 unsaved_files, num_unsaved_files,
2560 Options);
2561}
2562
2563struct ParseTranslationUnitInfo {
2564 CXIndex CIdx;
2565 const char *source_filename;
2566 const char *const *command_line_args;
2567 int num_command_line_args;
2568 struct CXUnsavedFile *unsaved_files;
2569 unsigned num_unsaved_files;
2570 unsigned options;
2571 CXTranslationUnit result;
2572};
2573static void clang_parseTranslationUnit_Impl(void *UserData) {
2574 ParseTranslationUnitInfo *PTUI =
2575 static_cast<ParseTranslationUnitInfo*>(UserData);
2576 CXIndex CIdx = PTUI->CIdx;
2577 const char *source_filename = PTUI->source_filename;
2578 const char * const *command_line_args = PTUI->command_line_args;
2579 int num_command_line_args = PTUI->num_command_line_args;
2580 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2581 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2582 unsigned options = PTUI->options;
2583 PTUI->result = 0;
2584
2585 if (!CIdx)
2586 return;
2587
2588 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2589
2590 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2591 setThreadBackgroundPriority();
2592
2593 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2594 // FIXME: Add a flag for modules.
2595 TranslationUnitKind TUKind
2596 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2597 bool CacheCodeCompetionResults
2598 = options & CXTranslationUnit_CacheCompletionResults;
2599 bool IncludeBriefCommentsInCodeCompletion
2600 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2601 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2602 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2603
2604 // Configure the diagnostics.
2605 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002606 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002607
2608 // Recover resources if we crash before exiting this function.
2609 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2610 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2611 DiagCleanup(Diags.getPtr());
2612
2613 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2614 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2615
2616 // Recover resources if we crash before exiting this function.
2617 llvm::CrashRecoveryContextCleanupRegistrar<
2618 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2619
2620 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2621 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2622 const llvm::MemoryBuffer *Buffer
2623 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2624 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2625 Buffer));
2626 }
2627
2628 OwningPtr<std::vector<const char *> >
2629 Args(new std::vector<const char*>());
2630
2631 // Recover resources if we crash before exiting this method.
2632 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2633 ArgsCleanup(Args.get());
2634
2635 // Since the Clang C library is primarily used by batch tools dealing with
2636 // (often very broken) source code, where spell-checking can have a
2637 // significant negative impact on performance (particularly when
2638 // precompiled headers are involved), we disable it by default.
2639 // Only do this if we haven't found a spell-checking-related argument.
2640 bool FoundSpellCheckingArgument = false;
2641 for (int I = 0; I != num_command_line_args; ++I) {
2642 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2643 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2644 FoundSpellCheckingArgument = true;
2645 break;
2646 }
2647 }
2648 if (!FoundSpellCheckingArgument)
2649 Args->push_back("-fno-spell-checking");
2650
2651 Args->insert(Args->end(), command_line_args,
2652 command_line_args + num_command_line_args);
2653
2654 // The 'source_filename' argument is optional. If the caller does not
2655 // specify it then it is assumed that the source file is specified
2656 // in the actual argument list.
2657 // Put the source file after command_line_args otherwise if '-x' flag is
2658 // present it will be unused.
2659 if (source_filename)
2660 Args->push_back(source_filename);
2661
2662 // Do we need the detailed preprocessing record?
2663 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2664 Args->push_back("-Xclang");
2665 Args->push_back("-detailed-preprocessing-record");
2666 }
2667
2668 unsigned NumErrors = Diags->getClient()->getNumErrors();
2669 OwningPtr<ASTUnit> ErrUnit;
2670 OwningPtr<ASTUnit> Unit(
2671 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2672 /* vector::data() not portable */,
2673 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2674 Diags,
2675 CXXIdx->getClangResourcesPath(),
2676 CXXIdx->getOnlyLocalDecls(),
2677 /*CaptureDiagnostics=*/true,
2678 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2679 RemappedFiles->size(),
2680 /*RemappedFilesKeepOriginalName=*/true,
2681 PrecompilePreamble,
2682 TUKind,
2683 CacheCodeCompetionResults,
2684 IncludeBriefCommentsInCodeCompletion,
2685 /*AllowPCHWithCompilerErrors=*/true,
2686 SkipFunctionBodies,
2687 /*UserFilesAreVolatile=*/true,
2688 ForSerialization,
2689 &ErrUnit));
2690
2691 if (NumErrors != Diags->getClient()->getNumErrors()) {
2692 // Make sure to check that 'Unit' is non-NULL.
2693 if (CXXIdx->getDisplayDiagnostics())
2694 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2695 }
2696
2697 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2698}
2699CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2700 const char *source_filename,
2701 const char * const *command_line_args,
2702 int num_command_line_args,
2703 struct CXUnsavedFile *unsaved_files,
2704 unsigned num_unsaved_files,
2705 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002706 LOG_FUNC_SECTION {
2707 *Log << source_filename << ": ";
2708 for (int i = 0; i != num_command_line_args; ++i)
2709 *Log << command_line_args[i] << " ";
2710 }
2711
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002712 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2713 num_command_line_args, unsaved_files,
2714 num_unsaved_files, options, 0 };
2715 llvm::CrashRecoveryContext CRC;
2716
2717 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2718 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2719 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2720 fprintf(stderr, " 'command_line_args' : [");
2721 for (int i = 0; i != num_command_line_args; ++i) {
2722 if (i)
2723 fprintf(stderr, ", ");
2724 fprintf(stderr, "'%s'", command_line_args[i]);
2725 }
2726 fprintf(stderr, "],\n");
2727 fprintf(stderr, " 'unsaved_files' : [");
2728 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2729 if (i)
2730 fprintf(stderr, ", ");
2731 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2732 unsaved_files[i].Length);
2733 }
2734 fprintf(stderr, "],\n");
2735 fprintf(stderr, " 'options' : %d,\n", options);
2736 fprintf(stderr, "}\n");
2737
2738 return 0;
2739 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2740 PrintLibclangResourceUsage(PTUI.result);
2741 }
2742
2743 return PTUI.result;
2744}
2745
2746unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2747 return CXSaveTranslationUnit_None;
2748}
2749
2750namespace {
2751
2752struct SaveTranslationUnitInfo {
2753 CXTranslationUnit TU;
2754 const char *FileName;
2755 unsigned options;
2756 CXSaveError result;
2757};
2758
2759}
2760
2761static void clang_saveTranslationUnit_Impl(void *UserData) {
2762 SaveTranslationUnitInfo *STUI =
2763 static_cast<SaveTranslationUnitInfo*>(UserData);
2764
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002765 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002766 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2767 setThreadBackgroundPriority();
2768
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002769 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002770 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2771}
2772
2773int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2774 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002775 LOG_FUNC_SECTION {
2776 *Log << TU << ' ' << FileName;
2777 }
2778
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002779 if (!TU)
2780 return CXSaveError_InvalidTU;
2781
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002782 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002783 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2784 if (!CXXUnit->hasSema())
2785 return CXSaveError_InvalidTU;
2786
2787 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2788
2789 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2790 getenv("LIBCLANG_NOTHREADS")) {
2791 clang_saveTranslationUnit_Impl(&STUI);
2792
2793 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2794 PrintLibclangResourceUsage(TU);
2795
2796 return STUI.result;
2797 }
2798
2799 // We have an AST that has invalid nodes due to compiler errors.
2800 // Use a crash recovery thread for protection.
2801
2802 llvm::CrashRecoveryContext CRC;
2803
2804 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2805 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2806 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2807 fprintf(stderr, " 'options' : %d,\n", options);
2808 fprintf(stderr, "}\n");
2809
2810 return CXSaveError_Unknown;
2811
2812 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2813 PrintLibclangResourceUsage(TU);
2814 }
2815
2816 return STUI.result;
2817}
2818
2819void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2820 if (CTUnit) {
2821 // If the translation unit has been marked as unsafe to free, just discard
2822 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002823 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002824 return;
2825
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002826 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002827 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002828 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2829 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002830 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002831 delete CTUnit;
2832 }
2833}
2834
2835unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2836 return CXReparse_None;
2837}
2838
2839struct ReparseTranslationUnitInfo {
2840 CXTranslationUnit TU;
2841 unsigned num_unsaved_files;
2842 struct CXUnsavedFile *unsaved_files;
2843 unsigned options;
2844 int result;
2845};
2846
2847static void clang_reparseTranslationUnit_Impl(void *UserData) {
2848 ReparseTranslationUnitInfo *RTUI =
2849 static_cast<ReparseTranslationUnitInfo*>(UserData);
2850 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002851 if (!TU)
2852 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002853
2854 // Reset the associated diagnostics.
2855 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2856 TU->Diagnostics = 0;
2857
2858 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2859 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2860 unsigned options = RTUI->options;
2861 (void) options;
2862 RTUI->result = 1;
2863
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002864 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002865 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2866 setThreadBackgroundPriority();
2867
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002868 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002869 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2870
2871 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2872 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2873
2874 // Recover resources if we crash before exiting this function.
2875 llvm::CrashRecoveryContextCleanupRegistrar<
2876 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2877
2878 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2879 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2880 const llvm::MemoryBuffer *Buffer
2881 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2882 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2883 Buffer));
2884 }
2885
2886 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2887 RemappedFiles->size()))
2888 RTUI->result = 0;
2889}
2890
2891int clang_reparseTranslationUnit(CXTranslationUnit TU,
2892 unsigned num_unsaved_files,
2893 struct CXUnsavedFile *unsaved_files,
2894 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002895 LOG_FUNC_SECTION {
2896 *Log << TU;
2897 }
2898
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002899 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2900 options, 0 };
2901
2902 if (getenv("LIBCLANG_NOTHREADS")) {
2903 clang_reparseTranslationUnit_Impl(&RTUI);
2904 return RTUI.result;
2905 }
2906
2907 llvm::CrashRecoveryContext CRC;
2908
2909 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2910 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002911 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002912 return 1;
2913 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2914 PrintLibclangResourceUsage(TU);
2915
2916 return RTUI.result;
2917}
2918
2919
2920CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2921 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002922 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002923
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002924 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002925 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002926}
2927
2928CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002929 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002930 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2931}
2932
2933} // end: extern "C"
2934
2935//===----------------------------------------------------------------------===//
2936// CXFile Operations.
2937//===----------------------------------------------------------------------===//
2938
2939extern "C" {
2940CXString clang_getFileName(CXFile SFile) {
2941 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002942 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002943
2944 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002945 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002946}
2947
2948time_t clang_getFileTime(CXFile SFile) {
2949 if (!SFile)
2950 return 0;
2951
2952 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2953 return FEnt->getModificationTime();
2954}
2955
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002956CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2957 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002958 return 0;
2959
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002960 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002961
2962 FileManager &FMgr = CXXUnit->getFileManager();
2963 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2964}
2965
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002966unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2967 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002968 return 0;
2969
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002970 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002971 FileEntry *FEnt = static_cast<FileEntry *>(file);
2972 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2973 .isFileMultipleIncludeGuarded(FEnt);
2974}
2975
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002976int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2977 if (!file || !outID)
2978 return 1;
2979
2980#ifdef LLVM_ON_WIN32
2981 return 1; // inodes not supported on windows.
2982#else
2983 FileEntry *FEnt = static_cast<FileEntry *>(file);
2984 outID->data[0] = FEnt->getDevice();
2985 outID->data[1] = FEnt->getInode();
2986 outID->data[2] = FEnt->getModificationTime();
2987 return 0;
2988#endif
2989}
2990
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002991} // end: extern "C"
2992
2993//===----------------------------------------------------------------------===//
2994// CXCursor Operations.
2995//===----------------------------------------------------------------------===//
2996
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002997static const Decl *getDeclFromExpr(const Stmt *E) {
2998 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002999 return getDeclFromExpr(CE->getSubExpr());
3000
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003001 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003002 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003003 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003004 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003005 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003006 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003007 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003008 if (PRE->isExplicitProperty())
3009 return PRE->getExplicitProperty();
3010 // It could be messaging both getter and setter as in:
3011 // ++myobj.myprop;
3012 // in which case prefer to associate the setter since it is less obvious
3013 // from inspecting the source that the setter is going to get called.
3014 if (PRE->isMessagingSetter())
3015 return PRE->getImplicitPropertySetter();
3016 return PRE->getImplicitPropertyGetter();
3017 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003018 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003019 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003020 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003021 if (Expr *Src = OVE->getSourceExpr())
3022 return getDeclFromExpr(Src);
3023
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003024 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003025 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003026 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003027 if (!CE->isElidable())
3028 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003029 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003030 return OME->getMethodDecl();
3031
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003032 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003033 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003034 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003035 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3036 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003037 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003038 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3039 isa<ParmVarDecl>(SizeOfPack->getPack()))
3040 return SizeOfPack->getPack();
3041
3042 return 0;
3043}
3044
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003045static SourceLocation getLocationFromExpr(const Expr *E) {
3046 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003047 return getLocationFromExpr(CE->getSubExpr());
3048
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003049 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003050 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003051 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003052 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003053 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003054 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003055 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003056 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003057 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003058 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003059 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003060 return PropRef->getLocation();
3061
3062 return E->getLocStart();
3063}
3064
3065extern "C" {
3066
3067unsigned clang_visitChildren(CXCursor parent,
3068 CXCursorVisitor visitor,
3069 CXClientData client_data) {
3070 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3071 /*VisitPreprocessorLast=*/false);
3072 return CursorVis.VisitChildren(parent);
3073}
3074
3075#ifndef __has_feature
3076#define __has_feature(x) 0
3077#endif
3078#if __has_feature(blocks)
3079typedef enum CXChildVisitResult
3080 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3081
3082static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3083 CXClientData client_data) {
3084 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3085 return block(cursor, parent);
3086}
3087#else
3088// If we are compiled with a compiler that doesn't have native blocks support,
3089// define and call the block manually, so the
3090typedef struct _CXChildVisitResult
3091{
3092 void *isa;
3093 int flags;
3094 int reserved;
3095 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3096 CXCursor);
3097} *CXCursorVisitorBlock;
3098
3099static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3100 CXClientData client_data) {
3101 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3102 return block->invoke(block, cursor, parent);
3103}
3104#endif
3105
3106
3107unsigned clang_visitChildrenWithBlock(CXCursor parent,
3108 CXCursorVisitorBlock block) {
3109 return clang_visitChildren(parent, visitWithBlock, block);
3110}
3111
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003112static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003113 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003114 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003115
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003116 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003117 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003118 if (const ObjCPropertyImplDecl *PropImpl =
3119 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003120 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003121 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003122
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003123 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003124 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003125 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003126
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003127 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003128 }
3129
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003130 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003131 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003132
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003133 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003134 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3135 // and returns different names. NamedDecl returns the class name and
3136 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003137 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003138
3139 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003140 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003141
3142 SmallString<1024> S;
3143 llvm::raw_svector_ostream os(S);
3144 ND->printName(os);
3145
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003146 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003147}
3148
3149CXString clang_getCursorSpelling(CXCursor C) {
3150 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003151 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003152
3153 if (clang_isReference(C.kind)) {
3154 switch (C.kind) {
3155 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003156 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003157 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003158 }
3159 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003160 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003161 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003162 }
3163 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003164 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003165 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003166 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003167 }
3168 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003169 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003170 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003171 }
3172 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003173 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003174 assert(Type && "Missing type decl");
3175
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003176 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003177 getAsString());
3178 }
3179 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003180 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003181 assert(Template && "Missing template decl");
3182
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003183 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003184 }
3185
3186 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003187 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003188 assert(NS && "Missing namespace decl");
3189
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003190 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003191 }
3192
3193 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003194 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195 assert(Field && "Missing member decl");
3196
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003197 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003198 }
3199
3200 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003201 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003202 assert(Label && "Missing label");
3203
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003204 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205 }
3206
3207 case CXCursor_OverloadedDeclRef: {
3208 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003209 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3210 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003211 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003212 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003213 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003214 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003215 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003216 OverloadedTemplateStorage *Ovl
3217 = Storage.get<OverloadedTemplateStorage*>();
3218 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003219 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003220 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003221 }
3222
3223 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003224 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003225 assert(Var && "Missing variable decl");
3226
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003227 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003228 }
3229
3230 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003231 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003232 }
3233 }
3234
3235 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003236 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003237 if (D)
3238 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003239 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003240 }
3241
3242 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003243 const Stmt *S = getCursorStmt(C);
3244 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003245 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003247 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003248 }
3249
3250 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003251 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003252 ->getNameStart());
3253
3254 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003255 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003256 ->getNameStart());
3257
3258 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003259 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003260
3261 if (clang_isDeclaration(C.kind))
3262 return getDeclSpelling(getCursorDecl(C));
3263
3264 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003265 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003266 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003267 }
3268
3269 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003270 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003271 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003272 }
3273
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003274 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003275}
3276
3277CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3278 unsigned pieceIndex,
3279 unsigned options) {
3280 if (clang_Cursor_isNull(C))
3281 return clang_getNullRange();
3282
3283 ASTContext &Ctx = getCursorContext(C);
3284
3285 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003286 const Stmt *S = getCursorStmt(C);
3287 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003288 if (pieceIndex > 0)
3289 return clang_getNullRange();
3290 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3291 }
3292
3293 return clang_getNullRange();
3294 }
3295
3296 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003297 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003298 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3299 if (pieceIndex >= ME->getNumSelectorLocs())
3300 return clang_getNullRange();
3301 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3302 }
3303 }
3304
3305 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3306 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003307 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003308 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3309 if (pieceIndex >= MD->getNumSelectorLocs())
3310 return clang_getNullRange();
3311 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3312 }
3313 }
3314
3315 if (C.kind == CXCursor_ObjCCategoryDecl ||
3316 C.kind == CXCursor_ObjCCategoryImplDecl) {
3317 if (pieceIndex > 0)
3318 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003319 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003320 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3321 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003322 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003323 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3324 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3325 }
3326
3327 if (C.kind == CXCursor_ModuleImportDecl) {
3328 if (pieceIndex > 0)
3329 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003330 if (const ImportDecl *ImportD =
3331 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003332 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3333 if (!Locs.empty())
3334 return cxloc::translateSourceRange(Ctx,
3335 SourceRange(Locs.front(), Locs.back()));
3336 }
3337 return clang_getNullRange();
3338 }
3339
3340 // FIXME: A CXCursor_InclusionDirective should give the location of the
3341 // filename, but we don't keep track of this.
3342
3343 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3344 // but we don't keep track of this.
3345
3346 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3347 // but we don't keep track of this.
3348
3349 // Default handling, give the location of the cursor.
3350
3351 if (pieceIndex > 0)
3352 return clang_getNullRange();
3353
3354 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3355 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3356 return cxloc::translateSourceRange(Ctx, Loc);
3357}
3358
3359CXString clang_getCursorDisplayName(CXCursor C) {
3360 if (!clang_isDeclaration(C.kind))
3361 return clang_getCursorSpelling(C);
3362
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003363 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003364 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003365 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003366
3367 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003368 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003369 D = FunTmpl->getTemplatedDecl();
3370
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003371 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003372 SmallString<64> Str;
3373 llvm::raw_svector_ostream OS(Str);
3374 OS << *Function;
3375 if (Function->getPrimaryTemplate())
3376 OS << "<>";
3377 OS << "(";
3378 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3379 if (I)
3380 OS << ", ";
3381 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3382 }
3383
3384 if (Function->isVariadic()) {
3385 if (Function->getNumParams())
3386 OS << ", ";
3387 OS << "...";
3388 }
3389 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003390 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003391 }
3392
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003393 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003394 SmallString<64> Str;
3395 llvm::raw_svector_ostream OS(Str);
3396 OS << *ClassTemplate;
3397 OS << "<";
3398 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3399 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3400 if (I)
3401 OS << ", ";
3402
3403 NamedDecl *Param = Params->getParam(I);
3404 if (Param->getIdentifier()) {
3405 OS << Param->getIdentifier()->getName();
3406 continue;
3407 }
3408
3409 // There is no parameter name, which makes this tricky. Try to come up
3410 // with something useful that isn't too long.
3411 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3412 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3413 else if (NonTypeTemplateParmDecl *NTTP
3414 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3415 OS << NTTP->getType().getAsString(Policy);
3416 else
3417 OS << "template<...> class";
3418 }
3419
3420 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003421 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003422 }
3423
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003424 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003425 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3426 // If the type was explicitly written, use that.
3427 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003428 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003429
Benjamin Kramer5eada842013-02-22 15:46:01 +00003430 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003431 llvm::raw_svector_ostream OS(Str);
3432 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003433 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003434 ClassSpec->getTemplateArgs().data(),
3435 ClassSpec->getTemplateArgs().size(),
3436 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003437 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003438 }
3439
3440 return clang_getCursorSpelling(C);
3441}
3442
3443CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3444 switch (Kind) {
3445 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003446 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003447 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003448 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003449 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003450 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003452 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003453 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003454 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003455 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003456 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003457 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003458 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003459 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003460 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003461 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003462 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003463 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003464 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003465 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003466 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003467 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003468 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003469 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003470 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003472 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003474 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("ObjCBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 }
3738
3739 llvm_unreachable("Unhandled CXCursorKind");
3740}
3741
3742struct GetCursorData {
3743 SourceLocation TokenBeginLoc;
3744 bool PointsAtMacroArgExpansion;
3745 bool VisitedObjCPropertyImplDecl;
3746 SourceLocation VisitedDeclaratorDeclStartLoc;
3747 CXCursor &BestCursor;
3748
3749 GetCursorData(SourceManager &SM,
3750 SourceLocation tokenBegin, CXCursor &outputCursor)
3751 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3752 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3753 VisitedObjCPropertyImplDecl = false;
3754 }
3755};
3756
3757static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3758 CXCursor parent,
3759 CXClientData client_data) {
3760 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3761 CXCursor *BestCursor = &Data->BestCursor;
3762
3763 // If we point inside a macro argument we should provide info of what the
3764 // token is so use the actual cursor, don't replace it with a macro expansion
3765 // cursor.
3766 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3767 return CXChildVisit_Recurse;
3768
3769 if (clang_isDeclaration(cursor.kind)) {
3770 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003771 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003772 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3773 if (MD->isImplicit())
3774 return CXChildVisit_Break;
3775
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003776 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003777 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3778 // Check that when we have multiple @class references in the same line,
3779 // that later ones do not override the previous ones.
3780 // If we have:
3781 // @class Foo, Bar;
3782 // source ranges for both start at '@', so 'Bar' will end up overriding
3783 // 'Foo' even though the cursor location was at 'Foo'.
3784 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3785 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003786 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003787 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3788 if (PrevID != ID &&
3789 !PrevID->isThisDeclarationADefinition() &&
3790 !ID->isThisDeclarationADefinition())
3791 return CXChildVisit_Break;
3792 }
3793
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003794 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003795 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3796 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3797 // Check that when we have multiple declarators in the same line,
3798 // that later ones do not override the previous ones.
3799 // If we have:
3800 // int Foo, Bar;
3801 // source ranges for both start at 'int', so 'Bar' will end up overriding
3802 // 'Foo' even though the cursor location was at 'Foo'.
3803 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3804 return CXChildVisit_Break;
3805 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3806
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003807 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003808 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3809 (void)PropImp;
3810 // Check that when we have multiple @synthesize in the same line,
3811 // that later ones do not override the previous ones.
3812 // If we have:
3813 // @synthesize Foo, Bar;
3814 // source ranges for both start at '@', so 'Bar' will end up overriding
3815 // 'Foo' even though the cursor location was at 'Foo'.
3816 if (Data->VisitedObjCPropertyImplDecl)
3817 return CXChildVisit_Break;
3818 Data->VisitedObjCPropertyImplDecl = true;
3819 }
3820 }
3821
3822 if (clang_isExpression(cursor.kind) &&
3823 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003824 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003825 // Avoid having the cursor of an expression replace the declaration cursor
3826 // when the expression source range overlaps the declaration range.
3827 // This can happen for C++ constructor expressions whose range generally
3828 // include the variable declaration, e.g.:
3829 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3830 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3831 D->getLocation() == Data->TokenBeginLoc)
3832 return CXChildVisit_Break;
3833 }
3834 }
3835
3836 // If our current best cursor is the construction of a temporary object,
3837 // don't replace that cursor with a type reference, because we want
3838 // clang_getCursor() to point at the constructor.
3839 if (clang_isExpression(BestCursor->kind) &&
3840 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3841 cursor.kind == CXCursor_TypeRef) {
3842 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3843 // as having the actual point on the type reference.
3844 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3845 return CXChildVisit_Recurse;
3846 }
3847
3848 *BestCursor = cursor;
3849 return CXChildVisit_Recurse;
3850}
3851
3852CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3853 if (!TU)
3854 return clang_getNullCursor();
3855
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003856 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003857 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3858
3859 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3860 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3861
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003862 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003863 CXFile SearchFile;
3864 unsigned SearchLine, SearchColumn;
3865 CXFile ResultFile;
3866 unsigned ResultLine, ResultColumn;
3867 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3868 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3869 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3870
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003871 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3872 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003873 &ResultColumn, 0);
3874 SearchFileName = clang_getFileName(SearchFile);
3875 ResultFileName = clang_getFileName(ResultFile);
3876 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3877 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003878 *Log << llvm::format("(%s:%d:%d) = %s",
3879 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3880 clang_getCString(KindSpelling))
3881 << llvm::format("(%s:%d:%d):%s%s",
3882 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3883 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003884 clang_disposeString(SearchFileName);
3885 clang_disposeString(ResultFileName);
3886 clang_disposeString(KindSpelling);
3887 clang_disposeString(USR);
3888
3889 CXCursor Definition = clang_getCursorDefinition(Result);
3890 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3891 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3892 CXString DefinitionKindSpelling
3893 = clang_getCursorKindSpelling(Definition.kind);
3894 CXFile DefinitionFile;
3895 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003896 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003897 &DefinitionLine, &DefinitionColumn, 0);
3898 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003899 *Log << llvm::format(" -> %s(%s:%d:%d)",
3900 clang_getCString(DefinitionKindSpelling),
3901 clang_getCString(DefinitionFileName),
3902 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003903 clang_disposeString(DefinitionFileName);
3904 clang_disposeString(DefinitionKindSpelling);
3905 }
3906 }
3907
3908 return Result;
3909}
3910
3911CXCursor clang_getNullCursor(void) {
3912 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3913}
3914
3915unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003916 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3917 // can't set consistently. For example, when visiting a DeclStmt we will set
3918 // it but we don't set it on the result of clang_getCursorDefinition for
3919 // a reference of the same declaration.
3920 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3921 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3922 // to provide that kind of info.
3923 if (clang_isDeclaration(X.kind))
3924 X.data[1] = 0;
3925 if (clang_isDeclaration(Y.kind))
3926 Y.data[1] = 0;
3927
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003928 return X == Y;
3929}
3930
3931unsigned clang_hashCursor(CXCursor C) {
3932 unsigned Index = 0;
3933 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3934 Index = 1;
3935
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003936 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003937 std::make_pair(C.kind, C.data[Index]));
3938}
3939
3940unsigned clang_isInvalid(enum CXCursorKind K) {
3941 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3942}
3943
3944unsigned clang_isDeclaration(enum CXCursorKind K) {
3945 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3946 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3947}
3948
3949unsigned clang_isReference(enum CXCursorKind K) {
3950 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3951}
3952
3953unsigned clang_isExpression(enum CXCursorKind K) {
3954 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3955}
3956
3957unsigned clang_isStatement(enum CXCursorKind K) {
3958 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3959}
3960
3961unsigned clang_isAttribute(enum CXCursorKind K) {
3962 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3963}
3964
3965unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3966 return K == CXCursor_TranslationUnit;
3967}
3968
3969unsigned clang_isPreprocessing(enum CXCursorKind K) {
3970 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3971}
3972
3973unsigned clang_isUnexposed(enum CXCursorKind K) {
3974 switch (K) {
3975 case CXCursor_UnexposedDecl:
3976 case CXCursor_UnexposedExpr:
3977 case CXCursor_UnexposedStmt:
3978 case CXCursor_UnexposedAttr:
3979 return true;
3980 default:
3981 return false;
3982 }
3983}
3984
3985CXCursorKind clang_getCursorKind(CXCursor C) {
3986 return C.kind;
3987}
3988
3989CXSourceLocation clang_getCursorLocation(CXCursor C) {
3990 if (clang_isReference(C.kind)) {
3991 switch (C.kind) {
3992 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003993 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003994 = getCursorObjCSuperClassRef(C);
3995 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3996 }
3997
3998 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003999 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004000 = getCursorObjCProtocolRef(C);
4001 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4002 }
4003
4004 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004005 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004006 = getCursorObjCClassRef(C);
4007 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4008 }
4009
4010 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004011 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004012 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4013 }
4014
4015 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004016 std::pair<const TemplateDecl *, SourceLocation> P =
4017 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004018 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4019 }
4020
4021 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004022 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004023 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4024 }
4025
4026 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004027 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004028 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4029 }
4030
4031 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004032 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004033 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4034 }
4035
4036 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004037 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004038 if (!BaseSpec)
4039 return clang_getNullLocation();
4040
4041 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4042 return cxloc::translateSourceLocation(getCursorContext(C),
4043 TSInfo->getTypeLoc().getBeginLoc());
4044
4045 return cxloc::translateSourceLocation(getCursorContext(C),
4046 BaseSpec->getLocStart());
4047 }
4048
4049 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004050 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004051 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4052 }
4053
4054 case CXCursor_OverloadedDeclRef:
4055 return cxloc::translateSourceLocation(getCursorContext(C),
4056 getCursorOverloadedDeclRef(C).second);
4057
4058 default:
4059 // FIXME: Need a way to enumerate all non-reference cases.
4060 llvm_unreachable("Missed a reference kind");
4061 }
4062 }
4063
4064 if (clang_isExpression(C.kind))
4065 return cxloc::translateSourceLocation(getCursorContext(C),
4066 getLocationFromExpr(getCursorExpr(C)));
4067
4068 if (clang_isStatement(C.kind))
4069 return cxloc::translateSourceLocation(getCursorContext(C),
4070 getCursorStmt(C)->getLocStart());
4071
4072 if (C.kind == CXCursor_PreprocessingDirective) {
4073 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4074 return cxloc::translateSourceLocation(getCursorContext(C), L);
4075 }
4076
4077 if (C.kind == CXCursor_MacroExpansion) {
4078 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004079 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004080 return cxloc::translateSourceLocation(getCursorContext(C), L);
4081 }
4082
4083 if (C.kind == CXCursor_MacroDefinition) {
4084 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4085 return cxloc::translateSourceLocation(getCursorContext(C), L);
4086 }
4087
4088 if (C.kind == CXCursor_InclusionDirective) {
4089 SourceLocation L
4090 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4091 return cxloc::translateSourceLocation(getCursorContext(C), L);
4092 }
4093
4094 if (!clang_isDeclaration(C.kind))
4095 return clang_getNullLocation();
4096
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004097 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004098 if (!D)
4099 return clang_getNullLocation();
4100
4101 SourceLocation Loc = D->getLocation();
4102 // FIXME: Multiple variables declared in a single declaration
4103 // currently lack the information needed to correctly determine their
4104 // ranges when accounting for the type-specifier. We use context
4105 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4106 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004107 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004108 if (!cxcursor::isFirstInDeclGroup(C))
4109 Loc = VD->getLocation();
4110 }
4111
4112 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004113 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004114 Loc = MD->getSelectorStartLoc();
4115
4116 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4117}
4118
4119} // end extern "C"
4120
4121CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4122 assert(TU);
4123
4124 // Guard against an invalid SourceLocation, or we may assert in one
4125 // of the following calls.
4126 if (SLoc.isInvalid())
4127 return clang_getNullCursor();
4128
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004129 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004130
4131 // Translate the given source location to make it point at the beginning of
4132 // the token under the cursor.
4133 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4134 CXXUnit->getASTContext().getLangOpts());
4135
4136 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4137 if (SLoc.isValid()) {
4138 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4139 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4140 /*VisitPreprocessorLast=*/true,
4141 /*VisitIncludedEntities=*/false,
4142 SourceLocation(SLoc));
4143 CursorVis.visitFileRegion();
4144 }
4145
4146 return Result;
4147}
4148
4149static SourceRange getRawCursorExtent(CXCursor C) {
4150 if (clang_isReference(C.kind)) {
4151 switch (C.kind) {
4152 case CXCursor_ObjCSuperClassRef:
4153 return getCursorObjCSuperClassRef(C).second;
4154
4155 case CXCursor_ObjCProtocolRef:
4156 return getCursorObjCProtocolRef(C).second;
4157
4158 case CXCursor_ObjCClassRef:
4159 return getCursorObjCClassRef(C).second;
4160
4161 case CXCursor_TypeRef:
4162 return getCursorTypeRef(C).second;
4163
4164 case CXCursor_TemplateRef:
4165 return getCursorTemplateRef(C).second;
4166
4167 case CXCursor_NamespaceRef:
4168 return getCursorNamespaceRef(C).second;
4169
4170 case CXCursor_MemberRef:
4171 return getCursorMemberRef(C).second;
4172
4173 case CXCursor_CXXBaseSpecifier:
4174 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4175
4176 case CXCursor_LabelRef:
4177 return getCursorLabelRef(C).second;
4178
4179 case CXCursor_OverloadedDeclRef:
4180 return getCursorOverloadedDeclRef(C).second;
4181
4182 case CXCursor_VariableRef:
4183 return getCursorVariableRef(C).second;
4184
4185 default:
4186 // FIXME: Need a way to enumerate all non-reference cases.
4187 llvm_unreachable("Missed a reference kind");
4188 }
4189 }
4190
4191 if (clang_isExpression(C.kind))
4192 return getCursorExpr(C)->getSourceRange();
4193
4194 if (clang_isStatement(C.kind))
4195 return getCursorStmt(C)->getSourceRange();
4196
4197 if (clang_isAttribute(C.kind))
4198 return getCursorAttr(C)->getRange();
4199
4200 if (C.kind == CXCursor_PreprocessingDirective)
4201 return cxcursor::getCursorPreprocessingDirective(C);
4202
4203 if (C.kind == CXCursor_MacroExpansion) {
4204 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004205 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004206 return TU->mapRangeFromPreamble(Range);
4207 }
4208
4209 if (C.kind == CXCursor_MacroDefinition) {
4210 ASTUnit *TU = getCursorASTUnit(C);
4211 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4212 return TU->mapRangeFromPreamble(Range);
4213 }
4214
4215 if (C.kind == CXCursor_InclusionDirective) {
4216 ASTUnit *TU = getCursorASTUnit(C);
4217 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4218 return TU->mapRangeFromPreamble(Range);
4219 }
4220
4221 if (C.kind == CXCursor_TranslationUnit) {
4222 ASTUnit *TU = getCursorASTUnit(C);
4223 FileID MainID = TU->getSourceManager().getMainFileID();
4224 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4225 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4226 return SourceRange(Start, End);
4227 }
4228
4229 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004230 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004231 if (!D)
4232 return SourceRange();
4233
4234 SourceRange R = D->getSourceRange();
4235 // FIXME: Multiple variables declared in a single declaration
4236 // currently lack the information needed to correctly determine their
4237 // ranges when accounting for the type-specifier. We use context
4238 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4239 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004240 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004241 if (!cxcursor::isFirstInDeclGroup(C))
4242 R.setBegin(VD->getLocation());
4243 }
4244 return R;
4245 }
4246 return SourceRange();
4247}
4248
4249/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4250/// the decl-specifier-seq for declarations.
4251static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4252 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004253 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004254 if (!D)
4255 return SourceRange();
4256
4257 SourceRange R = D->getSourceRange();
4258
4259 // Adjust the start of the location for declarations preceded by
4260 // declaration specifiers.
4261 SourceLocation StartLoc;
4262 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4263 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4264 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004265 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004266 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4267 StartLoc = TI->getTypeLoc().getLocStart();
4268 }
4269
4270 if (StartLoc.isValid() && R.getBegin().isValid() &&
4271 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4272 R.setBegin(StartLoc);
4273
4274 // FIXME: Multiple variables declared in a single declaration
4275 // currently lack the information needed to correctly determine their
4276 // ranges when accounting for the type-specifier. We use context
4277 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4278 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004279 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004280 if (!cxcursor::isFirstInDeclGroup(C))
4281 R.setBegin(VD->getLocation());
4282 }
4283
4284 return R;
4285 }
4286
4287 return getRawCursorExtent(C);
4288}
4289
4290extern "C" {
4291
4292CXSourceRange clang_getCursorExtent(CXCursor C) {
4293 SourceRange R = getRawCursorExtent(C);
4294 if (R.isInvalid())
4295 return clang_getNullRange();
4296
4297 return cxloc::translateSourceRange(getCursorContext(C), R);
4298}
4299
4300CXCursor clang_getCursorReferenced(CXCursor C) {
4301 if (clang_isInvalid(C.kind))
4302 return clang_getNullCursor();
4303
4304 CXTranslationUnit tu = getCursorTU(C);
4305 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004306 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004307 if (!D)
4308 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004309 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004310 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004311 if (const ObjCPropertyImplDecl *PropImpl =
4312 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004313 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4314 return MakeCXCursor(Property, tu);
4315
4316 return C;
4317 }
4318
4319 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004320 const Expr *E = getCursorExpr(C);
4321 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004322 if (D) {
4323 CXCursor declCursor = MakeCXCursor(D, tu);
4324 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4325 declCursor);
4326 return declCursor;
4327 }
4328
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004329 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004330 return MakeCursorOverloadedDeclRef(Ovl, tu);
4331
4332 return clang_getNullCursor();
4333 }
4334
4335 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004336 const Stmt *S = getCursorStmt(C);
4337 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004338 if (LabelDecl *label = Goto->getLabel())
4339 if (LabelStmt *labelS = label->getStmt())
4340 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4341
4342 return clang_getNullCursor();
4343 }
4344
4345 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004346 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004347 return MakeMacroDefinitionCursor(Def, tu);
4348 }
4349
4350 if (!clang_isReference(C.kind))
4351 return clang_getNullCursor();
4352
4353 switch (C.kind) {
4354 case CXCursor_ObjCSuperClassRef:
4355 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4356
4357 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004358 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4359 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004360 return MakeCXCursor(Def, tu);
4361
4362 return MakeCXCursor(Prot, tu);
4363 }
4364
4365 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004366 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4367 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004368 return MakeCXCursor(Def, tu);
4369
4370 return MakeCXCursor(Class, tu);
4371 }
4372
4373 case CXCursor_TypeRef:
4374 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4375
4376 case CXCursor_TemplateRef:
4377 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4378
4379 case CXCursor_NamespaceRef:
4380 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4381
4382 case CXCursor_MemberRef:
4383 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4384
4385 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004386 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004387 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4388 tu ));
4389 }
4390
4391 case CXCursor_LabelRef:
4392 // FIXME: We end up faking the "parent" declaration here because we
4393 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004394 return MakeCXCursor(getCursorLabelRef(C).first,
4395 cxtu::getASTUnit(tu)->getASTContext()
4396 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004397 tu);
4398
4399 case CXCursor_OverloadedDeclRef:
4400 return C;
4401
4402 case CXCursor_VariableRef:
4403 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4404
4405 default:
4406 // We would prefer to enumerate all non-reference cursor kinds here.
4407 llvm_unreachable("Unhandled reference cursor kind");
4408 }
4409}
4410
4411CXCursor clang_getCursorDefinition(CXCursor C) {
4412 if (clang_isInvalid(C.kind))
4413 return clang_getNullCursor();
4414
4415 CXTranslationUnit TU = getCursorTU(C);
4416
4417 bool WasReference = false;
4418 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4419 C = clang_getCursorReferenced(C);
4420 WasReference = true;
4421 }
4422
4423 if (C.kind == CXCursor_MacroExpansion)
4424 return clang_getCursorReferenced(C);
4425
4426 if (!clang_isDeclaration(C.kind))
4427 return clang_getNullCursor();
4428
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004429 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004430 if (!D)
4431 return clang_getNullCursor();
4432
4433 switch (D->getKind()) {
4434 // Declaration kinds that don't really separate the notions of
4435 // declaration and definition.
4436 case Decl::Namespace:
4437 case Decl::Typedef:
4438 case Decl::TypeAlias:
4439 case Decl::TypeAliasTemplate:
4440 case Decl::TemplateTypeParm:
4441 case Decl::EnumConstant:
4442 case Decl::Field:
4443 case Decl::IndirectField:
4444 case Decl::ObjCIvar:
4445 case Decl::ObjCAtDefsField:
4446 case Decl::ImplicitParam:
4447 case Decl::ParmVar:
4448 case Decl::NonTypeTemplateParm:
4449 case Decl::TemplateTemplateParm:
4450 case Decl::ObjCCategoryImpl:
4451 case Decl::ObjCImplementation:
4452 case Decl::AccessSpec:
4453 case Decl::LinkageSpec:
4454 case Decl::ObjCPropertyImpl:
4455 case Decl::FileScopeAsm:
4456 case Decl::StaticAssert:
4457 case Decl::Block:
4458 case Decl::Label: // FIXME: Is this right??
4459 case Decl::ClassScopeFunctionSpecialization:
4460 case Decl::Import:
4461 return C;
4462
4463 // Declaration kinds that don't make any sense here, but are
4464 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004465 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004466 case Decl::TranslationUnit:
4467 break;
4468
4469 // Declaration kinds for which the definition is not resolvable.
4470 case Decl::UnresolvedUsingTypename:
4471 case Decl::UnresolvedUsingValue:
4472 break;
4473
4474 case Decl::UsingDirective:
4475 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4476 TU);
4477
4478 case Decl::NamespaceAlias:
4479 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4480
4481 case Decl::Enum:
4482 case Decl::Record:
4483 case Decl::CXXRecord:
4484 case Decl::ClassTemplateSpecialization:
4485 case Decl::ClassTemplatePartialSpecialization:
4486 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4487 return MakeCXCursor(Def, TU);
4488 return clang_getNullCursor();
4489
4490 case Decl::Function:
4491 case Decl::CXXMethod:
4492 case Decl::CXXConstructor:
4493 case Decl::CXXDestructor:
4494 case Decl::CXXConversion: {
4495 const FunctionDecl *Def = 0;
4496 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004497 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004498 return clang_getNullCursor();
4499 }
4500
4501 case Decl::Var: {
4502 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004503 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004504 return MakeCXCursor(Def, TU);
4505 return clang_getNullCursor();
4506 }
4507
4508 case Decl::FunctionTemplate: {
4509 const FunctionDecl *Def = 0;
4510 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4511 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4512 return clang_getNullCursor();
4513 }
4514
4515 case Decl::ClassTemplate: {
4516 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4517 ->getDefinition())
4518 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4519 TU);
4520 return clang_getNullCursor();
4521 }
4522
4523 case Decl::Using:
4524 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4525 D->getLocation(), TU);
4526
4527 case Decl::UsingShadow:
4528 return clang_getCursorDefinition(
4529 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4530 TU));
4531
4532 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004533 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004534 if (Method->isThisDeclarationADefinition())
4535 return C;
4536
4537 // Dig out the method definition in the associated
4538 // @implementation, if we have it.
4539 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004540 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004541 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4542 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4543 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4544 Method->isInstanceMethod()))
4545 if (Def->isThisDeclarationADefinition())
4546 return MakeCXCursor(Def, TU);
4547
4548 return clang_getNullCursor();
4549 }
4550
4551 case Decl::ObjCCategory:
4552 if (ObjCCategoryImplDecl *Impl
4553 = cast<ObjCCategoryDecl>(D)->getImplementation())
4554 return MakeCXCursor(Impl, TU);
4555 return clang_getNullCursor();
4556
4557 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004558 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004559 return MakeCXCursor(Def, TU);
4560 return clang_getNullCursor();
4561
4562 case Decl::ObjCInterface: {
4563 // There are two notions of a "definition" for an Objective-C
4564 // class: the interface and its implementation. When we resolved a
4565 // reference to an Objective-C class, produce the @interface as
4566 // the definition; when we were provided with the interface,
4567 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004568 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004569 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004570 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004571 return MakeCXCursor(Def, TU);
4572 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4573 return MakeCXCursor(Impl, TU);
4574 return clang_getNullCursor();
4575 }
4576
4577 case Decl::ObjCProperty:
4578 // FIXME: We don't really know where to find the
4579 // ObjCPropertyImplDecls that implement this property.
4580 return clang_getNullCursor();
4581
4582 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004583 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004584 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004585 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004586 return MakeCXCursor(Def, TU);
4587
4588 return clang_getNullCursor();
4589
4590 case Decl::Friend:
4591 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4592 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4593 return clang_getNullCursor();
4594
4595 case Decl::FriendTemplate:
4596 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4597 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4598 return clang_getNullCursor();
4599 }
4600
4601 return clang_getNullCursor();
4602}
4603
4604unsigned clang_isCursorDefinition(CXCursor C) {
4605 if (!clang_isDeclaration(C.kind))
4606 return 0;
4607
4608 return clang_getCursorDefinition(C) == C;
4609}
4610
4611CXCursor clang_getCanonicalCursor(CXCursor C) {
4612 if (!clang_isDeclaration(C.kind))
4613 return C;
4614
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004615 if (const Decl *D = getCursorDecl(C)) {
4616 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004617 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4618 return MakeCXCursor(CatD, getCursorTU(C));
4619
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004620 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4621 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004622 return MakeCXCursor(IFD, getCursorTU(C));
4623
4624 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4625 }
4626
4627 return C;
4628}
4629
4630int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4631 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4632}
4633
4634unsigned clang_getNumOverloadedDecls(CXCursor C) {
4635 if (C.kind != CXCursor_OverloadedDeclRef)
4636 return 0;
4637
4638 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004639 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004640 return E->getNumDecls();
4641
4642 if (OverloadedTemplateStorage *S
4643 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4644 return S->size();
4645
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004646 const Decl *D = Storage.get<const Decl *>();
4647 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004648 return Using->shadow_size();
4649
4650 return 0;
4651}
4652
4653CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4654 if (cursor.kind != CXCursor_OverloadedDeclRef)
4655 return clang_getNullCursor();
4656
4657 if (index >= clang_getNumOverloadedDecls(cursor))
4658 return clang_getNullCursor();
4659
4660 CXTranslationUnit TU = getCursorTU(cursor);
4661 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).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 MakeCXCursor(E->decls_begin()[index], TU);
4664
4665 if (OverloadedTemplateStorage *S
4666 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4667 return MakeCXCursor(S->begin()[index], TU);
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 // FIXME: This is, unfortunately, linear time.
4672 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4673 std::advance(Pos, index);
4674 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4675 }
4676
4677 return clang_getNullCursor();
4678}
4679
4680void clang_getDefinitionSpellingAndExtent(CXCursor C,
4681 const char **startBuf,
4682 const char **endBuf,
4683 unsigned *startLine,
4684 unsigned *startColumn,
4685 unsigned *endLine,
4686 unsigned *endColumn) {
4687 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004688 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004689 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4690
4691 SourceManager &SM = FD->getASTContext().getSourceManager();
4692 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4693 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4694 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4695 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4696 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4697 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4698}
4699
4700
4701CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4702 unsigned PieceIndex) {
4703 RefNamePieces Pieces;
4704
4705 switch (C.kind) {
4706 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004707 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004708 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4709 E->getQualifierLoc().getSourceRange());
4710 break;
4711
4712 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004713 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004714 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4715 E->getQualifierLoc().getSourceRange(),
4716 E->getOptionalExplicitTemplateArgs());
4717 break;
4718
4719 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004720 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004721 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004722 const Expr *Callee = OCE->getCallee();
4723 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004724 Callee = ICE->getSubExpr();
4725
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004726 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004727 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4728 DRE->getQualifierLoc().getSourceRange());
4729 }
4730 break;
4731
4732 default:
4733 break;
4734 }
4735
4736 if (Pieces.empty()) {
4737 if (PieceIndex == 0)
4738 return clang_getCursorExtent(C);
4739 } else if (PieceIndex < Pieces.size()) {
4740 SourceRange R = Pieces[PieceIndex];
4741 if (R.isValid())
4742 return cxloc::translateSourceRange(getCursorContext(C), R);
4743 }
4744
4745 return clang_getNullRange();
4746}
4747
4748void clang_enableStackTraces(void) {
4749 llvm::sys::PrintStackTraceOnErrorSignal();
4750}
4751
4752void clang_executeOnThread(void (*fn)(void*), void *user_data,
4753 unsigned stack_size) {
4754 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4755}
4756
4757} // end: extern "C"
4758
4759//===----------------------------------------------------------------------===//
4760// Token-based Operations.
4761//===----------------------------------------------------------------------===//
4762
4763/* CXToken layout:
4764 * int_data[0]: a CXTokenKind
4765 * int_data[1]: starting token location
4766 * int_data[2]: token length
4767 * int_data[3]: reserved
4768 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4769 * otherwise unused.
4770 */
4771extern "C" {
4772
4773CXTokenKind clang_getTokenKind(CXToken CXTok) {
4774 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4775}
4776
4777CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4778 switch (clang_getTokenKind(CXTok)) {
4779 case CXToken_Identifier:
4780 case CXToken_Keyword:
4781 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004782 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004783 ->getNameStart());
4784
4785 case CXToken_Literal: {
4786 // We have stashed the starting pointer in the ptr_data field. Use it.
4787 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004788 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004789 }
4790
4791 case CXToken_Punctuation:
4792 case CXToken_Comment:
4793 break;
4794 }
4795
4796 // We have to find the starting buffer pointer the hard way, by
4797 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004798 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004799 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004800 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004801
4802 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4803 std::pair<FileID, unsigned> LocInfo
4804 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4805 bool Invalid = false;
4806 StringRef Buffer
4807 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4808 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004809 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004810
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004811 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004812}
4813
4814CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004815 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004816 if (!CXXUnit)
4817 return clang_getNullLocation();
4818
4819 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4820 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4821}
4822
4823CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004824 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004825 if (!CXXUnit)
4826 return clang_getNullRange();
4827
4828 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4829 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4830}
4831
4832static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4833 SmallVectorImpl<CXToken> &CXTokens) {
4834 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4835 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004836 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004837 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004838 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004839
4840 // Cannot tokenize across files.
4841 if (BeginLocInfo.first != EndLocInfo.first)
4842 return;
4843
4844 // Create a lexer
4845 bool Invalid = false;
4846 StringRef Buffer
4847 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4848 if (Invalid)
4849 return;
4850
4851 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4852 CXXUnit->getASTContext().getLangOpts(),
4853 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4854 Lex.SetCommentRetentionState(true);
4855
4856 // Lex tokens until we hit the end of the range.
4857 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4858 Token Tok;
4859 bool previousWasAt = false;
4860 do {
4861 // Lex the next token
4862 Lex.LexFromRawLexer(Tok);
4863 if (Tok.is(tok::eof))
4864 break;
4865
4866 // Initialize the CXToken.
4867 CXToken CXTok;
4868
4869 // - Common fields
4870 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4871 CXTok.int_data[2] = Tok.getLength();
4872 CXTok.int_data[3] = 0;
4873
4874 // - Kind-specific fields
4875 if (Tok.isLiteral()) {
4876 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004877 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004878 } else if (Tok.is(tok::raw_identifier)) {
4879 // Lookup the identifier to determine whether we have a keyword.
4880 IdentifierInfo *II
4881 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4882
4883 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4884 CXTok.int_data[0] = CXToken_Keyword;
4885 }
4886 else {
4887 CXTok.int_data[0] = Tok.is(tok::identifier)
4888 ? CXToken_Identifier
4889 : CXToken_Keyword;
4890 }
4891 CXTok.ptr_data = II;
4892 } else if (Tok.is(tok::comment)) {
4893 CXTok.int_data[0] = CXToken_Comment;
4894 CXTok.ptr_data = 0;
4895 } else {
4896 CXTok.int_data[0] = CXToken_Punctuation;
4897 CXTok.ptr_data = 0;
4898 }
4899 CXTokens.push_back(CXTok);
4900 previousWasAt = Tok.is(tok::at);
4901 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4902}
4903
4904void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4905 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004906 LOG_FUNC_SECTION {
4907 *Log << TU << ' ' << Range;
4908 }
4909
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004910 if (Tokens)
4911 *Tokens = 0;
4912 if (NumTokens)
4913 *NumTokens = 0;
4914
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004915 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004916 if (!CXXUnit || !Tokens || !NumTokens)
4917 return;
4918
4919 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4920
4921 SourceRange R = cxloc::translateCXSourceRange(Range);
4922 if (R.isInvalid())
4923 return;
4924
4925 SmallVector<CXToken, 32> CXTokens;
4926 getTokens(CXXUnit, R, CXTokens);
4927
4928 if (CXTokens.empty())
4929 return;
4930
4931 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4932 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4933 *NumTokens = CXTokens.size();
4934}
4935
4936void clang_disposeTokens(CXTranslationUnit TU,
4937 CXToken *Tokens, unsigned NumTokens) {
4938 free(Tokens);
4939}
4940
4941} // end: extern "C"
4942
4943//===----------------------------------------------------------------------===//
4944// Token annotation APIs.
4945//===----------------------------------------------------------------------===//
4946
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004947static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4948 CXCursor parent,
4949 CXClientData client_data);
4950static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4951 CXClientData client_data);
4952
4953namespace {
4954class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004955 CXToken *Tokens;
4956 CXCursor *Cursors;
4957 unsigned NumTokens;
4958 unsigned TokIdx;
4959 unsigned PreprocessingTokIdx;
4960 CursorVisitor AnnotateVis;
4961 SourceManager &SrcMgr;
4962 bool HasContextSensitiveKeywords;
4963
4964 struct PostChildrenInfo {
4965 CXCursor Cursor;
4966 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004967 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004968 unsigned BeforeChildrenTokenIdx;
4969 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004970 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004971
4972 bool MoreTokens() const { return TokIdx < NumTokens; }
4973 unsigned NextToken() const { return TokIdx; }
4974 void AdvanceToken() { ++TokIdx; }
4975 SourceLocation GetTokenLoc(unsigned tokI) {
4976 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4977 }
4978 bool isFunctionMacroToken(unsigned tokI) const {
4979 return Tokens[tokI].int_data[3] != 0;
4980 }
4981 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4982 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4983 }
4984
4985 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004986 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004987 SourceRange);
4988
4989public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004990 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004991 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004992 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004993 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004994 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004995 AnnotateTokensVisitor, this,
4996 /*VisitPreprocessorLast=*/true,
4997 /*VisitIncludedEntities=*/false,
4998 RegionOfInterest,
4999 /*VisitDeclsOnly=*/false,
5000 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005001 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005002 HasContextSensitiveKeywords(false) { }
5003
5004 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5005 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5006 bool postVisitChildren(CXCursor cursor);
5007 void AnnotateTokens();
5008
5009 /// \brief Determine whether the annotator saw any cursors that have
5010 /// context-sensitive keywords.
5011 bool hasContextSensitiveKeywords() const {
5012 return HasContextSensitiveKeywords;
5013 }
5014
5015 ~AnnotateTokensWorker() {
5016 assert(PostChildrenInfos.empty());
5017 }
5018};
5019}
5020
5021void AnnotateTokensWorker::AnnotateTokens() {
5022 // Walk the AST within the region of interest, annotating tokens
5023 // along the way.
5024 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005025}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005026
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005027static inline void updateCursorAnnotation(CXCursor &Cursor,
5028 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005029 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005030 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005031 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005032}
5033
5034/// \brief It annotates and advances tokens with a cursor until the comparison
5035//// between the cursor location and the source range is the same as
5036/// \arg compResult.
5037///
5038/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5039/// Pass RangeOverlap to annotate tokens inside a range.
5040void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5041 RangeComparisonResult compResult,
5042 SourceRange range) {
5043 while (MoreTokens()) {
5044 const unsigned I = NextToken();
5045 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005046 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5047 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005048
5049 SourceLocation TokLoc = GetTokenLoc(I);
5050 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005051 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005052 AdvanceToken();
5053 continue;
5054 }
5055 break;
5056 }
5057}
5058
5059/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005060/// \returns true if it advanced beyond all macro tokens, false otherwise.
5061bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005062 CXCursor updateC,
5063 RangeComparisonResult compResult,
5064 SourceRange range) {
5065 assert(MoreTokens());
5066 assert(isFunctionMacroToken(NextToken()) &&
5067 "Should be called only for macro arg tokens");
5068
5069 // This works differently than annotateAndAdvanceTokens; because expanded
5070 // macro arguments can have arbitrary translation-unit source order, we do not
5071 // advance the token index one by one until a token fails the range test.
5072 // We only advance once past all of the macro arg tokens if all of them
5073 // pass the range test. If one of them fails we keep the token index pointing
5074 // at the start of the macro arg tokens so that the failing token will be
5075 // annotated by a subsequent annotation try.
5076
5077 bool atLeastOneCompFail = false;
5078
5079 unsigned I = NextToken();
5080 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5081 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5082 if (TokLoc.isFileID())
5083 continue; // not macro arg token, it's parens or comma.
5084 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5085 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5086 Cursors[I] = updateC;
5087 } else
5088 atLeastOneCompFail = true;
5089 }
5090
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005091 if (atLeastOneCompFail)
5092 return false;
5093
5094 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5095 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005096}
5097
5098enum CXChildVisitResult
5099AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005100 SourceRange cursorRange = getRawCursorExtent(cursor);
5101 if (cursorRange.isInvalid())
5102 return CXChildVisit_Recurse;
5103
5104 if (!HasContextSensitiveKeywords) {
5105 // Objective-C properties can have context-sensitive keywords.
5106 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005107 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005108 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5109 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5110 }
5111 // Objective-C methods can have context-sensitive keywords.
5112 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5113 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005114 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005115 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5116 if (Method->getObjCDeclQualifier())
5117 HasContextSensitiveKeywords = true;
5118 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005119 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5120 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005121 P != PEnd; ++P) {
5122 if ((*P)->getObjCDeclQualifier()) {
5123 HasContextSensitiveKeywords = true;
5124 break;
5125 }
5126 }
5127 }
5128 }
5129 }
5130 // C++ methods can have context-sensitive keywords.
5131 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005132 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005133 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5134 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5135 HasContextSensitiveKeywords = true;
5136 }
5137 }
5138 // C++ classes can have context-sensitive keywords.
5139 else if (cursor.kind == CXCursor_StructDecl ||
5140 cursor.kind == CXCursor_ClassDecl ||
5141 cursor.kind == CXCursor_ClassTemplate ||
5142 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005143 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005144 if (D->hasAttr<FinalAttr>())
5145 HasContextSensitiveKeywords = true;
5146 }
5147 }
5148
5149 if (clang_isPreprocessing(cursor.kind)) {
5150 // Items in the preprocessing record are kept separate from items in
5151 // declarations, so we keep a separate token index.
5152 unsigned SavedTokIdx = TokIdx;
5153 TokIdx = PreprocessingTokIdx;
5154
5155 // Skip tokens up until we catch up to the beginning of the preprocessing
5156 // entry.
5157 while (MoreTokens()) {
5158 const unsigned I = NextToken();
5159 SourceLocation TokLoc = GetTokenLoc(I);
5160 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5161 case RangeBefore:
5162 AdvanceToken();
5163 continue;
5164 case RangeAfter:
5165 case RangeOverlap:
5166 break;
5167 }
5168 break;
5169 }
5170
5171 // Look at all of the tokens within this range.
5172 while (MoreTokens()) {
5173 const unsigned I = NextToken();
5174 SourceLocation TokLoc = GetTokenLoc(I);
5175 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5176 case RangeBefore:
5177 llvm_unreachable("Infeasible");
5178 case RangeAfter:
5179 break;
5180 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005181 // For macro expansions, just note where the beginning of the macro
5182 // expansion occurs.
5183 if (cursor.kind == CXCursor_MacroExpansion) {
5184 if (TokLoc == cursorRange.getBegin())
5185 Cursors[I] = cursor;
5186 AdvanceToken();
5187 break;
5188 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005189 // We may have already annotated macro names inside macro definitions.
5190 if (Cursors[I].kind != CXCursor_MacroExpansion)
5191 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005192 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005193 continue;
5194 }
5195 break;
5196 }
5197
5198 // Save the preprocessing token index; restore the non-preprocessing
5199 // token index.
5200 PreprocessingTokIdx = TokIdx;
5201 TokIdx = SavedTokIdx;
5202 return CXChildVisit_Recurse;
5203 }
5204
5205 if (cursorRange.isInvalid())
5206 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005207
5208 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005209 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005210 const enum CXCursorKind K = clang_getCursorKind(parent);
5211 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005212 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5213 // Attributes are annotated out-of-order, skip tokens until we reach it.
5214 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005215 ? clang_getNullCursor() : parent;
5216
5217 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5218
5219 // Avoid having the cursor of an expression "overwrite" the annotation of the
5220 // variable declaration that it belongs to.
5221 // This can happen for C++ constructor expressions whose range generally
5222 // include the variable declaration, e.g.:
5223 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5224 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005225 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005226 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005227 const unsigned I = NextToken();
5228 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5229 E->getLocStart() == D->getLocation() &&
5230 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005231 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005232 AdvanceToken();
5233 }
5234 }
5235 }
5236
5237 // Before recursing into the children keep some state that we are going
5238 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5239 // extra work after the child nodes are visited.
5240 // Note that we don't call VisitChildren here to avoid traversing statements
5241 // code-recursively which can blow the stack.
5242
5243 PostChildrenInfo Info;
5244 Info.Cursor = cursor;
5245 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005246 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005247 Info.BeforeChildrenTokenIdx = NextToken();
5248 PostChildrenInfos.push_back(Info);
5249
5250 return CXChildVisit_Recurse;
5251}
5252
5253bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5254 if (PostChildrenInfos.empty())
5255 return false;
5256 const PostChildrenInfo &Info = PostChildrenInfos.back();
5257 if (!clang_equalCursors(Info.Cursor, cursor))
5258 return false;
5259
5260 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5261 const unsigned AfterChildren = NextToken();
5262 SourceRange cursorRange = Info.CursorRange;
5263
5264 // Scan the tokens that are at the end of the cursor, but are not captured
5265 // but the child cursors.
5266 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5267
5268 // Scan the tokens that are at the beginning of the cursor, but are not
5269 // capture by the child cursors.
5270 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5271 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5272 break;
5273
5274 Cursors[I] = cursor;
5275 }
5276
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005277 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5278 // encountered the attribute cursor.
5279 if (clang_isAttribute(cursor.kind))
5280 TokIdx = Info.BeforeReachingCursorIdx;
5281
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005282 PostChildrenInfos.pop_back();
5283 return false;
5284}
5285
5286static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5287 CXCursor parent,
5288 CXClientData client_data) {
5289 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5290}
5291
5292static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5293 CXClientData client_data) {
5294 return static_cast<AnnotateTokensWorker*>(client_data)->
5295 postVisitChildren(cursor);
5296}
5297
5298namespace {
5299
5300/// \brief Uses the macro expansions in the preprocessing record to find
5301/// and mark tokens that are macro arguments. This info is used by the
5302/// AnnotateTokensWorker.
5303class MarkMacroArgTokensVisitor {
5304 SourceManager &SM;
5305 CXToken *Tokens;
5306 unsigned NumTokens;
5307 unsigned CurIdx;
5308
5309public:
5310 MarkMacroArgTokensVisitor(SourceManager &SM,
5311 CXToken *tokens, unsigned numTokens)
5312 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5313
5314 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5315 if (cursor.kind != CXCursor_MacroExpansion)
5316 return CXChildVisit_Continue;
5317
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005318 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005319 if (macroRange.getBegin() == macroRange.getEnd())
5320 return CXChildVisit_Continue; // it's not a function macro.
5321
5322 for (; CurIdx < NumTokens; ++CurIdx) {
5323 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5324 macroRange.getBegin()))
5325 break;
5326 }
5327
5328 if (CurIdx == NumTokens)
5329 return CXChildVisit_Break;
5330
5331 for (; CurIdx < NumTokens; ++CurIdx) {
5332 SourceLocation tokLoc = getTokenLoc(CurIdx);
5333 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5334 break;
5335
5336 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5337 }
5338
5339 if (CurIdx == NumTokens)
5340 return CXChildVisit_Break;
5341
5342 return CXChildVisit_Continue;
5343 }
5344
5345private:
5346 SourceLocation getTokenLoc(unsigned tokI) {
5347 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5348 }
5349
5350 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5351 // The third field is reserved and currently not used. Use it here
5352 // to mark macro arg expanded tokens with their expanded locations.
5353 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5354 }
5355};
5356
5357} // end anonymous namespace
5358
5359static CXChildVisitResult
5360MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5361 CXClientData client_data) {
5362 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5363 parent);
5364}
5365
5366namespace {
5367 struct clang_annotateTokens_Data {
5368 CXTranslationUnit TU;
5369 ASTUnit *CXXUnit;
5370 CXToken *Tokens;
5371 unsigned NumTokens;
5372 CXCursor *Cursors;
5373 };
5374}
5375
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005376/// \brief Used by \c annotatePreprocessorTokens.
5377/// \returns true if lexing was finished, false otherwise.
5378static bool lexNext(Lexer &Lex, Token &Tok,
5379 unsigned &NextIdx, unsigned NumTokens) {
5380 if (NextIdx >= NumTokens)
5381 return true;
5382
5383 ++NextIdx;
5384 Lex.LexFromRawLexer(Tok);
5385 if (Tok.is(tok::eof))
5386 return true;
5387
5388 return false;
5389}
5390
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005391static void annotatePreprocessorTokens(CXTranslationUnit TU,
5392 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005393 CXCursor *Cursors,
5394 CXToken *Tokens,
5395 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005396 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005397
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005398 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005399 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5400 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005401 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005402 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005403 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005404
5405 if (BeginLocInfo.first != EndLocInfo.first)
5406 return;
5407
5408 StringRef Buffer;
5409 bool Invalid = false;
5410 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5411 if (Buffer.empty() || Invalid)
5412 return;
5413
5414 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5415 CXXUnit->getASTContext().getLangOpts(),
5416 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5417 Buffer.end());
5418 Lex.SetCommentRetentionState(true);
5419
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005420 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005421 // Lex tokens in raw mode until we hit the end of the range, to avoid
5422 // entering #includes or expanding macros.
5423 while (true) {
5424 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005425 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5426 break;
5427 unsigned TokIdx = NextIdx-1;
5428 assert(Tok.getLocation() ==
5429 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005430
5431 reprocess:
5432 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005433 // We have found a preprocessing directive. Annotate the tokens
5434 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005435 //
5436 // FIXME: Some simple tests here could identify macro definitions and
5437 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005438
5439 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005440 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5441 break;
5442
5443 MacroInfo *MI = 0;
5444 if (Tok.is(tok::raw_identifier) &&
5445 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5446 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5447 break;
5448
5449 if (Tok.is(tok::raw_identifier)) {
5450 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5451 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5452 SourceLocation MappedTokLoc =
5453 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5454 MI = getMacroInfo(II, MappedTokLoc, TU);
5455 }
5456 }
5457
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005458 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005459 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005460 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5461 finished = true;
5462 break;
5463 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005464 // If we are in a macro definition, check if the token was ever a
5465 // macro name and annotate it if that's the case.
5466 if (MI) {
5467 SourceLocation SaveLoc = Tok.getLocation();
5468 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5469 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5470 Tok.setLocation(SaveLoc);
5471 if (MacroDef)
5472 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5473 Tok.getLocation(), TU);
5474 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005475 } while (!Tok.isAtStartOfLine());
5476
5477 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5478 assert(TokIdx <= LastIdx);
5479 SourceLocation EndLoc =
5480 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5481 CXCursor Cursor =
5482 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5483
5484 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005485 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005486
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005487 if (finished)
5488 break;
5489 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005490 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005491 }
5492}
5493
5494// This gets run a separate thread to avoid stack blowout.
5495static void clang_annotateTokensImpl(void *UserData) {
5496 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5497 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5498 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5499 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5500 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5501
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005502 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005503 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5504 setThreadBackgroundPriority();
5505
5506 // Determine the region of interest, which contains all of the tokens.
5507 SourceRange RegionOfInterest;
5508 RegionOfInterest.setBegin(
5509 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5510 RegionOfInterest.setEnd(
5511 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5512 Tokens[NumTokens-1])));
5513
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005514 // Relex the tokens within the source range to look for preprocessing
5515 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005516 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005517
5518 // If begin location points inside a macro argument, set it to the expansion
5519 // location so we can have the full context when annotating semantically.
5520 {
5521 SourceManager &SM = CXXUnit->getSourceManager();
5522 SourceLocation Loc =
5523 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5524 if (Loc.isMacroID())
5525 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5526 }
5527
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005528 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5529 // Search and mark tokens that are macro argument expansions.
5530 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5531 Tokens, NumTokens);
5532 CursorVisitor MacroArgMarker(TU,
5533 MarkMacroArgTokensVisitorDelegate, &Visitor,
5534 /*VisitPreprocessorLast=*/true,
5535 /*VisitIncludedEntities=*/false,
5536 RegionOfInterest);
5537 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5538 }
5539
5540 // Annotate all of the source locations in the region of interest that map to
5541 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005542 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005543
5544 // FIXME: We use a ridiculous stack size here because the data-recursion
5545 // algorithm uses a large stack frame than the non-data recursive version,
5546 // and AnnotationTokensWorker currently transforms the data-recursion
5547 // algorithm back into a traditional recursion by explicitly calling
5548 // VisitChildren(). We will need to remove this explicit recursive call.
5549 W.AnnotateTokens();
5550
5551 // If we ran into any entities that involve context-sensitive keywords,
5552 // take another pass through the tokens to mark them as such.
5553 if (W.hasContextSensitiveKeywords()) {
5554 for (unsigned I = 0; I != NumTokens; ++I) {
5555 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5556 continue;
5557
5558 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5559 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005560 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005561 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5562 if (Property->getPropertyAttributesAsWritten() != 0 &&
5563 llvm::StringSwitch<bool>(II->getName())
5564 .Case("readonly", true)
5565 .Case("assign", true)
5566 .Case("unsafe_unretained", true)
5567 .Case("readwrite", true)
5568 .Case("retain", true)
5569 .Case("copy", true)
5570 .Case("nonatomic", true)
5571 .Case("atomic", true)
5572 .Case("getter", true)
5573 .Case("setter", true)
5574 .Case("strong", true)
5575 .Case("weak", true)
5576 .Default(false))
5577 Tokens[I].int_data[0] = CXToken_Keyword;
5578 }
5579 continue;
5580 }
5581
5582 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5583 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5584 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5585 if (llvm::StringSwitch<bool>(II->getName())
5586 .Case("in", true)
5587 .Case("out", true)
5588 .Case("inout", true)
5589 .Case("oneway", true)
5590 .Case("bycopy", true)
5591 .Case("byref", true)
5592 .Default(false))
5593 Tokens[I].int_data[0] = CXToken_Keyword;
5594 continue;
5595 }
5596
5597 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5598 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5599 Tokens[I].int_data[0] = CXToken_Keyword;
5600 continue;
5601 }
5602 }
5603 }
5604}
5605
5606extern "C" {
5607
5608void clang_annotateTokens(CXTranslationUnit TU,
5609 CXToken *Tokens, unsigned NumTokens,
5610 CXCursor *Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005611 if (NumTokens == 0 || !Tokens || !Cursors) {
5612 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005613 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005614 }
5615
5616 LOG_FUNC_SECTION {
5617 *Log << TU << ' ';
5618 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5619 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5620 *Log << clang_getRange(bloc, eloc);
5621 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005622
5623 // Any token we don't specifically annotate will have a NULL cursor.
5624 CXCursor C = clang_getNullCursor();
5625 for (unsigned I = 0; I != NumTokens; ++I)
5626 Cursors[I] = C;
5627
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005628 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005629 if (!CXXUnit)
5630 return;
5631
5632 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5633
5634 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5635 llvm::CrashRecoveryContext CRC;
5636 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5637 GetSafetyThreadStackSize() * 2)) {
5638 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5639 }
5640}
5641
5642} // end: extern "C"
5643
5644//===----------------------------------------------------------------------===//
5645// Operations for querying linkage of a cursor.
5646//===----------------------------------------------------------------------===//
5647
5648extern "C" {
5649CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5650 if (!clang_isDeclaration(cursor.kind))
5651 return CXLinkage_Invalid;
5652
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005653 const Decl *D = cxcursor::getCursorDecl(cursor);
5654 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005655 switch (ND->getLinkage()) {
5656 case NoLinkage: return CXLinkage_NoLinkage;
5657 case InternalLinkage: return CXLinkage_Internal;
5658 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5659 case ExternalLinkage: return CXLinkage_External;
5660 };
5661
5662 return CXLinkage_Invalid;
5663}
5664} // end: extern "C"
5665
5666//===----------------------------------------------------------------------===//
5667// Operations for querying language of a cursor.
5668//===----------------------------------------------------------------------===//
5669
5670static CXLanguageKind getDeclLanguage(const Decl *D) {
5671 if (!D)
5672 return CXLanguage_C;
5673
5674 switch (D->getKind()) {
5675 default:
5676 break;
5677 case Decl::ImplicitParam:
5678 case Decl::ObjCAtDefsField:
5679 case Decl::ObjCCategory:
5680 case Decl::ObjCCategoryImpl:
5681 case Decl::ObjCCompatibleAlias:
5682 case Decl::ObjCImplementation:
5683 case Decl::ObjCInterface:
5684 case Decl::ObjCIvar:
5685 case Decl::ObjCMethod:
5686 case Decl::ObjCProperty:
5687 case Decl::ObjCPropertyImpl:
5688 case Decl::ObjCProtocol:
5689 return CXLanguage_ObjC;
5690 case Decl::CXXConstructor:
5691 case Decl::CXXConversion:
5692 case Decl::CXXDestructor:
5693 case Decl::CXXMethod:
5694 case Decl::CXXRecord:
5695 case Decl::ClassTemplate:
5696 case Decl::ClassTemplatePartialSpecialization:
5697 case Decl::ClassTemplateSpecialization:
5698 case Decl::Friend:
5699 case Decl::FriendTemplate:
5700 case Decl::FunctionTemplate:
5701 case Decl::LinkageSpec:
5702 case Decl::Namespace:
5703 case Decl::NamespaceAlias:
5704 case Decl::NonTypeTemplateParm:
5705 case Decl::StaticAssert:
5706 case Decl::TemplateTemplateParm:
5707 case Decl::TemplateTypeParm:
5708 case Decl::UnresolvedUsingTypename:
5709 case Decl::UnresolvedUsingValue:
5710 case Decl::Using:
5711 case Decl::UsingDirective:
5712 case Decl::UsingShadow:
5713 return CXLanguage_CPlusPlus;
5714 }
5715
5716 return CXLanguage_C;
5717}
5718
5719extern "C" {
5720
5721enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5722 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005723 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005724 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5725 return CXAvailability_Available;
5726
5727 switch (D->getAvailability()) {
5728 case AR_Available:
5729 case AR_NotYetIntroduced:
5730 return CXAvailability_Available;
5731
5732 case AR_Deprecated:
5733 return CXAvailability_Deprecated;
5734
5735 case AR_Unavailable:
5736 return CXAvailability_NotAvailable;
5737 }
5738 }
5739
5740 return CXAvailability_Available;
5741}
5742
5743static CXVersion convertVersion(VersionTuple In) {
5744 CXVersion Out = { -1, -1, -1 };
5745 if (In.empty())
5746 return Out;
5747
5748 Out.Major = In.getMajor();
5749
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005750 Optional<unsigned> Minor = In.getMinor();
5751 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005752 Out.Minor = *Minor;
5753 else
5754 return Out;
5755
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005756 Optional<unsigned> Subminor = In.getSubminor();
5757 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005758 Out.Subminor = *Subminor;
5759
5760 return Out;
5761}
5762
5763int clang_getCursorPlatformAvailability(CXCursor cursor,
5764 int *always_deprecated,
5765 CXString *deprecated_message,
5766 int *always_unavailable,
5767 CXString *unavailable_message,
5768 CXPlatformAvailability *availability,
5769 int availability_size) {
5770 if (always_deprecated)
5771 *always_deprecated = 0;
5772 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005773 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005774 if (always_unavailable)
5775 *always_unavailable = 0;
5776 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005777 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005778
5779 if (!clang_isDeclaration(cursor.kind))
5780 return 0;
5781
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005782 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005783 if (!D)
5784 return 0;
5785
5786 int N = 0;
5787 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5788 ++A) {
5789 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5790 if (always_deprecated)
5791 *always_deprecated = 1;
5792 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005793 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005794 continue;
5795 }
5796
5797 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5798 if (always_unavailable)
5799 *always_unavailable = 1;
5800 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005801 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005802 }
5803 continue;
5804 }
5805
5806 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5807 if (N < availability_size) {
5808 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005809 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005810 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5811 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5812 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5813 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005814 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005815 }
5816 ++N;
5817 }
5818 }
5819
5820 return N;
5821}
5822
5823void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5824 clang_disposeString(availability->Platform);
5825 clang_disposeString(availability->Message);
5826}
5827
5828CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5829 if (clang_isDeclaration(cursor.kind))
5830 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5831
5832 return CXLanguage_Invalid;
5833}
5834
5835 /// \brief If the given cursor is the "templated" declaration
5836 /// descibing a class or function template, return the class or
5837 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005838static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005839 if (!D)
5840 return 0;
5841
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005842 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005843 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5844 return FunTmpl;
5845
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005846 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005847 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5848 return ClassTmpl;
5849
5850 return D;
5851}
5852
5853CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5854 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005855 if (const Decl *D = getCursorDecl(cursor)) {
5856 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005857 if (!DC)
5858 return clang_getNullCursor();
5859
5860 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5861 getCursorTU(cursor));
5862 }
5863 }
5864
5865 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005866 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005867 return MakeCXCursor(D, getCursorTU(cursor));
5868 }
5869
5870 return clang_getNullCursor();
5871}
5872
5873CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5874 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005875 if (const Decl *D = getCursorDecl(cursor)) {
5876 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005877 if (!DC)
5878 return clang_getNullCursor();
5879
5880 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5881 getCursorTU(cursor));
5882 }
5883 }
5884
5885 // FIXME: Note that we can't easily compute the lexical context of a
5886 // statement or expression, so we return nothing.
5887 return clang_getNullCursor();
5888}
5889
5890CXFile clang_getIncludedFile(CXCursor cursor) {
5891 if (cursor.kind != CXCursor_InclusionDirective)
5892 return 0;
5893
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005894 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005895 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005896}
5897
5898CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5899 if (!clang_isDeclaration(C.kind))
5900 return clang_getNullRange();
5901
5902 const Decl *D = getCursorDecl(C);
5903 ASTContext &Context = getCursorContext(C);
5904 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5905 if (!RC)
5906 return clang_getNullRange();
5907
5908 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5909}
5910
5911CXString clang_Cursor_getRawCommentText(CXCursor C) {
5912 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005913 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005914
5915 const Decl *D = getCursorDecl(C);
5916 ASTContext &Context = getCursorContext(C);
5917 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5918 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5919 StringRef();
5920
5921 // Don't duplicate the string because RawText points directly into source
5922 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005923 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005924}
5925
5926CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5927 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005928 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005929
5930 const Decl *D = getCursorDecl(C);
5931 const ASTContext &Context = getCursorContext(C);
5932 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5933
5934 if (RC) {
5935 StringRef BriefText = RC->getBriefText(Context);
5936
5937 // Don't duplicate the string because RawComment ensures that this memory
5938 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005939 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005940 }
5941
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005942 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005943}
5944
5945CXComment clang_Cursor_getParsedComment(CXCursor C) {
5946 if (!clang_isDeclaration(C.kind))
5947 return cxcomment::createCXComment(NULL, NULL);
5948
5949 const Decl *D = getCursorDecl(C);
5950 const ASTContext &Context = getCursorContext(C);
5951 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5952
5953 return cxcomment::createCXComment(FC, getCursorTU(C));
5954}
5955
5956CXModule clang_Cursor_getModule(CXCursor C) {
5957 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005958 if (const ImportDecl *ImportD =
5959 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005960 return ImportD->getImportedModule();
5961 }
5962
5963 return 0;
5964}
5965
5966CXModule clang_Module_getParent(CXModule CXMod) {
5967 if (!CXMod)
5968 return 0;
5969 Module *Mod = static_cast<Module*>(CXMod);
5970 return Mod->Parent;
5971}
5972
5973CXString clang_Module_getName(CXModule CXMod) {
5974 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005975 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005976 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005977 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005978}
5979
5980CXString clang_Module_getFullName(CXModule CXMod) {
5981 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005982 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005983 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005984 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005985}
5986
5987unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
5988 if (!CXMod)
5989 return 0;
5990 Module *Mod = static_cast<Module*>(CXMod);
5991 return Mod->TopHeaders.size();
5992}
5993
5994CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
5995 if (!CXMod)
5996 return 0;
5997 Module *Mod = static_cast<Module*>(CXMod);
5998
5999 if (Index < Mod->TopHeaders.size())
6000 return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
6001
6002 return 0;
6003}
6004
6005} // end: extern "C"
6006
6007//===----------------------------------------------------------------------===//
6008// C++ AST instrospection.
6009//===----------------------------------------------------------------------===//
6010
6011extern "C" {
6012unsigned clang_CXXMethod_isStatic(CXCursor C) {
6013 if (!clang_isDeclaration(C.kind))
6014 return 0;
6015
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006016 const CXXMethodDecl *Method = 0;
6017 const Decl *D = cxcursor::getCursorDecl(C);
6018 if (const FunctionTemplateDecl *FunTmpl =
6019 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006020 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6021 else
6022 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6023 return (Method && Method->isStatic()) ? 1 : 0;
6024}
6025
6026unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6027 if (!clang_isDeclaration(C.kind))
6028 return 0;
6029
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006030 const CXXMethodDecl *Method = 0;
6031 const Decl *D = cxcursor::getCursorDecl(C);
6032 if (const FunctionTemplateDecl *FunTmpl =
6033 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006034 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6035 else
6036 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6037 return (Method && Method->isVirtual()) ? 1 : 0;
6038}
6039} // end: extern "C"
6040
6041//===----------------------------------------------------------------------===//
6042// Attribute introspection.
6043//===----------------------------------------------------------------------===//
6044
6045extern "C" {
6046CXType clang_getIBOutletCollectionType(CXCursor C) {
6047 if (C.kind != CXCursor_IBOutletCollectionAttr)
6048 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6049
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006050 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006051 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6052
6053 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6054}
6055} // end: extern "C"
6056
6057//===----------------------------------------------------------------------===//
6058// Inspecting memory usage.
6059//===----------------------------------------------------------------------===//
6060
6061typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6062
6063static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6064 enum CXTUResourceUsageKind k,
6065 unsigned long amount) {
6066 CXTUResourceUsageEntry entry = { k, amount };
6067 entries.push_back(entry);
6068}
6069
6070extern "C" {
6071
6072const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6073 const char *str = "";
6074 switch (kind) {
6075 case CXTUResourceUsage_AST:
6076 str = "ASTContext: expressions, declarations, and types";
6077 break;
6078 case CXTUResourceUsage_Identifiers:
6079 str = "ASTContext: identifiers";
6080 break;
6081 case CXTUResourceUsage_Selectors:
6082 str = "ASTContext: selectors";
6083 break;
6084 case CXTUResourceUsage_GlobalCompletionResults:
6085 str = "Code completion: cached global results";
6086 break;
6087 case CXTUResourceUsage_SourceManagerContentCache:
6088 str = "SourceManager: content cache allocator";
6089 break;
6090 case CXTUResourceUsage_AST_SideTables:
6091 str = "ASTContext: side tables";
6092 break;
6093 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6094 str = "SourceManager: malloc'ed memory buffers";
6095 break;
6096 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6097 str = "SourceManager: mmap'ed memory buffers";
6098 break;
6099 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6100 str = "ExternalASTSource: malloc'ed memory buffers";
6101 break;
6102 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6103 str = "ExternalASTSource: mmap'ed memory buffers";
6104 break;
6105 case CXTUResourceUsage_Preprocessor:
6106 str = "Preprocessor: malloc'ed memory";
6107 break;
6108 case CXTUResourceUsage_PreprocessingRecord:
6109 str = "Preprocessor: PreprocessingRecord";
6110 break;
6111 case CXTUResourceUsage_SourceManager_DataStructures:
6112 str = "SourceManager: data structures and tables";
6113 break;
6114 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6115 str = "Preprocessor: header search tables";
6116 break;
6117 }
6118 return str;
6119}
6120
6121CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6122 if (!TU) {
6123 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6124 return usage;
6125 }
6126
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006127 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006128 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6129 ASTContext &astContext = astUnit->getASTContext();
6130
6131 // How much memory is used by AST nodes and types?
6132 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6133 (unsigned long) astContext.getASTAllocatedMemory());
6134
6135 // How much memory is used by identifiers?
6136 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6137 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6138
6139 // How much memory is used for selectors?
6140 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6141 (unsigned long) astContext.Selectors.getTotalMemory());
6142
6143 // How much memory is used by ASTContext's side tables?
6144 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6145 (unsigned long) astContext.getSideTableAllocatedMemory());
6146
6147 // How much memory is used for caching global code completion results?
6148 unsigned long completionBytes = 0;
6149 if (GlobalCodeCompletionAllocator *completionAllocator =
6150 astUnit->getCachedCompletionAllocator().getPtr()) {
6151 completionBytes = completionAllocator->getTotalMemory();
6152 }
6153 createCXTUResourceUsageEntry(*entries,
6154 CXTUResourceUsage_GlobalCompletionResults,
6155 completionBytes);
6156
6157 // How much memory is being used by SourceManager's content cache?
6158 createCXTUResourceUsageEntry(*entries,
6159 CXTUResourceUsage_SourceManagerContentCache,
6160 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6161
6162 // How much memory is being used by the MemoryBuffer's in SourceManager?
6163 const SourceManager::MemoryBufferSizes &srcBufs =
6164 astUnit->getSourceManager().getMemoryBufferSizes();
6165
6166 createCXTUResourceUsageEntry(*entries,
6167 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6168 (unsigned long) srcBufs.malloc_bytes);
6169 createCXTUResourceUsageEntry(*entries,
6170 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6171 (unsigned long) srcBufs.mmap_bytes);
6172 createCXTUResourceUsageEntry(*entries,
6173 CXTUResourceUsage_SourceManager_DataStructures,
6174 (unsigned long) astContext.getSourceManager()
6175 .getDataStructureSizes());
6176
6177 // How much memory is being used by the ExternalASTSource?
6178 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6179 const ExternalASTSource::MemoryBufferSizes &sizes =
6180 esrc->getMemoryBufferSizes();
6181
6182 createCXTUResourceUsageEntry(*entries,
6183 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6184 (unsigned long) sizes.malloc_bytes);
6185 createCXTUResourceUsageEntry(*entries,
6186 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6187 (unsigned long) sizes.mmap_bytes);
6188 }
6189
6190 // How much memory is being used by the Preprocessor?
6191 Preprocessor &pp = astUnit->getPreprocessor();
6192 createCXTUResourceUsageEntry(*entries,
6193 CXTUResourceUsage_Preprocessor,
6194 pp.getTotalMemory());
6195
6196 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6197 createCXTUResourceUsageEntry(*entries,
6198 CXTUResourceUsage_PreprocessingRecord,
6199 pRec->getTotalMemory());
6200 }
6201
6202 createCXTUResourceUsageEntry(*entries,
6203 CXTUResourceUsage_Preprocessor_HeaderSearch,
6204 pp.getHeaderSearchInfo().getTotalMemory());
6205
6206 CXTUResourceUsage usage = { (void*) entries.get(),
6207 (unsigned) entries->size(),
6208 entries->size() ? &(*entries)[0] : 0 };
6209 entries.take();
6210 return usage;
6211}
6212
6213void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6214 if (usage.data)
6215 delete (MemUsageEntries*) usage.data;
6216}
6217
6218} // end extern "C"
6219
6220void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6221 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6222 for (unsigned I = 0; I != Usage.numEntries; ++I)
6223 fprintf(stderr, " %s: %lu\n",
6224 clang_getTUResourceUsageName(Usage.entries[I].kind),
6225 Usage.entries[I].amount);
6226
6227 clang_disposeCXTUResourceUsage(Usage);
6228}
6229
6230//===----------------------------------------------------------------------===//
6231// Misc. utility functions.
6232//===----------------------------------------------------------------------===//
6233
6234/// Default to using an 8 MB stack size on "safety" threads.
6235static unsigned SafetyStackThreadSize = 8 << 20;
6236
6237namespace clang {
6238
6239bool RunSafely(llvm::CrashRecoveryContext &CRC,
6240 void (*Fn)(void*), void *UserData,
6241 unsigned Size) {
6242 if (!Size)
6243 Size = GetSafetyThreadStackSize();
6244 if (Size)
6245 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6246 return CRC.RunSafely(Fn, UserData);
6247}
6248
6249unsigned GetSafetyThreadStackSize() {
6250 return SafetyStackThreadSize;
6251}
6252
6253void SetSafetyThreadStackSize(unsigned Value) {
6254 SafetyStackThreadSize = Value;
6255}
6256
6257}
6258
6259void clang::setThreadBackgroundPriority() {
6260 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6261 return;
6262
6263 // FIXME: Move to llvm/Support and make it cross-platform.
6264#ifdef __APPLE__
6265 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6266#endif
6267}
6268
6269void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6270 if (!Unit)
6271 return;
6272
6273 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6274 DEnd = Unit->stored_diag_end();
6275 D != DEnd; ++D) {
6276 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6277 CXString Msg = clang_formatDiagnostic(&Diag,
6278 clang_defaultDiagnosticDisplayOptions());
6279 fprintf(stderr, "%s\n", clang_getCString(Msg));
6280 clang_disposeString(Msg);
6281 }
6282#ifdef LLVM_ON_WIN32
6283 // On Windows, force a flush, since there may be multiple copies of
6284 // stderr and stdout in the file system, all with different buffers
6285 // but writing to the same device.
6286 fflush(stderr);
6287#endif
6288}
6289
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006290MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6291 SourceLocation MacroDefLoc,
6292 CXTranslationUnit TU){
6293 if (MacroDefLoc.isInvalid() || !TU)
6294 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006295 if (!II.hadMacroDefinition())
6296 return 0;
6297
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006299 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006300 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
6301 while (MD) {
6302 if (MacroDefLoc == MD->getInfo()->getDefinitionLoc())
6303 return MD->getInfo();
6304 MD = MD->getPrevious();
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006305 }
6306
6307 return 0;
6308}
6309
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006310const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6311 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006312 if (!MacroDef || !TU)
6313 return 0;
6314 const IdentifierInfo *II = MacroDef->getName();
6315 if (!II)
6316 return 0;
6317
6318 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6319}
6320
6321MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6322 const Token &Tok,
6323 CXTranslationUnit TU) {
6324 if (!MI || !TU)
6325 return 0;
6326 if (Tok.isNot(tok::raw_identifier))
6327 return 0;
6328
6329 if (MI->getNumTokens() == 0)
6330 return 0;
6331 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6332 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006333 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006334
6335 // Check that the token is inside the definition and not its argument list.
6336 SourceManager &SM = Unit->getSourceManager();
6337 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6338 return 0;
6339 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6340 return 0;
6341
6342 Preprocessor &PP = Unit->getPreprocessor();
6343 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6344 if (!PPRec)
6345 return 0;
6346
6347 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6348 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6349 if (!II.hadMacroDefinition())
6350 return 0;
6351
6352 // Check that the identifier is not one of the macro arguments.
6353 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6354 return 0;
6355
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006356 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6357 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006358 return 0;
6359
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006360 return PPRec->findMacroDefinition(InnerMD->getInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006361}
6362
6363MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6364 SourceLocation Loc,
6365 CXTranslationUnit TU) {
6366 if (Loc.isInvalid() || !MI || !TU)
6367 return 0;
6368
6369 if (MI->getNumTokens() == 0)
6370 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006371 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006372 Preprocessor &PP = Unit->getPreprocessor();
6373 if (!PP.getPreprocessingRecord())
6374 return 0;
6375 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6376 Token Tok;
6377 if (PP.getRawToken(Loc, Tok))
6378 return 0;
6379
6380 return checkForMacroInMacroDefinition(MI, Tok, TU);
6381}
6382
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006383extern "C" {
6384
6385CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006386 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006387}
6388
6389} // end: extern "C"
6390
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006391Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6392 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006393 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006394 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006395 if (Unit->isMainFileAST())
6396 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006397 return *this;
6398 }
6399 }
6400
6401 LogOS << "<NULL TU>";
6402 return *this;
6403}
6404
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006405Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6406 *this << FE->getName();
6407 return *this;
6408}
6409
6410Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6411 CXString cursorName = clang_getCursorDisplayName(cursor);
6412 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6413 clang_disposeString(cursorName);
6414 return *this;
6415}
6416
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006417Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6418 CXFile File;
6419 unsigned Line, Column;
6420 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6421 CXString FileName = clang_getFileName(File);
6422 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6423 clang_disposeString(FileName);
6424 return *this;
6425}
6426
6427Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6428 CXSourceLocation BLoc = clang_getRangeStart(range);
6429 CXSourceLocation ELoc = clang_getRangeEnd(range);
6430
6431 CXFile BFile;
6432 unsigned BLine, BColumn;
6433 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6434
6435 CXFile EFile;
6436 unsigned ELine, EColumn;
6437 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6438
6439 CXString BFileName = clang_getFileName(BFile);
6440 if (BFile == EFile) {
6441 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6442 BLine, BColumn, ELine, EColumn);
6443 } else {
6444 CXString EFileName = clang_getFileName(EFile);
6445 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6446 BLine, BColumn)
6447 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6448 ELine, EColumn);
6449 clang_disposeString(EFileName);
6450 }
6451 clang_disposeString(BFileName);
6452 return *this;
6453}
6454
6455Logger &cxindex::Logger::operator<<(CXString Str) {
6456 *this << clang_getCString(Str);
6457 return *this;
6458}
6459
6460Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6461 LogOS << Fmt;
6462 return *this;
6463}
6464
6465cxindex::Logger::~Logger() {
6466 LogOS.flush();
6467
6468 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6469
6470 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6471
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006472 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006473 OS << "[libclang:" << Name << ':';
6474
6475 // FIXME: Portability.
6476#if HAVE_PTHREAD_H && __APPLE__
6477 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6478 OS << tid << ':';
6479#endif
6480
6481 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6482 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6483 OS << Msg.str() << '\n';
6484
6485 if (Trace) {
6486 llvm::sys::PrintStackTrace(stderr);
6487 OS << "--------------------------------------------------\n";
6488 }
6489}