blob: 59a7e8d112527323d139dc1a805283ab6c794ed7 [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
Chad Rosier90836282013-03-27 18:28:23 +00002459static void fatal_error_handler(void *user_data, const std::string& reason,
2460 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002461 // Write the result out to stderr avoiding errs() because raw_ostreams can
2462 // call report_fatal_error.
2463 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2464 ::abort();
2465}
2466
2467extern "C" {
2468CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2469 int displayDiagnostics) {
2470 // Disable pretty stack trace functionality, which will otherwise be a very
2471 // poor citizen of the world and set up all sorts of signal handlers.
2472 llvm::DisablePrettyStackTrace = true;
2473
2474 // We use crash recovery to make some of our APIs more reliable, implicitly
2475 // enable it.
2476 llvm::CrashRecoveryContext::Enable();
2477
2478 // Enable support for multithreading in LLVM.
2479 {
2480 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2481 if (!EnabledMultithreading) {
2482 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2483 llvm::llvm_start_multithreaded();
2484 EnabledMultithreading = true;
2485 }
2486 }
2487
2488 CIndexer *CIdxr = new CIndexer();
2489 if (excludeDeclarationsFromPCH)
2490 CIdxr->setOnlyLocalDecls();
2491 if (displayDiagnostics)
2492 CIdxr->setDisplayDiagnostics();
2493
2494 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2495 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2496 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2497 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2498 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2499 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2500
2501 return CIdxr;
2502}
2503
2504void clang_disposeIndex(CXIndex CIdx) {
2505 if (CIdx)
2506 delete static_cast<CIndexer *>(CIdx);
2507}
2508
2509void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2510 if (CIdx)
2511 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2512}
2513
2514unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2515 if (CIdx)
2516 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2517 return 0;
2518}
2519
2520void clang_toggleCrashRecovery(unsigned isEnabled) {
2521 if (isEnabled)
2522 llvm::CrashRecoveryContext::Enable();
2523 else
2524 llvm::CrashRecoveryContext::Disable();
2525}
2526
2527CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2528 const char *ast_filename) {
2529 if (!CIdx)
2530 return 0;
2531
2532 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2533 FileSystemOptions FileSystemOpts;
2534
2535 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2536 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2537 CXXIdx->getOnlyLocalDecls(),
2538 0, 0,
2539 /*CaptureDiagnostics=*/true,
2540 /*AllowPCHWithCompilerErrors=*/true,
2541 /*UserFilesAreVolatile=*/true);
2542 return MakeCXTranslationUnit(CXXIdx, TU);
2543}
2544
2545unsigned clang_defaultEditingTranslationUnitOptions() {
2546 return CXTranslationUnit_PrecompiledPreamble |
2547 CXTranslationUnit_CacheCompletionResults;
2548}
2549
2550CXTranslationUnit
2551clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2552 const char *source_filename,
2553 int num_command_line_args,
2554 const char * const *command_line_args,
2555 unsigned num_unsaved_files,
2556 struct CXUnsavedFile *unsaved_files) {
2557 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2558 return clang_parseTranslationUnit(CIdx, source_filename,
2559 command_line_args, num_command_line_args,
2560 unsaved_files, num_unsaved_files,
2561 Options);
2562}
2563
2564struct ParseTranslationUnitInfo {
2565 CXIndex CIdx;
2566 const char *source_filename;
2567 const char *const *command_line_args;
2568 int num_command_line_args;
2569 struct CXUnsavedFile *unsaved_files;
2570 unsigned num_unsaved_files;
2571 unsigned options;
2572 CXTranslationUnit result;
2573};
2574static void clang_parseTranslationUnit_Impl(void *UserData) {
2575 ParseTranslationUnitInfo *PTUI =
2576 static_cast<ParseTranslationUnitInfo*>(UserData);
2577 CXIndex CIdx = PTUI->CIdx;
2578 const char *source_filename = PTUI->source_filename;
2579 const char * const *command_line_args = PTUI->command_line_args;
2580 int num_command_line_args = PTUI->num_command_line_args;
2581 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2582 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2583 unsigned options = PTUI->options;
2584 PTUI->result = 0;
2585
2586 if (!CIdx)
2587 return;
2588
2589 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2590
2591 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2592 setThreadBackgroundPriority();
2593
2594 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2595 // FIXME: Add a flag for modules.
2596 TranslationUnitKind TUKind
2597 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2598 bool CacheCodeCompetionResults
2599 = options & CXTranslationUnit_CacheCompletionResults;
2600 bool IncludeBriefCommentsInCodeCompletion
2601 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2602 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2603 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2604
2605 // Configure the diagnostics.
2606 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002607 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002608
2609 // Recover resources if we crash before exiting this function.
2610 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2611 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2612 DiagCleanup(Diags.getPtr());
2613
2614 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2615 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2616
2617 // Recover resources if we crash before exiting this function.
2618 llvm::CrashRecoveryContextCleanupRegistrar<
2619 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2620
2621 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2622 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2623 const llvm::MemoryBuffer *Buffer
2624 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2625 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2626 Buffer));
2627 }
2628
2629 OwningPtr<std::vector<const char *> >
2630 Args(new std::vector<const char*>());
2631
2632 // Recover resources if we crash before exiting this method.
2633 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2634 ArgsCleanup(Args.get());
2635
2636 // Since the Clang C library is primarily used by batch tools dealing with
2637 // (often very broken) source code, where spell-checking can have a
2638 // significant negative impact on performance (particularly when
2639 // precompiled headers are involved), we disable it by default.
2640 // Only do this if we haven't found a spell-checking-related argument.
2641 bool FoundSpellCheckingArgument = false;
2642 for (int I = 0; I != num_command_line_args; ++I) {
2643 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2644 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2645 FoundSpellCheckingArgument = true;
2646 break;
2647 }
2648 }
2649 if (!FoundSpellCheckingArgument)
2650 Args->push_back("-fno-spell-checking");
2651
2652 Args->insert(Args->end(), command_line_args,
2653 command_line_args + num_command_line_args);
2654
2655 // The 'source_filename' argument is optional. If the caller does not
2656 // specify it then it is assumed that the source file is specified
2657 // in the actual argument list.
2658 // Put the source file after command_line_args otherwise if '-x' flag is
2659 // present it will be unused.
2660 if (source_filename)
2661 Args->push_back(source_filename);
2662
2663 // Do we need the detailed preprocessing record?
2664 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2665 Args->push_back("-Xclang");
2666 Args->push_back("-detailed-preprocessing-record");
2667 }
2668
2669 unsigned NumErrors = Diags->getClient()->getNumErrors();
2670 OwningPtr<ASTUnit> ErrUnit;
2671 OwningPtr<ASTUnit> Unit(
2672 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2673 /* vector::data() not portable */,
2674 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2675 Diags,
2676 CXXIdx->getClangResourcesPath(),
2677 CXXIdx->getOnlyLocalDecls(),
2678 /*CaptureDiagnostics=*/true,
2679 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2680 RemappedFiles->size(),
2681 /*RemappedFilesKeepOriginalName=*/true,
2682 PrecompilePreamble,
2683 TUKind,
2684 CacheCodeCompetionResults,
2685 IncludeBriefCommentsInCodeCompletion,
2686 /*AllowPCHWithCompilerErrors=*/true,
2687 SkipFunctionBodies,
2688 /*UserFilesAreVolatile=*/true,
2689 ForSerialization,
2690 &ErrUnit));
2691
2692 if (NumErrors != Diags->getClient()->getNumErrors()) {
2693 // Make sure to check that 'Unit' is non-NULL.
2694 if (CXXIdx->getDisplayDiagnostics())
2695 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2696 }
2697
2698 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2699}
2700CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2701 const char *source_filename,
2702 const char * const *command_line_args,
2703 int num_command_line_args,
2704 struct CXUnsavedFile *unsaved_files,
2705 unsigned num_unsaved_files,
2706 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002707 LOG_FUNC_SECTION {
2708 *Log << source_filename << ": ";
2709 for (int i = 0; i != num_command_line_args; ++i)
2710 *Log << command_line_args[i] << " ";
2711 }
2712
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002713 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2714 num_command_line_args, unsaved_files,
2715 num_unsaved_files, options, 0 };
2716 llvm::CrashRecoveryContext CRC;
2717
2718 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2719 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2720 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2721 fprintf(stderr, " 'command_line_args' : [");
2722 for (int i = 0; i != num_command_line_args; ++i) {
2723 if (i)
2724 fprintf(stderr, ", ");
2725 fprintf(stderr, "'%s'", command_line_args[i]);
2726 }
2727 fprintf(stderr, "],\n");
2728 fprintf(stderr, " 'unsaved_files' : [");
2729 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2730 if (i)
2731 fprintf(stderr, ", ");
2732 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2733 unsaved_files[i].Length);
2734 }
2735 fprintf(stderr, "],\n");
2736 fprintf(stderr, " 'options' : %d,\n", options);
2737 fprintf(stderr, "}\n");
2738
2739 return 0;
2740 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2741 PrintLibclangResourceUsage(PTUI.result);
2742 }
2743
2744 return PTUI.result;
2745}
2746
2747unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2748 return CXSaveTranslationUnit_None;
2749}
2750
2751namespace {
2752
2753struct SaveTranslationUnitInfo {
2754 CXTranslationUnit TU;
2755 const char *FileName;
2756 unsigned options;
2757 CXSaveError result;
2758};
2759
2760}
2761
2762static void clang_saveTranslationUnit_Impl(void *UserData) {
2763 SaveTranslationUnitInfo *STUI =
2764 static_cast<SaveTranslationUnitInfo*>(UserData);
2765
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002766 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002767 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2768 setThreadBackgroundPriority();
2769
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002770 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002771 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2772}
2773
2774int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2775 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002776 LOG_FUNC_SECTION {
2777 *Log << TU << ' ' << FileName;
2778 }
2779
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002780 if (!TU)
2781 return CXSaveError_InvalidTU;
2782
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002783 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002784 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2785 if (!CXXUnit->hasSema())
2786 return CXSaveError_InvalidTU;
2787
2788 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2789
2790 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2791 getenv("LIBCLANG_NOTHREADS")) {
2792 clang_saveTranslationUnit_Impl(&STUI);
2793
2794 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2795 PrintLibclangResourceUsage(TU);
2796
2797 return STUI.result;
2798 }
2799
2800 // We have an AST that has invalid nodes due to compiler errors.
2801 // Use a crash recovery thread for protection.
2802
2803 llvm::CrashRecoveryContext CRC;
2804
2805 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2806 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2807 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2808 fprintf(stderr, " 'options' : %d,\n", options);
2809 fprintf(stderr, "}\n");
2810
2811 return CXSaveError_Unknown;
2812
2813 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2814 PrintLibclangResourceUsage(TU);
2815 }
2816
2817 return STUI.result;
2818}
2819
2820void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2821 if (CTUnit) {
2822 // If the translation unit has been marked as unsafe to free, just discard
2823 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002824 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002825 return;
2826
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002827 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002828 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002829 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2830 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002831 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002832 delete CTUnit;
2833 }
2834}
2835
2836unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2837 return CXReparse_None;
2838}
2839
2840struct ReparseTranslationUnitInfo {
2841 CXTranslationUnit TU;
2842 unsigned num_unsaved_files;
2843 struct CXUnsavedFile *unsaved_files;
2844 unsigned options;
2845 int result;
2846};
2847
2848static void clang_reparseTranslationUnit_Impl(void *UserData) {
2849 ReparseTranslationUnitInfo *RTUI =
2850 static_cast<ReparseTranslationUnitInfo*>(UserData);
2851 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002852 if (!TU)
2853 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002854
2855 // Reset the associated diagnostics.
2856 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2857 TU->Diagnostics = 0;
2858
2859 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2860 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2861 unsigned options = RTUI->options;
2862 (void) options;
2863 RTUI->result = 1;
2864
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002865 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002866 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2867 setThreadBackgroundPriority();
2868
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002869 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002870 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2871
2872 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2873 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2874
2875 // Recover resources if we crash before exiting this function.
2876 llvm::CrashRecoveryContextCleanupRegistrar<
2877 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2878
2879 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2880 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2881 const llvm::MemoryBuffer *Buffer
2882 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2883 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2884 Buffer));
2885 }
2886
2887 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2888 RemappedFiles->size()))
2889 RTUI->result = 0;
2890}
2891
2892int clang_reparseTranslationUnit(CXTranslationUnit TU,
2893 unsigned num_unsaved_files,
2894 struct CXUnsavedFile *unsaved_files,
2895 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002896 LOG_FUNC_SECTION {
2897 *Log << TU;
2898 }
2899
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002900 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2901 options, 0 };
2902
2903 if (getenv("LIBCLANG_NOTHREADS")) {
2904 clang_reparseTranslationUnit_Impl(&RTUI);
2905 return RTUI.result;
2906 }
2907
2908 llvm::CrashRecoveryContext CRC;
2909
2910 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2911 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002912 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002913 return 1;
2914 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2915 PrintLibclangResourceUsage(TU);
2916
2917 return RTUI.result;
2918}
2919
2920
2921CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2922 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002923 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002924
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002925 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002926 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002927}
2928
2929CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002930 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002931 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2932}
2933
2934} // end: extern "C"
2935
2936//===----------------------------------------------------------------------===//
2937// CXFile Operations.
2938//===----------------------------------------------------------------------===//
2939
2940extern "C" {
2941CXString clang_getFileName(CXFile SFile) {
2942 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002943 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002944
2945 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002946 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002947}
2948
2949time_t clang_getFileTime(CXFile SFile) {
2950 if (!SFile)
2951 return 0;
2952
2953 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2954 return FEnt->getModificationTime();
2955}
2956
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002957CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2958 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002959 return 0;
2960
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002961 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002962
2963 FileManager &FMgr = CXXUnit->getFileManager();
2964 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2965}
2966
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002967unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2968 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002969 return 0;
2970
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002971 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002972 FileEntry *FEnt = static_cast<FileEntry *>(file);
2973 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2974 .isFileMultipleIncludeGuarded(FEnt);
2975}
2976
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002977int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2978 if (!file || !outID)
2979 return 1;
2980
2981#ifdef LLVM_ON_WIN32
2982 return 1; // inodes not supported on windows.
2983#else
2984 FileEntry *FEnt = static_cast<FileEntry *>(file);
2985 outID->data[0] = FEnt->getDevice();
2986 outID->data[1] = FEnt->getInode();
2987 outID->data[2] = FEnt->getModificationTime();
2988 return 0;
2989#endif
2990}
2991
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002992} // end: extern "C"
2993
2994//===----------------------------------------------------------------------===//
2995// CXCursor Operations.
2996//===----------------------------------------------------------------------===//
2997
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002998static const Decl *getDeclFromExpr(const Stmt *E) {
2999 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003000 return getDeclFromExpr(CE->getSubExpr());
3001
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003002 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003003 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003004 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003005 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003006 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003007 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003008 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003009 if (PRE->isExplicitProperty())
3010 return PRE->getExplicitProperty();
3011 // It could be messaging both getter and setter as in:
3012 // ++myobj.myprop;
3013 // in which case prefer to associate the setter since it is less obvious
3014 // from inspecting the source that the setter is going to get called.
3015 if (PRE->isMessagingSetter())
3016 return PRE->getImplicitPropertySetter();
3017 return PRE->getImplicitPropertyGetter();
3018 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003019 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003020 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003021 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003022 if (Expr *Src = OVE->getSourceExpr())
3023 return getDeclFromExpr(Src);
3024
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003025 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003026 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003027 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003028 if (!CE->isElidable())
3029 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003030 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003031 return OME->getMethodDecl();
3032
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003033 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003034 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003035 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003036 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3037 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003038 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003039 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3040 isa<ParmVarDecl>(SizeOfPack->getPack()))
3041 return SizeOfPack->getPack();
3042
3043 return 0;
3044}
3045
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003046static SourceLocation getLocationFromExpr(const Expr *E) {
3047 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003048 return getLocationFromExpr(CE->getSubExpr());
3049
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003050 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003052 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003053 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003054 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003055 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003056 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003057 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003058 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003059 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003060 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003061 return PropRef->getLocation();
3062
3063 return E->getLocStart();
3064}
3065
3066extern "C" {
3067
3068unsigned clang_visitChildren(CXCursor parent,
3069 CXCursorVisitor visitor,
3070 CXClientData client_data) {
3071 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3072 /*VisitPreprocessorLast=*/false);
3073 return CursorVis.VisitChildren(parent);
3074}
3075
3076#ifndef __has_feature
3077#define __has_feature(x) 0
3078#endif
3079#if __has_feature(blocks)
3080typedef enum CXChildVisitResult
3081 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3082
3083static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3084 CXClientData client_data) {
3085 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3086 return block(cursor, parent);
3087}
3088#else
3089// If we are compiled with a compiler that doesn't have native blocks support,
3090// define and call the block manually, so the
3091typedef struct _CXChildVisitResult
3092{
3093 void *isa;
3094 int flags;
3095 int reserved;
3096 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3097 CXCursor);
3098} *CXCursorVisitorBlock;
3099
3100static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3101 CXClientData client_data) {
3102 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3103 return block->invoke(block, cursor, parent);
3104}
3105#endif
3106
3107
3108unsigned clang_visitChildrenWithBlock(CXCursor parent,
3109 CXCursorVisitorBlock block) {
3110 return clang_visitChildren(parent, visitWithBlock, block);
3111}
3112
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003113static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003114 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003115 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003116
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003117 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003118 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003119 if (const ObjCPropertyImplDecl *PropImpl =
3120 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003121 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003122 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003123
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003124 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003125 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003126 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003127
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003128 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003129 }
3130
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003131 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003132 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003134 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3136 // and returns different names. NamedDecl returns the class name and
3137 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003138 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003139
3140 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003141 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003142
3143 SmallString<1024> S;
3144 llvm::raw_svector_ostream os(S);
3145 ND->printName(os);
3146
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003147 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003148}
3149
3150CXString clang_getCursorSpelling(CXCursor C) {
3151 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003152 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003153
3154 if (clang_isReference(C.kind)) {
3155 switch (C.kind) {
3156 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003157 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003158 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003159 }
3160 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003161 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003162 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003163 }
3164 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003165 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003166 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003167 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003168 }
3169 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003170 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003171 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003172 }
3173 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003174 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003175 assert(Type && "Missing type decl");
3176
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003177 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003178 getAsString());
3179 }
3180 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003181 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003182 assert(Template && "Missing template decl");
3183
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003184 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003185 }
3186
3187 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003188 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003189 assert(NS && "Missing namespace decl");
3190
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003191 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 }
3193
3194 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003195 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003196 assert(Field && "Missing member decl");
3197
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003198 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 }
3200
3201 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003202 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203 assert(Label && "Missing label");
3204
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003205 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003206 }
3207
3208 case CXCursor_OverloadedDeclRef: {
3209 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003210 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3211 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003212 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003213 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003214 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003215 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003216 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003217 OverloadedTemplateStorage *Ovl
3218 = Storage.get<OverloadedTemplateStorage*>();
3219 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003220 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003221 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003222 }
3223
3224 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003225 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003226 assert(Var && "Missing variable decl");
3227
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003228 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003229 }
3230
3231 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003232 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003233 }
3234 }
3235
3236 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003237 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003238 if (D)
3239 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003240 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003241 }
3242
3243 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003244 const Stmt *S = getCursorStmt(C);
3245 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003246 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003247
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003248 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003249 }
3250
3251 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003252 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003253 ->getNameStart());
3254
3255 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003256 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003257 ->getNameStart());
3258
3259 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003260 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003261
3262 if (clang_isDeclaration(C.kind))
3263 return getDeclSpelling(getCursorDecl(C));
3264
3265 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003266 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003267 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003268 }
3269
3270 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003271 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003272 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003273 }
3274
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003275 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003276}
3277
3278CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3279 unsigned pieceIndex,
3280 unsigned options) {
3281 if (clang_Cursor_isNull(C))
3282 return clang_getNullRange();
3283
3284 ASTContext &Ctx = getCursorContext(C);
3285
3286 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003287 const Stmt *S = getCursorStmt(C);
3288 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003289 if (pieceIndex > 0)
3290 return clang_getNullRange();
3291 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3292 }
3293
3294 return clang_getNullRange();
3295 }
3296
3297 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003298 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003299 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3300 if (pieceIndex >= ME->getNumSelectorLocs())
3301 return clang_getNullRange();
3302 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3303 }
3304 }
3305
3306 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3307 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003308 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003309 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3310 if (pieceIndex >= MD->getNumSelectorLocs())
3311 return clang_getNullRange();
3312 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3313 }
3314 }
3315
3316 if (C.kind == CXCursor_ObjCCategoryDecl ||
3317 C.kind == CXCursor_ObjCCategoryImplDecl) {
3318 if (pieceIndex > 0)
3319 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003320 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003321 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3322 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003323 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003324 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3325 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3326 }
3327
3328 if (C.kind == CXCursor_ModuleImportDecl) {
3329 if (pieceIndex > 0)
3330 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003331 if (const ImportDecl *ImportD =
3332 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003333 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3334 if (!Locs.empty())
3335 return cxloc::translateSourceRange(Ctx,
3336 SourceRange(Locs.front(), Locs.back()));
3337 }
3338 return clang_getNullRange();
3339 }
3340
3341 // FIXME: A CXCursor_InclusionDirective should give the location of the
3342 // filename, but we don't keep track of this.
3343
3344 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3345 // but we don't keep track of this.
3346
3347 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3348 // but we don't keep track of this.
3349
3350 // Default handling, give the location of the cursor.
3351
3352 if (pieceIndex > 0)
3353 return clang_getNullRange();
3354
3355 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3356 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3357 return cxloc::translateSourceRange(Ctx, Loc);
3358}
3359
3360CXString clang_getCursorDisplayName(CXCursor C) {
3361 if (!clang_isDeclaration(C.kind))
3362 return clang_getCursorSpelling(C);
3363
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003364 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003365 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003366 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003367
3368 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003369 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003370 D = FunTmpl->getTemplatedDecl();
3371
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003372 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003373 SmallString<64> Str;
3374 llvm::raw_svector_ostream OS(Str);
3375 OS << *Function;
3376 if (Function->getPrimaryTemplate())
3377 OS << "<>";
3378 OS << "(";
3379 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3380 if (I)
3381 OS << ", ";
3382 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3383 }
3384
3385 if (Function->isVariadic()) {
3386 if (Function->getNumParams())
3387 OS << ", ";
3388 OS << "...";
3389 }
3390 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003391 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003392 }
3393
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003394 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003395 SmallString<64> Str;
3396 llvm::raw_svector_ostream OS(Str);
3397 OS << *ClassTemplate;
3398 OS << "<";
3399 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3400 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3401 if (I)
3402 OS << ", ";
3403
3404 NamedDecl *Param = Params->getParam(I);
3405 if (Param->getIdentifier()) {
3406 OS << Param->getIdentifier()->getName();
3407 continue;
3408 }
3409
3410 // There is no parameter name, which makes this tricky. Try to come up
3411 // with something useful that isn't too long.
3412 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3413 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3414 else if (NonTypeTemplateParmDecl *NTTP
3415 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3416 OS << NTTP->getType().getAsString(Policy);
3417 else
3418 OS << "template<...> class";
3419 }
3420
3421 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003422 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003423 }
3424
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003425 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003426 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3427 // If the type was explicitly written, use that.
3428 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003429 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003430
Benjamin Kramer5eada842013-02-22 15:46:01 +00003431 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003432 llvm::raw_svector_ostream OS(Str);
3433 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003434 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003435 ClassSpec->getTemplateArgs().data(),
3436 ClassSpec->getTemplateArgs().size(),
3437 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003438 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003439 }
3440
3441 return clang_getCursorSpelling(C);
3442}
3443
3444CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3445 switch (Kind) {
3446 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003447 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003448 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003449 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003450 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003451 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003452 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003453 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003454 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003455 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003456 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003457 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003458 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003459 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003460 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003461 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003462 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003463 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003464 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003465 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003466 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003467 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003468 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003469 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003470 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003471 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003472 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003473 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003474 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003475 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003476 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003477 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003478 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003479 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003480 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003481 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003482 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003483 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003484 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003485 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003486 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003487 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003488 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003489 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003490 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003491 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003492 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003493 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003494 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003495 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003496 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003497 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003498 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003499 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003500 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003501 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003502 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003503 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003504 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003505 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003506 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003507 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003508 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003509 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003511 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003512 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003513 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003514 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003515 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003516 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003517 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003518 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003519 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003520 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003521 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003522 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003523 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003524 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003525 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003526 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("ObjCBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 }
3739
3740 llvm_unreachable("Unhandled CXCursorKind");
3741}
3742
3743struct GetCursorData {
3744 SourceLocation TokenBeginLoc;
3745 bool PointsAtMacroArgExpansion;
3746 bool VisitedObjCPropertyImplDecl;
3747 SourceLocation VisitedDeclaratorDeclStartLoc;
3748 CXCursor &BestCursor;
3749
3750 GetCursorData(SourceManager &SM,
3751 SourceLocation tokenBegin, CXCursor &outputCursor)
3752 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3753 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3754 VisitedObjCPropertyImplDecl = false;
3755 }
3756};
3757
3758static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3759 CXCursor parent,
3760 CXClientData client_data) {
3761 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3762 CXCursor *BestCursor = &Data->BestCursor;
3763
3764 // If we point inside a macro argument we should provide info of what the
3765 // token is so use the actual cursor, don't replace it with a macro expansion
3766 // cursor.
3767 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3768 return CXChildVisit_Recurse;
3769
3770 if (clang_isDeclaration(cursor.kind)) {
3771 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003772 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003773 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3774 if (MD->isImplicit())
3775 return CXChildVisit_Break;
3776
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003777 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003778 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3779 // Check that when we have multiple @class references in the same line,
3780 // that later ones do not override the previous ones.
3781 // If we have:
3782 // @class Foo, Bar;
3783 // source ranges for both start at '@', so 'Bar' will end up overriding
3784 // 'Foo' even though the cursor location was at 'Foo'.
3785 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3786 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003787 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003788 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3789 if (PrevID != ID &&
3790 !PrevID->isThisDeclarationADefinition() &&
3791 !ID->isThisDeclarationADefinition())
3792 return CXChildVisit_Break;
3793 }
3794
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003795 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3797 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3798 // Check that when we have multiple declarators in the same line,
3799 // that later ones do not override the previous ones.
3800 // If we have:
3801 // int Foo, Bar;
3802 // source ranges for both start at 'int', so 'Bar' will end up overriding
3803 // 'Foo' even though the cursor location was at 'Foo'.
3804 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3805 return CXChildVisit_Break;
3806 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3807
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003808 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003809 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3810 (void)PropImp;
3811 // Check that when we have multiple @synthesize in the same line,
3812 // that later ones do not override the previous ones.
3813 // If we have:
3814 // @synthesize Foo, Bar;
3815 // source ranges for both start at '@', so 'Bar' will end up overriding
3816 // 'Foo' even though the cursor location was at 'Foo'.
3817 if (Data->VisitedObjCPropertyImplDecl)
3818 return CXChildVisit_Break;
3819 Data->VisitedObjCPropertyImplDecl = true;
3820 }
3821 }
3822
3823 if (clang_isExpression(cursor.kind) &&
3824 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003825 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003826 // Avoid having the cursor of an expression replace the declaration cursor
3827 // when the expression source range overlaps the declaration range.
3828 // This can happen for C++ constructor expressions whose range generally
3829 // include the variable declaration, e.g.:
3830 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3831 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3832 D->getLocation() == Data->TokenBeginLoc)
3833 return CXChildVisit_Break;
3834 }
3835 }
3836
3837 // If our current best cursor is the construction of a temporary object,
3838 // don't replace that cursor with a type reference, because we want
3839 // clang_getCursor() to point at the constructor.
3840 if (clang_isExpression(BestCursor->kind) &&
3841 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3842 cursor.kind == CXCursor_TypeRef) {
3843 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3844 // as having the actual point on the type reference.
3845 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3846 return CXChildVisit_Recurse;
3847 }
3848
3849 *BestCursor = cursor;
3850 return CXChildVisit_Recurse;
3851}
3852
3853CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3854 if (!TU)
3855 return clang_getNullCursor();
3856
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003857 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003858 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3859
3860 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3861 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3862
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003863 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003864 CXFile SearchFile;
3865 unsigned SearchLine, SearchColumn;
3866 CXFile ResultFile;
3867 unsigned ResultLine, ResultColumn;
3868 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3869 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3870 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3871
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003872 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3873 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003874 &ResultColumn, 0);
3875 SearchFileName = clang_getFileName(SearchFile);
3876 ResultFileName = clang_getFileName(ResultFile);
3877 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3878 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003879 *Log << llvm::format("(%s:%d:%d) = %s",
3880 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3881 clang_getCString(KindSpelling))
3882 << llvm::format("(%s:%d:%d):%s%s",
3883 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3884 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003885 clang_disposeString(SearchFileName);
3886 clang_disposeString(ResultFileName);
3887 clang_disposeString(KindSpelling);
3888 clang_disposeString(USR);
3889
3890 CXCursor Definition = clang_getCursorDefinition(Result);
3891 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3892 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3893 CXString DefinitionKindSpelling
3894 = clang_getCursorKindSpelling(Definition.kind);
3895 CXFile DefinitionFile;
3896 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003897 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003898 &DefinitionLine, &DefinitionColumn, 0);
3899 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003900 *Log << llvm::format(" -> %s(%s:%d:%d)",
3901 clang_getCString(DefinitionKindSpelling),
3902 clang_getCString(DefinitionFileName),
3903 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003904 clang_disposeString(DefinitionFileName);
3905 clang_disposeString(DefinitionKindSpelling);
3906 }
3907 }
3908
3909 return Result;
3910}
3911
3912CXCursor clang_getNullCursor(void) {
3913 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3914}
3915
3916unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003917 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3918 // can't set consistently. For example, when visiting a DeclStmt we will set
3919 // it but we don't set it on the result of clang_getCursorDefinition for
3920 // a reference of the same declaration.
3921 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3922 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3923 // to provide that kind of info.
3924 if (clang_isDeclaration(X.kind))
3925 X.data[1] = 0;
3926 if (clang_isDeclaration(Y.kind))
3927 Y.data[1] = 0;
3928
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003929 return X == Y;
3930}
3931
3932unsigned clang_hashCursor(CXCursor C) {
3933 unsigned Index = 0;
3934 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3935 Index = 1;
3936
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003937 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003938 std::make_pair(C.kind, C.data[Index]));
3939}
3940
3941unsigned clang_isInvalid(enum CXCursorKind K) {
3942 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3943}
3944
3945unsigned clang_isDeclaration(enum CXCursorKind K) {
3946 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3947 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3948}
3949
3950unsigned clang_isReference(enum CXCursorKind K) {
3951 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3952}
3953
3954unsigned clang_isExpression(enum CXCursorKind K) {
3955 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3956}
3957
3958unsigned clang_isStatement(enum CXCursorKind K) {
3959 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3960}
3961
3962unsigned clang_isAttribute(enum CXCursorKind K) {
3963 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3964}
3965
3966unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3967 return K == CXCursor_TranslationUnit;
3968}
3969
3970unsigned clang_isPreprocessing(enum CXCursorKind K) {
3971 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3972}
3973
3974unsigned clang_isUnexposed(enum CXCursorKind K) {
3975 switch (K) {
3976 case CXCursor_UnexposedDecl:
3977 case CXCursor_UnexposedExpr:
3978 case CXCursor_UnexposedStmt:
3979 case CXCursor_UnexposedAttr:
3980 return true;
3981 default:
3982 return false;
3983 }
3984}
3985
3986CXCursorKind clang_getCursorKind(CXCursor C) {
3987 return C.kind;
3988}
3989
3990CXSourceLocation clang_getCursorLocation(CXCursor C) {
3991 if (clang_isReference(C.kind)) {
3992 switch (C.kind) {
3993 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003994 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003995 = getCursorObjCSuperClassRef(C);
3996 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3997 }
3998
3999 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004000 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004001 = getCursorObjCProtocolRef(C);
4002 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4003 }
4004
4005 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004006 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004007 = getCursorObjCClassRef(C);
4008 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4009 }
4010
4011 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004012 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004013 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4014 }
4015
4016 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004017 std::pair<const TemplateDecl *, SourceLocation> P =
4018 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004019 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4020 }
4021
4022 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004023 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004024 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4025 }
4026
4027 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004028 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004029 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4030 }
4031
4032 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004033 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004034 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4035 }
4036
4037 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004038 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004039 if (!BaseSpec)
4040 return clang_getNullLocation();
4041
4042 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4043 return cxloc::translateSourceLocation(getCursorContext(C),
4044 TSInfo->getTypeLoc().getBeginLoc());
4045
4046 return cxloc::translateSourceLocation(getCursorContext(C),
4047 BaseSpec->getLocStart());
4048 }
4049
4050 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004051 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004052 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4053 }
4054
4055 case CXCursor_OverloadedDeclRef:
4056 return cxloc::translateSourceLocation(getCursorContext(C),
4057 getCursorOverloadedDeclRef(C).second);
4058
4059 default:
4060 // FIXME: Need a way to enumerate all non-reference cases.
4061 llvm_unreachable("Missed a reference kind");
4062 }
4063 }
4064
4065 if (clang_isExpression(C.kind))
4066 return cxloc::translateSourceLocation(getCursorContext(C),
4067 getLocationFromExpr(getCursorExpr(C)));
4068
4069 if (clang_isStatement(C.kind))
4070 return cxloc::translateSourceLocation(getCursorContext(C),
4071 getCursorStmt(C)->getLocStart());
4072
4073 if (C.kind == CXCursor_PreprocessingDirective) {
4074 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4075 return cxloc::translateSourceLocation(getCursorContext(C), L);
4076 }
4077
4078 if (C.kind == CXCursor_MacroExpansion) {
4079 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004080 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004081 return cxloc::translateSourceLocation(getCursorContext(C), L);
4082 }
4083
4084 if (C.kind == CXCursor_MacroDefinition) {
4085 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4086 return cxloc::translateSourceLocation(getCursorContext(C), L);
4087 }
4088
4089 if (C.kind == CXCursor_InclusionDirective) {
4090 SourceLocation L
4091 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4092 return cxloc::translateSourceLocation(getCursorContext(C), L);
4093 }
4094
4095 if (!clang_isDeclaration(C.kind))
4096 return clang_getNullLocation();
4097
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004098 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004099 if (!D)
4100 return clang_getNullLocation();
4101
4102 SourceLocation Loc = D->getLocation();
4103 // FIXME: Multiple variables declared in a single declaration
4104 // currently lack the information needed to correctly determine their
4105 // ranges when accounting for the type-specifier. We use context
4106 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4107 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004108 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004109 if (!cxcursor::isFirstInDeclGroup(C))
4110 Loc = VD->getLocation();
4111 }
4112
4113 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004114 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004115 Loc = MD->getSelectorStartLoc();
4116
4117 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4118}
4119
4120} // end extern "C"
4121
4122CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4123 assert(TU);
4124
4125 // Guard against an invalid SourceLocation, or we may assert in one
4126 // of the following calls.
4127 if (SLoc.isInvalid())
4128 return clang_getNullCursor();
4129
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004131
4132 // Translate the given source location to make it point at the beginning of
4133 // the token under the cursor.
4134 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4135 CXXUnit->getASTContext().getLangOpts());
4136
4137 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4138 if (SLoc.isValid()) {
4139 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4140 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4141 /*VisitPreprocessorLast=*/true,
4142 /*VisitIncludedEntities=*/false,
4143 SourceLocation(SLoc));
4144 CursorVis.visitFileRegion();
4145 }
4146
4147 return Result;
4148}
4149
4150static SourceRange getRawCursorExtent(CXCursor C) {
4151 if (clang_isReference(C.kind)) {
4152 switch (C.kind) {
4153 case CXCursor_ObjCSuperClassRef:
4154 return getCursorObjCSuperClassRef(C).second;
4155
4156 case CXCursor_ObjCProtocolRef:
4157 return getCursorObjCProtocolRef(C).second;
4158
4159 case CXCursor_ObjCClassRef:
4160 return getCursorObjCClassRef(C).second;
4161
4162 case CXCursor_TypeRef:
4163 return getCursorTypeRef(C).second;
4164
4165 case CXCursor_TemplateRef:
4166 return getCursorTemplateRef(C).second;
4167
4168 case CXCursor_NamespaceRef:
4169 return getCursorNamespaceRef(C).second;
4170
4171 case CXCursor_MemberRef:
4172 return getCursorMemberRef(C).second;
4173
4174 case CXCursor_CXXBaseSpecifier:
4175 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4176
4177 case CXCursor_LabelRef:
4178 return getCursorLabelRef(C).second;
4179
4180 case CXCursor_OverloadedDeclRef:
4181 return getCursorOverloadedDeclRef(C).second;
4182
4183 case CXCursor_VariableRef:
4184 return getCursorVariableRef(C).second;
4185
4186 default:
4187 // FIXME: Need a way to enumerate all non-reference cases.
4188 llvm_unreachable("Missed a reference kind");
4189 }
4190 }
4191
4192 if (clang_isExpression(C.kind))
4193 return getCursorExpr(C)->getSourceRange();
4194
4195 if (clang_isStatement(C.kind))
4196 return getCursorStmt(C)->getSourceRange();
4197
4198 if (clang_isAttribute(C.kind))
4199 return getCursorAttr(C)->getRange();
4200
4201 if (C.kind == CXCursor_PreprocessingDirective)
4202 return cxcursor::getCursorPreprocessingDirective(C);
4203
4204 if (C.kind == CXCursor_MacroExpansion) {
4205 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004206 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004207 return TU->mapRangeFromPreamble(Range);
4208 }
4209
4210 if (C.kind == CXCursor_MacroDefinition) {
4211 ASTUnit *TU = getCursorASTUnit(C);
4212 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4213 return TU->mapRangeFromPreamble(Range);
4214 }
4215
4216 if (C.kind == CXCursor_InclusionDirective) {
4217 ASTUnit *TU = getCursorASTUnit(C);
4218 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4219 return TU->mapRangeFromPreamble(Range);
4220 }
4221
4222 if (C.kind == CXCursor_TranslationUnit) {
4223 ASTUnit *TU = getCursorASTUnit(C);
4224 FileID MainID = TU->getSourceManager().getMainFileID();
4225 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4226 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4227 return SourceRange(Start, End);
4228 }
4229
4230 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004231 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004232 if (!D)
4233 return SourceRange();
4234
4235 SourceRange R = D->getSourceRange();
4236 // FIXME: Multiple variables declared in a single declaration
4237 // currently lack the information needed to correctly determine their
4238 // ranges when accounting for the type-specifier. We use context
4239 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4240 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004241 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004242 if (!cxcursor::isFirstInDeclGroup(C))
4243 R.setBegin(VD->getLocation());
4244 }
4245 return R;
4246 }
4247 return SourceRange();
4248}
4249
4250/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4251/// the decl-specifier-seq for declarations.
4252static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4253 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004254 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004255 if (!D)
4256 return SourceRange();
4257
4258 SourceRange R = D->getSourceRange();
4259
4260 // Adjust the start of the location for declarations preceded by
4261 // declaration specifiers.
4262 SourceLocation StartLoc;
4263 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4264 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4265 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004266 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004267 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4268 StartLoc = TI->getTypeLoc().getLocStart();
4269 }
4270
4271 if (StartLoc.isValid() && R.getBegin().isValid() &&
4272 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4273 R.setBegin(StartLoc);
4274
4275 // FIXME: Multiple variables declared in a single declaration
4276 // currently lack the information needed to correctly determine their
4277 // ranges when accounting for the type-specifier. We use context
4278 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4279 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004280 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004281 if (!cxcursor::isFirstInDeclGroup(C))
4282 R.setBegin(VD->getLocation());
4283 }
4284
4285 return R;
4286 }
4287
4288 return getRawCursorExtent(C);
4289}
4290
4291extern "C" {
4292
4293CXSourceRange clang_getCursorExtent(CXCursor C) {
4294 SourceRange R = getRawCursorExtent(C);
4295 if (R.isInvalid())
4296 return clang_getNullRange();
4297
4298 return cxloc::translateSourceRange(getCursorContext(C), R);
4299}
4300
4301CXCursor clang_getCursorReferenced(CXCursor C) {
4302 if (clang_isInvalid(C.kind))
4303 return clang_getNullCursor();
4304
4305 CXTranslationUnit tu = getCursorTU(C);
4306 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004307 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004308 if (!D)
4309 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004310 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004311 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004312 if (const ObjCPropertyImplDecl *PropImpl =
4313 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004314 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4315 return MakeCXCursor(Property, tu);
4316
4317 return C;
4318 }
4319
4320 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004321 const Expr *E = getCursorExpr(C);
4322 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004323 if (D) {
4324 CXCursor declCursor = MakeCXCursor(D, tu);
4325 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4326 declCursor);
4327 return declCursor;
4328 }
4329
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004330 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004331 return MakeCursorOverloadedDeclRef(Ovl, tu);
4332
4333 return clang_getNullCursor();
4334 }
4335
4336 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004337 const Stmt *S = getCursorStmt(C);
4338 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004339 if (LabelDecl *label = Goto->getLabel())
4340 if (LabelStmt *labelS = label->getStmt())
4341 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4342
4343 return clang_getNullCursor();
4344 }
4345
4346 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004347 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004348 return MakeMacroDefinitionCursor(Def, tu);
4349 }
4350
4351 if (!clang_isReference(C.kind))
4352 return clang_getNullCursor();
4353
4354 switch (C.kind) {
4355 case CXCursor_ObjCSuperClassRef:
4356 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4357
4358 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004359 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4360 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004361 return MakeCXCursor(Def, tu);
4362
4363 return MakeCXCursor(Prot, tu);
4364 }
4365
4366 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004367 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4368 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004369 return MakeCXCursor(Def, tu);
4370
4371 return MakeCXCursor(Class, tu);
4372 }
4373
4374 case CXCursor_TypeRef:
4375 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4376
4377 case CXCursor_TemplateRef:
4378 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4379
4380 case CXCursor_NamespaceRef:
4381 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4382
4383 case CXCursor_MemberRef:
4384 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4385
4386 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004387 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004388 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4389 tu ));
4390 }
4391
4392 case CXCursor_LabelRef:
4393 // FIXME: We end up faking the "parent" declaration here because we
4394 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004395 return MakeCXCursor(getCursorLabelRef(C).first,
4396 cxtu::getASTUnit(tu)->getASTContext()
4397 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004398 tu);
4399
4400 case CXCursor_OverloadedDeclRef:
4401 return C;
4402
4403 case CXCursor_VariableRef:
4404 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4405
4406 default:
4407 // We would prefer to enumerate all non-reference cursor kinds here.
4408 llvm_unreachable("Unhandled reference cursor kind");
4409 }
4410}
4411
4412CXCursor clang_getCursorDefinition(CXCursor C) {
4413 if (clang_isInvalid(C.kind))
4414 return clang_getNullCursor();
4415
4416 CXTranslationUnit TU = getCursorTU(C);
4417
4418 bool WasReference = false;
4419 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4420 C = clang_getCursorReferenced(C);
4421 WasReference = true;
4422 }
4423
4424 if (C.kind == CXCursor_MacroExpansion)
4425 return clang_getCursorReferenced(C);
4426
4427 if (!clang_isDeclaration(C.kind))
4428 return clang_getNullCursor();
4429
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004430 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004431 if (!D)
4432 return clang_getNullCursor();
4433
4434 switch (D->getKind()) {
4435 // Declaration kinds that don't really separate the notions of
4436 // declaration and definition.
4437 case Decl::Namespace:
4438 case Decl::Typedef:
4439 case Decl::TypeAlias:
4440 case Decl::TypeAliasTemplate:
4441 case Decl::TemplateTypeParm:
4442 case Decl::EnumConstant:
4443 case Decl::Field:
4444 case Decl::IndirectField:
4445 case Decl::ObjCIvar:
4446 case Decl::ObjCAtDefsField:
4447 case Decl::ImplicitParam:
4448 case Decl::ParmVar:
4449 case Decl::NonTypeTemplateParm:
4450 case Decl::TemplateTemplateParm:
4451 case Decl::ObjCCategoryImpl:
4452 case Decl::ObjCImplementation:
4453 case Decl::AccessSpec:
4454 case Decl::LinkageSpec:
4455 case Decl::ObjCPropertyImpl:
4456 case Decl::FileScopeAsm:
4457 case Decl::StaticAssert:
4458 case Decl::Block:
4459 case Decl::Label: // FIXME: Is this right??
4460 case Decl::ClassScopeFunctionSpecialization:
4461 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004462 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004463 return C;
4464
4465 // Declaration kinds that don't make any sense here, but are
4466 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004467 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004468 case Decl::TranslationUnit:
4469 break;
4470
4471 // Declaration kinds for which the definition is not resolvable.
4472 case Decl::UnresolvedUsingTypename:
4473 case Decl::UnresolvedUsingValue:
4474 break;
4475
4476 case Decl::UsingDirective:
4477 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4478 TU);
4479
4480 case Decl::NamespaceAlias:
4481 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4482
4483 case Decl::Enum:
4484 case Decl::Record:
4485 case Decl::CXXRecord:
4486 case Decl::ClassTemplateSpecialization:
4487 case Decl::ClassTemplatePartialSpecialization:
4488 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4489 return MakeCXCursor(Def, TU);
4490 return clang_getNullCursor();
4491
4492 case Decl::Function:
4493 case Decl::CXXMethod:
4494 case Decl::CXXConstructor:
4495 case Decl::CXXDestructor:
4496 case Decl::CXXConversion: {
4497 const FunctionDecl *Def = 0;
4498 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004499 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004500 return clang_getNullCursor();
4501 }
4502
4503 case Decl::Var: {
4504 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004505 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004506 return MakeCXCursor(Def, TU);
4507 return clang_getNullCursor();
4508 }
4509
4510 case Decl::FunctionTemplate: {
4511 const FunctionDecl *Def = 0;
4512 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4513 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4514 return clang_getNullCursor();
4515 }
4516
4517 case Decl::ClassTemplate: {
4518 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4519 ->getDefinition())
4520 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4521 TU);
4522 return clang_getNullCursor();
4523 }
4524
4525 case Decl::Using:
4526 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4527 D->getLocation(), TU);
4528
4529 case Decl::UsingShadow:
4530 return clang_getCursorDefinition(
4531 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4532 TU));
4533
4534 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004535 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004536 if (Method->isThisDeclarationADefinition())
4537 return C;
4538
4539 // Dig out the method definition in the associated
4540 // @implementation, if we have it.
4541 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004542 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004543 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4544 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4545 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4546 Method->isInstanceMethod()))
4547 if (Def->isThisDeclarationADefinition())
4548 return MakeCXCursor(Def, TU);
4549
4550 return clang_getNullCursor();
4551 }
4552
4553 case Decl::ObjCCategory:
4554 if (ObjCCategoryImplDecl *Impl
4555 = cast<ObjCCategoryDecl>(D)->getImplementation())
4556 return MakeCXCursor(Impl, TU);
4557 return clang_getNullCursor();
4558
4559 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004560 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004561 return MakeCXCursor(Def, TU);
4562 return clang_getNullCursor();
4563
4564 case Decl::ObjCInterface: {
4565 // There are two notions of a "definition" for an Objective-C
4566 // class: the interface and its implementation. When we resolved a
4567 // reference to an Objective-C class, produce the @interface as
4568 // the definition; when we were provided with the interface,
4569 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004570 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004571 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004572 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004573 return MakeCXCursor(Def, TU);
4574 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4575 return MakeCXCursor(Impl, TU);
4576 return clang_getNullCursor();
4577 }
4578
4579 case Decl::ObjCProperty:
4580 // FIXME: We don't really know where to find the
4581 // ObjCPropertyImplDecls that implement this property.
4582 return clang_getNullCursor();
4583
4584 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004585 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004586 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004587 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004588 return MakeCXCursor(Def, TU);
4589
4590 return clang_getNullCursor();
4591
4592 case Decl::Friend:
4593 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4594 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4595 return clang_getNullCursor();
4596
4597 case Decl::FriendTemplate:
4598 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4599 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4600 return clang_getNullCursor();
4601 }
4602
4603 return clang_getNullCursor();
4604}
4605
4606unsigned clang_isCursorDefinition(CXCursor C) {
4607 if (!clang_isDeclaration(C.kind))
4608 return 0;
4609
4610 return clang_getCursorDefinition(C) == C;
4611}
4612
4613CXCursor clang_getCanonicalCursor(CXCursor C) {
4614 if (!clang_isDeclaration(C.kind))
4615 return C;
4616
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004617 if (const Decl *D = getCursorDecl(C)) {
4618 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004619 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4620 return MakeCXCursor(CatD, getCursorTU(C));
4621
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004622 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4623 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004624 return MakeCXCursor(IFD, getCursorTU(C));
4625
4626 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4627 }
4628
4629 return C;
4630}
4631
4632int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4633 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4634}
4635
4636unsigned clang_getNumOverloadedDecls(CXCursor C) {
4637 if (C.kind != CXCursor_OverloadedDeclRef)
4638 return 0;
4639
4640 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004641 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004642 return E->getNumDecls();
4643
4644 if (OverloadedTemplateStorage *S
4645 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4646 return S->size();
4647
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004648 const Decl *D = Storage.get<const Decl *>();
4649 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004650 return Using->shadow_size();
4651
4652 return 0;
4653}
4654
4655CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4656 if (cursor.kind != CXCursor_OverloadedDeclRef)
4657 return clang_getNullCursor();
4658
4659 if (index >= clang_getNumOverloadedDecls(cursor))
4660 return clang_getNullCursor();
4661
4662 CXTranslationUnit TU = getCursorTU(cursor);
4663 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004664 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004665 return MakeCXCursor(E->decls_begin()[index], TU);
4666
4667 if (OverloadedTemplateStorage *S
4668 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4669 return MakeCXCursor(S->begin()[index], TU);
4670
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004671 const Decl *D = Storage.get<const Decl *>();
4672 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004673 // FIXME: This is, unfortunately, linear time.
4674 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4675 std::advance(Pos, index);
4676 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4677 }
4678
4679 return clang_getNullCursor();
4680}
4681
4682void clang_getDefinitionSpellingAndExtent(CXCursor C,
4683 const char **startBuf,
4684 const char **endBuf,
4685 unsigned *startLine,
4686 unsigned *startColumn,
4687 unsigned *endLine,
4688 unsigned *endColumn) {
4689 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004690 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004691 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4692
4693 SourceManager &SM = FD->getASTContext().getSourceManager();
4694 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4695 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4696 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4697 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4698 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4699 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4700}
4701
4702
4703CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4704 unsigned PieceIndex) {
4705 RefNamePieces Pieces;
4706
4707 switch (C.kind) {
4708 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004709 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004710 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4711 E->getQualifierLoc().getSourceRange());
4712 break;
4713
4714 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004715 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004716 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4717 E->getQualifierLoc().getSourceRange(),
4718 E->getOptionalExplicitTemplateArgs());
4719 break;
4720
4721 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004722 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004723 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004724 const Expr *Callee = OCE->getCallee();
4725 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004726 Callee = ICE->getSubExpr();
4727
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004728 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004729 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4730 DRE->getQualifierLoc().getSourceRange());
4731 }
4732 break;
4733
4734 default:
4735 break;
4736 }
4737
4738 if (Pieces.empty()) {
4739 if (PieceIndex == 0)
4740 return clang_getCursorExtent(C);
4741 } else if (PieceIndex < Pieces.size()) {
4742 SourceRange R = Pieces[PieceIndex];
4743 if (R.isValid())
4744 return cxloc::translateSourceRange(getCursorContext(C), R);
4745 }
4746
4747 return clang_getNullRange();
4748}
4749
4750void clang_enableStackTraces(void) {
4751 llvm::sys::PrintStackTraceOnErrorSignal();
4752}
4753
4754void clang_executeOnThread(void (*fn)(void*), void *user_data,
4755 unsigned stack_size) {
4756 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4757}
4758
4759} // end: extern "C"
4760
4761//===----------------------------------------------------------------------===//
4762// Token-based Operations.
4763//===----------------------------------------------------------------------===//
4764
4765/* CXToken layout:
4766 * int_data[0]: a CXTokenKind
4767 * int_data[1]: starting token location
4768 * int_data[2]: token length
4769 * int_data[3]: reserved
4770 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4771 * otherwise unused.
4772 */
4773extern "C" {
4774
4775CXTokenKind clang_getTokenKind(CXToken CXTok) {
4776 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4777}
4778
4779CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4780 switch (clang_getTokenKind(CXTok)) {
4781 case CXToken_Identifier:
4782 case CXToken_Keyword:
4783 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004784 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004785 ->getNameStart());
4786
4787 case CXToken_Literal: {
4788 // We have stashed the starting pointer in the ptr_data field. Use it.
4789 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004790 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004791 }
4792
4793 case CXToken_Punctuation:
4794 case CXToken_Comment:
4795 break;
4796 }
4797
4798 // We have to find the starting buffer pointer the hard way, by
4799 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004800 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004801 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004802 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004803
4804 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4805 std::pair<FileID, unsigned> LocInfo
4806 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4807 bool Invalid = false;
4808 StringRef Buffer
4809 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4810 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004811 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004812
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004813 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004814}
4815
4816CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004817 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004818 if (!CXXUnit)
4819 return clang_getNullLocation();
4820
4821 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4822 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4823}
4824
4825CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004826 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004827 if (!CXXUnit)
4828 return clang_getNullRange();
4829
4830 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4831 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4832}
4833
4834static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4835 SmallVectorImpl<CXToken> &CXTokens) {
4836 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4837 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004838 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004839 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004840 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004841
4842 // Cannot tokenize across files.
4843 if (BeginLocInfo.first != EndLocInfo.first)
4844 return;
4845
4846 // Create a lexer
4847 bool Invalid = false;
4848 StringRef Buffer
4849 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4850 if (Invalid)
4851 return;
4852
4853 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4854 CXXUnit->getASTContext().getLangOpts(),
4855 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4856 Lex.SetCommentRetentionState(true);
4857
4858 // Lex tokens until we hit the end of the range.
4859 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4860 Token Tok;
4861 bool previousWasAt = false;
4862 do {
4863 // Lex the next token
4864 Lex.LexFromRawLexer(Tok);
4865 if (Tok.is(tok::eof))
4866 break;
4867
4868 // Initialize the CXToken.
4869 CXToken CXTok;
4870
4871 // - Common fields
4872 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4873 CXTok.int_data[2] = Tok.getLength();
4874 CXTok.int_data[3] = 0;
4875
4876 // - Kind-specific fields
4877 if (Tok.isLiteral()) {
4878 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004879 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004880 } else if (Tok.is(tok::raw_identifier)) {
4881 // Lookup the identifier to determine whether we have a keyword.
4882 IdentifierInfo *II
4883 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4884
4885 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4886 CXTok.int_data[0] = CXToken_Keyword;
4887 }
4888 else {
4889 CXTok.int_data[0] = Tok.is(tok::identifier)
4890 ? CXToken_Identifier
4891 : CXToken_Keyword;
4892 }
4893 CXTok.ptr_data = II;
4894 } else if (Tok.is(tok::comment)) {
4895 CXTok.int_data[0] = CXToken_Comment;
4896 CXTok.ptr_data = 0;
4897 } else {
4898 CXTok.int_data[0] = CXToken_Punctuation;
4899 CXTok.ptr_data = 0;
4900 }
4901 CXTokens.push_back(CXTok);
4902 previousWasAt = Tok.is(tok::at);
4903 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4904}
4905
4906void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4907 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004908 LOG_FUNC_SECTION {
4909 *Log << TU << ' ' << Range;
4910 }
4911
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004912 if (Tokens)
4913 *Tokens = 0;
4914 if (NumTokens)
4915 *NumTokens = 0;
4916
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004917 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004918 if (!CXXUnit || !Tokens || !NumTokens)
4919 return;
4920
4921 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4922
4923 SourceRange R = cxloc::translateCXSourceRange(Range);
4924 if (R.isInvalid())
4925 return;
4926
4927 SmallVector<CXToken, 32> CXTokens;
4928 getTokens(CXXUnit, R, CXTokens);
4929
4930 if (CXTokens.empty())
4931 return;
4932
4933 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4934 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4935 *NumTokens = CXTokens.size();
4936}
4937
4938void clang_disposeTokens(CXTranslationUnit TU,
4939 CXToken *Tokens, unsigned NumTokens) {
4940 free(Tokens);
4941}
4942
4943} // end: extern "C"
4944
4945//===----------------------------------------------------------------------===//
4946// Token annotation APIs.
4947//===----------------------------------------------------------------------===//
4948
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004949static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4950 CXCursor parent,
4951 CXClientData client_data);
4952static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4953 CXClientData client_data);
4954
4955namespace {
4956class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004957 CXToken *Tokens;
4958 CXCursor *Cursors;
4959 unsigned NumTokens;
4960 unsigned TokIdx;
4961 unsigned PreprocessingTokIdx;
4962 CursorVisitor AnnotateVis;
4963 SourceManager &SrcMgr;
4964 bool HasContextSensitiveKeywords;
4965
4966 struct PostChildrenInfo {
4967 CXCursor Cursor;
4968 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004969 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004970 unsigned BeforeChildrenTokenIdx;
4971 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004972 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004973
4974 bool MoreTokens() const { return TokIdx < NumTokens; }
4975 unsigned NextToken() const { return TokIdx; }
4976 void AdvanceToken() { ++TokIdx; }
4977 SourceLocation GetTokenLoc(unsigned tokI) {
4978 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4979 }
4980 bool isFunctionMacroToken(unsigned tokI) const {
4981 return Tokens[tokI].int_data[3] != 0;
4982 }
4983 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4984 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4985 }
4986
4987 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004988 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004989 SourceRange);
4990
4991public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004992 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004993 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004994 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004995 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004996 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004997 AnnotateTokensVisitor, this,
4998 /*VisitPreprocessorLast=*/true,
4999 /*VisitIncludedEntities=*/false,
5000 RegionOfInterest,
5001 /*VisitDeclsOnly=*/false,
5002 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005003 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005004 HasContextSensitiveKeywords(false) { }
5005
5006 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5007 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5008 bool postVisitChildren(CXCursor cursor);
5009 void AnnotateTokens();
5010
5011 /// \brief Determine whether the annotator saw any cursors that have
5012 /// context-sensitive keywords.
5013 bool hasContextSensitiveKeywords() const {
5014 return HasContextSensitiveKeywords;
5015 }
5016
5017 ~AnnotateTokensWorker() {
5018 assert(PostChildrenInfos.empty());
5019 }
5020};
5021}
5022
5023void AnnotateTokensWorker::AnnotateTokens() {
5024 // Walk the AST within the region of interest, annotating tokens
5025 // along the way.
5026 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005027}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005028
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005029static inline void updateCursorAnnotation(CXCursor &Cursor,
5030 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005031 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005032 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005033 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005034}
5035
5036/// \brief It annotates and advances tokens with a cursor until the comparison
5037//// between the cursor location and the source range is the same as
5038/// \arg compResult.
5039///
5040/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5041/// Pass RangeOverlap to annotate tokens inside a range.
5042void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5043 RangeComparisonResult compResult,
5044 SourceRange range) {
5045 while (MoreTokens()) {
5046 const unsigned I = NextToken();
5047 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005048 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5049 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005050
5051 SourceLocation TokLoc = GetTokenLoc(I);
5052 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005053 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005054 AdvanceToken();
5055 continue;
5056 }
5057 break;
5058 }
5059}
5060
5061/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005062/// \returns true if it advanced beyond all macro tokens, false otherwise.
5063bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005064 CXCursor updateC,
5065 RangeComparisonResult compResult,
5066 SourceRange range) {
5067 assert(MoreTokens());
5068 assert(isFunctionMacroToken(NextToken()) &&
5069 "Should be called only for macro arg tokens");
5070
5071 // This works differently than annotateAndAdvanceTokens; because expanded
5072 // macro arguments can have arbitrary translation-unit source order, we do not
5073 // advance the token index one by one until a token fails the range test.
5074 // We only advance once past all of the macro arg tokens if all of them
5075 // pass the range test. If one of them fails we keep the token index pointing
5076 // at the start of the macro arg tokens so that the failing token will be
5077 // annotated by a subsequent annotation try.
5078
5079 bool atLeastOneCompFail = false;
5080
5081 unsigned I = NextToken();
5082 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5083 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5084 if (TokLoc.isFileID())
5085 continue; // not macro arg token, it's parens or comma.
5086 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5087 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5088 Cursors[I] = updateC;
5089 } else
5090 atLeastOneCompFail = true;
5091 }
5092
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005093 if (atLeastOneCompFail)
5094 return false;
5095
5096 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5097 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005098}
5099
5100enum CXChildVisitResult
5101AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005102 SourceRange cursorRange = getRawCursorExtent(cursor);
5103 if (cursorRange.isInvalid())
5104 return CXChildVisit_Recurse;
5105
5106 if (!HasContextSensitiveKeywords) {
5107 // Objective-C properties can have context-sensitive keywords.
5108 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005109 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005110 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5111 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5112 }
5113 // Objective-C methods can have context-sensitive keywords.
5114 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5115 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005116 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005117 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5118 if (Method->getObjCDeclQualifier())
5119 HasContextSensitiveKeywords = true;
5120 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005121 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5122 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005123 P != PEnd; ++P) {
5124 if ((*P)->getObjCDeclQualifier()) {
5125 HasContextSensitiveKeywords = true;
5126 break;
5127 }
5128 }
5129 }
5130 }
5131 }
5132 // C++ methods can have context-sensitive keywords.
5133 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005134 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005135 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5136 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5137 HasContextSensitiveKeywords = true;
5138 }
5139 }
5140 // C++ classes can have context-sensitive keywords.
5141 else if (cursor.kind == CXCursor_StructDecl ||
5142 cursor.kind == CXCursor_ClassDecl ||
5143 cursor.kind == CXCursor_ClassTemplate ||
5144 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005145 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005146 if (D->hasAttr<FinalAttr>())
5147 HasContextSensitiveKeywords = true;
5148 }
5149 }
5150
5151 if (clang_isPreprocessing(cursor.kind)) {
5152 // Items in the preprocessing record are kept separate from items in
5153 // declarations, so we keep a separate token index.
5154 unsigned SavedTokIdx = TokIdx;
5155 TokIdx = PreprocessingTokIdx;
5156
5157 // Skip tokens up until we catch up to the beginning of the preprocessing
5158 // entry.
5159 while (MoreTokens()) {
5160 const unsigned I = NextToken();
5161 SourceLocation TokLoc = GetTokenLoc(I);
5162 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5163 case RangeBefore:
5164 AdvanceToken();
5165 continue;
5166 case RangeAfter:
5167 case RangeOverlap:
5168 break;
5169 }
5170 break;
5171 }
5172
5173 // Look at all of the tokens within this range.
5174 while (MoreTokens()) {
5175 const unsigned I = NextToken();
5176 SourceLocation TokLoc = GetTokenLoc(I);
5177 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5178 case RangeBefore:
5179 llvm_unreachable("Infeasible");
5180 case RangeAfter:
5181 break;
5182 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005183 // For macro expansions, just note where the beginning of the macro
5184 // expansion occurs.
5185 if (cursor.kind == CXCursor_MacroExpansion) {
5186 if (TokLoc == cursorRange.getBegin())
5187 Cursors[I] = cursor;
5188 AdvanceToken();
5189 break;
5190 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005191 // We may have already annotated macro names inside macro definitions.
5192 if (Cursors[I].kind != CXCursor_MacroExpansion)
5193 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005194 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005195 continue;
5196 }
5197 break;
5198 }
5199
5200 // Save the preprocessing token index; restore the non-preprocessing
5201 // token index.
5202 PreprocessingTokIdx = TokIdx;
5203 TokIdx = SavedTokIdx;
5204 return CXChildVisit_Recurse;
5205 }
5206
5207 if (cursorRange.isInvalid())
5208 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005209
5210 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005211 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005212 const enum CXCursorKind K = clang_getCursorKind(parent);
5213 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005214 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5215 // Attributes are annotated out-of-order, skip tokens until we reach it.
5216 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005217 ? clang_getNullCursor() : parent;
5218
5219 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5220
5221 // Avoid having the cursor of an expression "overwrite" the annotation of the
5222 // variable declaration that it belongs to.
5223 // This can happen for C++ constructor expressions whose range generally
5224 // include the variable declaration, e.g.:
5225 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5226 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005227 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005228 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005229 const unsigned I = NextToken();
5230 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5231 E->getLocStart() == D->getLocation() &&
5232 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005233 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005234 AdvanceToken();
5235 }
5236 }
5237 }
5238
5239 // Before recursing into the children keep some state that we are going
5240 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5241 // extra work after the child nodes are visited.
5242 // Note that we don't call VisitChildren here to avoid traversing statements
5243 // code-recursively which can blow the stack.
5244
5245 PostChildrenInfo Info;
5246 Info.Cursor = cursor;
5247 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005248 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005249 Info.BeforeChildrenTokenIdx = NextToken();
5250 PostChildrenInfos.push_back(Info);
5251
5252 return CXChildVisit_Recurse;
5253}
5254
5255bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5256 if (PostChildrenInfos.empty())
5257 return false;
5258 const PostChildrenInfo &Info = PostChildrenInfos.back();
5259 if (!clang_equalCursors(Info.Cursor, cursor))
5260 return false;
5261
5262 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5263 const unsigned AfterChildren = NextToken();
5264 SourceRange cursorRange = Info.CursorRange;
5265
5266 // Scan the tokens that are at the end of the cursor, but are not captured
5267 // but the child cursors.
5268 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5269
5270 // Scan the tokens that are at the beginning of the cursor, but are not
5271 // capture by the child cursors.
5272 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5273 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5274 break;
5275
5276 Cursors[I] = cursor;
5277 }
5278
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005279 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5280 // encountered the attribute cursor.
5281 if (clang_isAttribute(cursor.kind))
5282 TokIdx = Info.BeforeReachingCursorIdx;
5283
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005284 PostChildrenInfos.pop_back();
5285 return false;
5286}
5287
5288static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5289 CXCursor parent,
5290 CXClientData client_data) {
5291 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5292}
5293
5294static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5295 CXClientData client_data) {
5296 return static_cast<AnnotateTokensWorker*>(client_data)->
5297 postVisitChildren(cursor);
5298}
5299
5300namespace {
5301
5302/// \brief Uses the macro expansions in the preprocessing record to find
5303/// and mark tokens that are macro arguments. This info is used by the
5304/// AnnotateTokensWorker.
5305class MarkMacroArgTokensVisitor {
5306 SourceManager &SM;
5307 CXToken *Tokens;
5308 unsigned NumTokens;
5309 unsigned CurIdx;
5310
5311public:
5312 MarkMacroArgTokensVisitor(SourceManager &SM,
5313 CXToken *tokens, unsigned numTokens)
5314 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5315
5316 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5317 if (cursor.kind != CXCursor_MacroExpansion)
5318 return CXChildVisit_Continue;
5319
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005320 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005321 if (macroRange.getBegin() == macroRange.getEnd())
5322 return CXChildVisit_Continue; // it's not a function macro.
5323
5324 for (; CurIdx < NumTokens; ++CurIdx) {
5325 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5326 macroRange.getBegin()))
5327 break;
5328 }
5329
5330 if (CurIdx == NumTokens)
5331 return CXChildVisit_Break;
5332
5333 for (; CurIdx < NumTokens; ++CurIdx) {
5334 SourceLocation tokLoc = getTokenLoc(CurIdx);
5335 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5336 break;
5337
5338 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5339 }
5340
5341 if (CurIdx == NumTokens)
5342 return CXChildVisit_Break;
5343
5344 return CXChildVisit_Continue;
5345 }
5346
5347private:
5348 SourceLocation getTokenLoc(unsigned tokI) {
5349 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5350 }
5351
5352 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5353 // The third field is reserved and currently not used. Use it here
5354 // to mark macro arg expanded tokens with their expanded locations.
5355 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5356 }
5357};
5358
5359} // end anonymous namespace
5360
5361static CXChildVisitResult
5362MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5363 CXClientData client_data) {
5364 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5365 parent);
5366}
5367
5368namespace {
5369 struct clang_annotateTokens_Data {
5370 CXTranslationUnit TU;
5371 ASTUnit *CXXUnit;
5372 CXToken *Tokens;
5373 unsigned NumTokens;
5374 CXCursor *Cursors;
5375 };
5376}
5377
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005378/// \brief Used by \c annotatePreprocessorTokens.
5379/// \returns true if lexing was finished, false otherwise.
5380static bool lexNext(Lexer &Lex, Token &Tok,
5381 unsigned &NextIdx, unsigned NumTokens) {
5382 if (NextIdx >= NumTokens)
5383 return true;
5384
5385 ++NextIdx;
5386 Lex.LexFromRawLexer(Tok);
5387 if (Tok.is(tok::eof))
5388 return true;
5389
5390 return false;
5391}
5392
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005393static void annotatePreprocessorTokens(CXTranslationUnit TU,
5394 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005395 CXCursor *Cursors,
5396 CXToken *Tokens,
5397 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005398 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005399
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005400 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005401 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5402 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005403 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005404 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005405 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005406
5407 if (BeginLocInfo.first != EndLocInfo.first)
5408 return;
5409
5410 StringRef Buffer;
5411 bool Invalid = false;
5412 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5413 if (Buffer.empty() || Invalid)
5414 return;
5415
5416 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5417 CXXUnit->getASTContext().getLangOpts(),
5418 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5419 Buffer.end());
5420 Lex.SetCommentRetentionState(true);
5421
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005422 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005423 // Lex tokens in raw mode until we hit the end of the range, to avoid
5424 // entering #includes or expanding macros.
5425 while (true) {
5426 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005427 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5428 break;
5429 unsigned TokIdx = NextIdx-1;
5430 assert(Tok.getLocation() ==
5431 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005432
5433 reprocess:
5434 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005435 // We have found a preprocessing directive. Annotate the tokens
5436 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005437 //
5438 // FIXME: Some simple tests here could identify macro definitions and
5439 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005440
5441 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005442 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5443 break;
5444
5445 MacroInfo *MI = 0;
5446 if (Tok.is(tok::raw_identifier) &&
5447 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5448 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5449 break;
5450
5451 if (Tok.is(tok::raw_identifier)) {
5452 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5453 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5454 SourceLocation MappedTokLoc =
5455 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5456 MI = getMacroInfo(II, MappedTokLoc, TU);
5457 }
5458 }
5459
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005460 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005461 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005462 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5463 finished = true;
5464 break;
5465 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005466 // If we are in a macro definition, check if the token was ever a
5467 // macro name and annotate it if that's the case.
5468 if (MI) {
5469 SourceLocation SaveLoc = Tok.getLocation();
5470 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5471 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5472 Tok.setLocation(SaveLoc);
5473 if (MacroDef)
5474 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5475 Tok.getLocation(), TU);
5476 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005477 } while (!Tok.isAtStartOfLine());
5478
5479 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5480 assert(TokIdx <= LastIdx);
5481 SourceLocation EndLoc =
5482 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5483 CXCursor Cursor =
5484 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5485
5486 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005487 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005488
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005489 if (finished)
5490 break;
5491 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005492 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005493 }
5494}
5495
5496// This gets run a separate thread to avoid stack blowout.
5497static void clang_annotateTokensImpl(void *UserData) {
5498 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5499 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5500 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5501 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5502 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5503
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005504 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005505 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5506 setThreadBackgroundPriority();
5507
5508 // Determine the region of interest, which contains all of the tokens.
5509 SourceRange RegionOfInterest;
5510 RegionOfInterest.setBegin(
5511 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5512 RegionOfInterest.setEnd(
5513 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5514 Tokens[NumTokens-1])));
5515
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005516 // Relex the tokens within the source range to look for preprocessing
5517 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005518 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005519
5520 // If begin location points inside a macro argument, set it to the expansion
5521 // location so we can have the full context when annotating semantically.
5522 {
5523 SourceManager &SM = CXXUnit->getSourceManager();
5524 SourceLocation Loc =
5525 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5526 if (Loc.isMacroID())
5527 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5528 }
5529
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005530 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5531 // Search and mark tokens that are macro argument expansions.
5532 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5533 Tokens, NumTokens);
5534 CursorVisitor MacroArgMarker(TU,
5535 MarkMacroArgTokensVisitorDelegate, &Visitor,
5536 /*VisitPreprocessorLast=*/true,
5537 /*VisitIncludedEntities=*/false,
5538 RegionOfInterest);
5539 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5540 }
5541
5542 // Annotate all of the source locations in the region of interest that map to
5543 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005544 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005545
5546 // FIXME: We use a ridiculous stack size here because the data-recursion
5547 // algorithm uses a large stack frame than the non-data recursive version,
5548 // and AnnotationTokensWorker currently transforms the data-recursion
5549 // algorithm back into a traditional recursion by explicitly calling
5550 // VisitChildren(). We will need to remove this explicit recursive call.
5551 W.AnnotateTokens();
5552
5553 // If we ran into any entities that involve context-sensitive keywords,
5554 // take another pass through the tokens to mark them as such.
5555 if (W.hasContextSensitiveKeywords()) {
5556 for (unsigned I = 0; I != NumTokens; ++I) {
5557 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5558 continue;
5559
5560 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5561 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005562 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005563 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5564 if (Property->getPropertyAttributesAsWritten() != 0 &&
5565 llvm::StringSwitch<bool>(II->getName())
5566 .Case("readonly", true)
5567 .Case("assign", true)
5568 .Case("unsafe_unretained", true)
5569 .Case("readwrite", true)
5570 .Case("retain", true)
5571 .Case("copy", true)
5572 .Case("nonatomic", true)
5573 .Case("atomic", true)
5574 .Case("getter", true)
5575 .Case("setter", true)
5576 .Case("strong", true)
5577 .Case("weak", true)
5578 .Default(false))
5579 Tokens[I].int_data[0] = CXToken_Keyword;
5580 }
5581 continue;
5582 }
5583
5584 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5585 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5586 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5587 if (llvm::StringSwitch<bool>(II->getName())
5588 .Case("in", true)
5589 .Case("out", true)
5590 .Case("inout", true)
5591 .Case("oneway", true)
5592 .Case("bycopy", true)
5593 .Case("byref", true)
5594 .Default(false))
5595 Tokens[I].int_data[0] = CXToken_Keyword;
5596 continue;
5597 }
5598
5599 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5600 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5601 Tokens[I].int_data[0] = CXToken_Keyword;
5602 continue;
5603 }
5604 }
5605 }
5606}
5607
5608extern "C" {
5609
5610void clang_annotateTokens(CXTranslationUnit TU,
5611 CXToken *Tokens, unsigned NumTokens,
5612 CXCursor *Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005613 if (NumTokens == 0 || !Tokens || !Cursors) {
5614 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005615 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005616 }
5617
5618 LOG_FUNC_SECTION {
5619 *Log << TU << ' ';
5620 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5621 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5622 *Log << clang_getRange(bloc, eloc);
5623 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005624
5625 // Any token we don't specifically annotate will have a NULL cursor.
5626 CXCursor C = clang_getNullCursor();
5627 for (unsigned I = 0; I != NumTokens; ++I)
5628 Cursors[I] = C;
5629
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005630 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005631 if (!CXXUnit)
5632 return;
5633
5634 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5635
5636 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5637 llvm::CrashRecoveryContext CRC;
5638 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5639 GetSafetyThreadStackSize() * 2)) {
5640 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5641 }
5642}
5643
5644} // end: extern "C"
5645
5646//===----------------------------------------------------------------------===//
5647// Operations for querying linkage of a cursor.
5648//===----------------------------------------------------------------------===//
5649
5650extern "C" {
5651CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5652 if (!clang_isDeclaration(cursor.kind))
5653 return CXLinkage_Invalid;
5654
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005655 const Decl *D = cxcursor::getCursorDecl(cursor);
5656 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005657 switch (ND->getLinkage()) {
5658 case NoLinkage: return CXLinkage_NoLinkage;
5659 case InternalLinkage: return CXLinkage_Internal;
5660 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5661 case ExternalLinkage: return CXLinkage_External;
5662 };
5663
5664 return CXLinkage_Invalid;
5665}
5666} // end: extern "C"
5667
5668//===----------------------------------------------------------------------===//
5669// Operations for querying language of a cursor.
5670//===----------------------------------------------------------------------===//
5671
5672static CXLanguageKind getDeclLanguage(const Decl *D) {
5673 if (!D)
5674 return CXLanguage_C;
5675
5676 switch (D->getKind()) {
5677 default:
5678 break;
5679 case Decl::ImplicitParam:
5680 case Decl::ObjCAtDefsField:
5681 case Decl::ObjCCategory:
5682 case Decl::ObjCCategoryImpl:
5683 case Decl::ObjCCompatibleAlias:
5684 case Decl::ObjCImplementation:
5685 case Decl::ObjCInterface:
5686 case Decl::ObjCIvar:
5687 case Decl::ObjCMethod:
5688 case Decl::ObjCProperty:
5689 case Decl::ObjCPropertyImpl:
5690 case Decl::ObjCProtocol:
5691 return CXLanguage_ObjC;
5692 case Decl::CXXConstructor:
5693 case Decl::CXXConversion:
5694 case Decl::CXXDestructor:
5695 case Decl::CXXMethod:
5696 case Decl::CXXRecord:
5697 case Decl::ClassTemplate:
5698 case Decl::ClassTemplatePartialSpecialization:
5699 case Decl::ClassTemplateSpecialization:
5700 case Decl::Friend:
5701 case Decl::FriendTemplate:
5702 case Decl::FunctionTemplate:
5703 case Decl::LinkageSpec:
5704 case Decl::Namespace:
5705 case Decl::NamespaceAlias:
5706 case Decl::NonTypeTemplateParm:
5707 case Decl::StaticAssert:
5708 case Decl::TemplateTemplateParm:
5709 case Decl::TemplateTypeParm:
5710 case Decl::UnresolvedUsingTypename:
5711 case Decl::UnresolvedUsingValue:
5712 case Decl::Using:
5713 case Decl::UsingDirective:
5714 case Decl::UsingShadow:
5715 return CXLanguage_CPlusPlus;
5716 }
5717
5718 return CXLanguage_C;
5719}
5720
5721extern "C" {
5722
5723enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5724 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005725 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005726 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5727 return CXAvailability_Available;
5728
5729 switch (D->getAvailability()) {
5730 case AR_Available:
5731 case AR_NotYetIntroduced:
5732 return CXAvailability_Available;
5733
5734 case AR_Deprecated:
5735 return CXAvailability_Deprecated;
5736
5737 case AR_Unavailable:
5738 return CXAvailability_NotAvailable;
5739 }
5740 }
5741
5742 return CXAvailability_Available;
5743}
5744
5745static CXVersion convertVersion(VersionTuple In) {
5746 CXVersion Out = { -1, -1, -1 };
5747 if (In.empty())
5748 return Out;
5749
5750 Out.Major = In.getMajor();
5751
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005752 Optional<unsigned> Minor = In.getMinor();
5753 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005754 Out.Minor = *Minor;
5755 else
5756 return Out;
5757
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005758 Optional<unsigned> Subminor = In.getSubminor();
5759 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005760 Out.Subminor = *Subminor;
5761
5762 return Out;
5763}
5764
5765int clang_getCursorPlatformAvailability(CXCursor cursor,
5766 int *always_deprecated,
5767 CXString *deprecated_message,
5768 int *always_unavailable,
5769 CXString *unavailable_message,
5770 CXPlatformAvailability *availability,
5771 int availability_size) {
5772 if (always_deprecated)
5773 *always_deprecated = 0;
5774 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005775 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005776 if (always_unavailable)
5777 *always_unavailable = 0;
5778 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005779 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005780
5781 if (!clang_isDeclaration(cursor.kind))
5782 return 0;
5783
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005784 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005785 if (!D)
5786 return 0;
5787
5788 int N = 0;
5789 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5790 ++A) {
5791 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5792 if (always_deprecated)
5793 *always_deprecated = 1;
5794 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005795 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005796 continue;
5797 }
5798
5799 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5800 if (always_unavailable)
5801 *always_unavailable = 1;
5802 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005803 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005804 }
5805 continue;
5806 }
5807
5808 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5809 if (N < availability_size) {
5810 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005811 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005812 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5813 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5814 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5815 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005816 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005817 }
5818 ++N;
5819 }
5820 }
5821
5822 return N;
5823}
5824
5825void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5826 clang_disposeString(availability->Platform);
5827 clang_disposeString(availability->Message);
5828}
5829
5830CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5831 if (clang_isDeclaration(cursor.kind))
5832 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5833
5834 return CXLanguage_Invalid;
5835}
5836
5837 /// \brief If the given cursor is the "templated" declaration
5838 /// descibing a class or function template, return the class or
5839 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005840static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005841 if (!D)
5842 return 0;
5843
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005844 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005845 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5846 return FunTmpl;
5847
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005848 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005849 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5850 return ClassTmpl;
5851
5852 return D;
5853}
5854
5855CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5856 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005857 if (const Decl *D = getCursorDecl(cursor)) {
5858 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005859 if (!DC)
5860 return clang_getNullCursor();
5861
5862 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5863 getCursorTU(cursor));
5864 }
5865 }
5866
5867 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005868 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005869 return MakeCXCursor(D, getCursorTU(cursor));
5870 }
5871
5872 return clang_getNullCursor();
5873}
5874
5875CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5876 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005877 if (const Decl *D = getCursorDecl(cursor)) {
5878 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005879 if (!DC)
5880 return clang_getNullCursor();
5881
5882 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5883 getCursorTU(cursor));
5884 }
5885 }
5886
5887 // FIXME: Note that we can't easily compute the lexical context of a
5888 // statement or expression, so we return nothing.
5889 return clang_getNullCursor();
5890}
5891
5892CXFile clang_getIncludedFile(CXCursor cursor) {
5893 if (cursor.kind != CXCursor_InclusionDirective)
5894 return 0;
5895
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005896 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005897 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005898}
5899
5900CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5901 if (!clang_isDeclaration(C.kind))
5902 return clang_getNullRange();
5903
5904 const Decl *D = getCursorDecl(C);
5905 ASTContext &Context = getCursorContext(C);
5906 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5907 if (!RC)
5908 return clang_getNullRange();
5909
5910 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5911}
5912
5913CXString clang_Cursor_getRawCommentText(CXCursor C) {
5914 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005915 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005916
5917 const Decl *D = getCursorDecl(C);
5918 ASTContext &Context = getCursorContext(C);
5919 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5920 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5921 StringRef();
5922
5923 // Don't duplicate the string because RawText points directly into source
5924 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005925 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005926}
5927
5928CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5929 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005930 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005931
5932 const Decl *D = getCursorDecl(C);
5933 const ASTContext &Context = getCursorContext(C);
5934 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5935
5936 if (RC) {
5937 StringRef BriefText = RC->getBriefText(Context);
5938
5939 // Don't duplicate the string because RawComment ensures that this memory
5940 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005941 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005942 }
5943
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005944 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005945}
5946
5947CXComment clang_Cursor_getParsedComment(CXCursor C) {
5948 if (!clang_isDeclaration(C.kind))
5949 return cxcomment::createCXComment(NULL, NULL);
5950
5951 const Decl *D = getCursorDecl(C);
5952 const ASTContext &Context = getCursorContext(C);
5953 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5954
5955 return cxcomment::createCXComment(FC, getCursorTU(C));
5956}
5957
5958CXModule clang_Cursor_getModule(CXCursor C) {
5959 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005960 if (const ImportDecl *ImportD =
5961 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005962 return ImportD->getImportedModule();
5963 }
5964
5965 return 0;
5966}
5967
5968CXModule clang_Module_getParent(CXModule CXMod) {
5969 if (!CXMod)
5970 return 0;
5971 Module *Mod = static_cast<Module*>(CXMod);
5972 return Mod->Parent;
5973}
5974
5975CXString clang_Module_getName(CXModule CXMod) {
5976 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005977 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005978 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005979 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005980}
5981
5982CXString clang_Module_getFullName(CXModule CXMod) {
5983 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005984 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005985 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005986 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005987}
5988
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00005989unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
5990 CXModule CXMod) {
5991 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005992 return 0;
5993 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00005994 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
5995 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
5996 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005997}
5998
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00005999CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6000 CXModule CXMod, unsigned Index) {
6001 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006002 return 0;
6003 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006004 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006005
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006006 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6007 if (Index < TopHeaders.size())
6008 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006009
6010 return 0;
6011}
6012
6013} // end: extern "C"
6014
6015//===----------------------------------------------------------------------===//
6016// C++ AST instrospection.
6017//===----------------------------------------------------------------------===//
6018
6019extern "C" {
6020unsigned clang_CXXMethod_isStatic(CXCursor C) {
6021 if (!clang_isDeclaration(C.kind))
6022 return 0;
6023
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006024 const CXXMethodDecl *Method = 0;
6025 const Decl *D = cxcursor::getCursorDecl(C);
6026 if (const FunctionTemplateDecl *FunTmpl =
6027 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006028 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6029 else
6030 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6031 return (Method && Method->isStatic()) ? 1 : 0;
6032}
6033
6034unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6035 if (!clang_isDeclaration(C.kind))
6036 return 0;
6037
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006038 const CXXMethodDecl *Method = 0;
6039 const Decl *D = cxcursor::getCursorDecl(C);
6040 if (const FunctionTemplateDecl *FunTmpl =
6041 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006042 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6043 else
6044 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6045 return (Method && Method->isVirtual()) ? 1 : 0;
6046}
6047} // end: extern "C"
6048
6049//===----------------------------------------------------------------------===//
6050// Attribute introspection.
6051//===----------------------------------------------------------------------===//
6052
6053extern "C" {
6054CXType clang_getIBOutletCollectionType(CXCursor C) {
6055 if (C.kind != CXCursor_IBOutletCollectionAttr)
6056 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6057
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006058 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006059 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6060
6061 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6062}
6063} // end: extern "C"
6064
6065//===----------------------------------------------------------------------===//
6066// Inspecting memory usage.
6067//===----------------------------------------------------------------------===//
6068
6069typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6070
6071static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6072 enum CXTUResourceUsageKind k,
6073 unsigned long amount) {
6074 CXTUResourceUsageEntry entry = { k, amount };
6075 entries.push_back(entry);
6076}
6077
6078extern "C" {
6079
6080const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6081 const char *str = "";
6082 switch (kind) {
6083 case CXTUResourceUsage_AST:
6084 str = "ASTContext: expressions, declarations, and types";
6085 break;
6086 case CXTUResourceUsage_Identifiers:
6087 str = "ASTContext: identifiers";
6088 break;
6089 case CXTUResourceUsage_Selectors:
6090 str = "ASTContext: selectors";
6091 break;
6092 case CXTUResourceUsage_GlobalCompletionResults:
6093 str = "Code completion: cached global results";
6094 break;
6095 case CXTUResourceUsage_SourceManagerContentCache:
6096 str = "SourceManager: content cache allocator";
6097 break;
6098 case CXTUResourceUsage_AST_SideTables:
6099 str = "ASTContext: side tables";
6100 break;
6101 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6102 str = "SourceManager: malloc'ed memory buffers";
6103 break;
6104 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6105 str = "SourceManager: mmap'ed memory buffers";
6106 break;
6107 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6108 str = "ExternalASTSource: malloc'ed memory buffers";
6109 break;
6110 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6111 str = "ExternalASTSource: mmap'ed memory buffers";
6112 break;
6113 case CXTUResourceUsage_Preprocessor:
6114 str = "Preprocessor: malloc'ed memory";
6115 break;
6116 case CXTUResourceUsage_PreprocessingRecord:
6117 str = "Preprocessor: PreprocessingRecord";
6118 break;
6119 case CXTUResourceUsage_SourceManager_DataStructures:
6120 str = "SourceManager: data structures and tables";
6121 break;
6122 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6123 str = "Preprocessor: header search tables";
6124 break;
6125 }
6126 return str;
6127}
6128
6129CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6130 if (!TU) {
6131 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6132 return usage;
6133 }
6134
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006135 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006136 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6137 ASTContext &astContext = astUnit->getASTContext();
6138
6139 // How much memory is used by AST nodes and types?
6140 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6141 (unsigned long) astContext.getASTAllocatedMemory());
6142
6143 // How much memory is used by identifiers?
6144 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6145 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6146
6147 // How much memory is used for selectors?
6148 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6149 (unsigned long) astContext.Selectors.getTotalMemory());
6150
6151 // How much memory is used by ASTContext's side tables?
6152 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6153 (unsigned long) astContext.getSideTableAllocatedMemory());
6154
6155 // How much memory is used for caching global code completion results?
6156 unsigned long completionBytes = 0;
6157 if (GlobalCodeCompletionAllocator *completionAllocator =
6158 astUnit->getCachedCompletionAllocator().getPtr()) {
6159 completionBytes = completionAllocator->getTotalMemory();
6160 }
6161 createCXTUResourceUsageEntry(*entries,
6162 CXTUResourceUsage_GlobalCompletionResults,
6163 completionBytes);
6164
6165 // How much memory is being used by SourceManager's content cache?
6166 createCXTUResourceUsageEntry(*entries,
6167 CXTUResourceUsage_SourceManagerContentCache,
6168 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6169
6170 // How much memory is being used by the MemoryBuffer's in SourceManager?
6171 const SourceManager::MemoryBufferSizes &srcBufs =
6172 astUnit->getSourceManager().getMemoryBufferSizes();
6173
6174 createCXTUResourceUsageEntry(*entries,
6175 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6176 (unsigned long) srcBufs.malloc_bytes);
6177 createCXTUResourceUsageEntry(*entries,
6178 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6179 (unsigned long) srcBufs.mmap_bytes);
6180 createCXTUResourceUsageEntry(*entries,
6181 CXTUResourceUsage_SourceManager_DataStructures,
6182 (unsigned long) astContext.getSourceManager()
6183 .getDataStructureSizes());
6184
6185 // How much memory is being used by the ExternalASTSource?
6186 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6187 const ExternalASTSource::MemoryBufferSizes &sizes =
6188 esrc->getMemoryBufferSizes();
6189
6190 createCXTUResourceUsageEntry(*entries,
6191 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6192 (unsigned long) sizes.malloc_bytes);
6193 createCXTUResourceUsageEntry(*entries,
6194 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6195 (unsigned long) sizes.mmap_bytes);
6196 }
6197
6198 // How much memory is being used by the Preprocessor?
6199 Preprocessor &pp = astUnit->getPreprocessor();
6200 createCXTUResourceUsageEntry(*entries,
6201 CXTUResourceUsage_Preprocessor,
6202 pp.getTotalMemory());
6203
6204 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6205 createCXTUResourceUsageEntry(*entries,
6206 CXTUResourceUsage_PreprocessingRecord,
6207 pRec->getTotalMemory());
6208 }
6209
6210 createCXTUResourceUsageEntry(*entries,
6211 CXTUResourceUsage_Preprocessor_HeaderSearch,
6212 pp.getHeaderSearchInfo().getTotalMemory());
6213
6214 CXTUResourceUsage usage = { (void*) entries.get(),
6215 (unsigned) entries->size(),
6216 entries->size() ? &(*entries)[0] : 0 };
6217 entries.take();
6218 return usage;
6219}
6220
6221void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6222 if (usage.data)
6223 delete (MemUsageEntries*) usage.data;
6224}
6225
6226} // end extern "C"
6227
6228void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6229 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6230 for (unsigned I = 0; I != Usage.numEntries; ++I)
6231 fprintf(stderr, " %s: %lu\n",
6232 clang_getTUResourceUsageName(Usage.entries[I].kind),
6233 Usage.entries[I].amount);
6234
6235 clang_disposeCXTUResourceUsage(Usage);
6236}
6237
6238//===----------------------------------------------------------------------===//
6239// Misc. utility functions.
6240//===----------------------------------------------------------------------===//
6241
6242/// Default to using an 8 MB stack size on "safety" threads.
6243static unsigned SafetyStackThreadSize = 8 << 20;
6244
6245namespace clang {
6246
6247bool RunSafely(llvm::CrashRecoveryContext &CRC,
6248 void (*Fn)(void*), void *UserData,
6249 unsigned Size) {
6250 if (!Size)
6251 Size = GetSafetyThreadStackSize();
6252 if (Size)
6253 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6254 return CRC.RunSafely(Fn, UserData);
6255}
6256
6257unsigned GetSafetyThreadStackSize() {
6258 return SafetyStackThreadSize;
6259}
6260
6261void SetSafetyThreadStackSize(unsigned Value) {
6262 SafetyStackThreadSize = Value;
6263}
6264
6265}
6266
6267void clang::setThreadBackgroundPriority() {
6268 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6269 return;
6270
6271 // FIXME: Move to llvm/Support and make it cross-platform.
6272#ifdef __APPLE__
6273 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6274#endif
6275}
6276
6277void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6278 if (!Unit)
6279 return;
6280
6281 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6282 DEnd = Unit->stored_diag_end();
6283 D != DEnd; ++D) {
6284 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6285 CXString Msg = clang_formatDiagnostic(&Diag,
6286 clang_defaultDiagnosticDisplayOptions());
6287 fprintf(stderr, "%s\n", clang_getCString(Msg));
6288 clang_disposeString(Msg);
6289 }
6290#ifdef LLVM_ON_WIN32
6291 // On Windows, force a flush, since there may be multiple copies of
6292 // stderr and stdout in the file system, all with different buffers
6293 // but writing to the same device.
6294 fflush(stderr);
6295#endif
6296}
6297
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006298MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6299 SourceLocation MacroDefLoc,
6300 CXTranslationUnit TU){
6301 if (MacroDefLoc.isInvalid() || !TU)
6302 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006303 if (!II.hadMacroDefinition())
6304 return 0;
6305
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006306 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006307 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006308 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006309 if (MD) {
6310 for (MacroDirective::DefInfo
6311 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6312 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6313 return Def.getMacroInfo();
6314 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006315 }
6316
6317 return 0;
6318}
6319
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006320const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6321 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006322 if (!MacroDef || !TU)
6323 return 0;
6324 const IdentifierInfo *II = MacroDef->getName();
6325 if (!II)
6326 return 0;
6327
6328 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6329}
6330
6331MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6332 const Token &Tok,
6333 CXTranslationUnit TU) {
6334 if (!MI || !TU)
6335 return 0;
6336 if (Tok.isNot(tok::raw_identifier))
6337 return 0;
6338
6339 if (MI->getNumTokens() == 0)
6340 return 0;
6341 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6342 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006343 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006344
6345 // Check that the token is inside the definition and not its argument list.
6346 SourceManager &SM = Unit->getSourceManager();
6347 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6348 return 0;
6349 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6350 return 0;
6351
6352 Preprocessor &PP = Unit->getPreprocessor();
6353 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6354 if (!PPRec)
6355 return 0;
6356
6357 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6358 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6359 if (!II.hadMacroDefinition())
6360 return 0;
6361
6362 // Check that the identifier is not one of the macro arguments.
6363 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6364 return 0;
6365
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006366 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6367 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006368 return 0;
6369
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006370 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006371}
6372
6373MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6374 SourceLocation Loc,
6375 CXTranslationUnit TU) {
6376 if (Loc.isInvalid() || !MI || !TU)
6377 return 0;
6378
6379 if (MI->getNumTokens() == 0)
6380 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006381 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006382 Preprocessor &PP = Unit->getPreprocessor();
6383 if (!PP.getPreprocessingRecord())
6384 return 0;
6385 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6386 Token Tok;
6387 if (PP.getRawToken(Loc, Tok))
6388 return 0;
6389
6390 return checkForMacroInMacroDefinition(MI, Tok, TU);
6391}
6392
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006393extern "C" {
6394
6395CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006396 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006397}
6398
6399} // end: extern "C"
6400
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006401Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6402 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006403 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006404 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006405 if (Unit->isMainFileAST())
6406 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006407 return *this;
6408 }
6409 }
6410
6411 LogOS << "<NULL TU>";
6412 return *this;
6413}
6414
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006415Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6416 *this << FE->getName();
6417 return *this;
6418}
6419
6420Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6421 CXString cursorName = clang_getCursorDisplayName(cursor);
6422 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6423 clang_disposeString(cursorName);
6424 return *this;
6425}
6426
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006427Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6428 CXFile File;
6429 unsigned Line, Column;
6430 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6431 CXString FileName = clang_getFileName(File);
6432 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6433 clang_disposeString(FileName);
6434 return *this;
6435}
6436
6437Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6438 CXSourceLocation BLoc = clang_getRangeStart(range);
6439 CXSourceLocation ELoc = clang_getRangeEnd(range);
6440
6441 CXFile BFile;
6442 unsigned BLine, BColumn;
6443 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6444
6445 CXFile EFile;
6446 unsigned ELine, EColumn;
6447 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6448
6449 CXString BFileName = clang_getFileName(BFile);
6450 if (BFile == EFile) {
6451 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6452 BLine, BColumn, ELine, EColumn);
6453 } else {
6454 CXString EFileName = clang_getFileName(EFile);
6455 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6456 BLine, BColumn)
6457 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6458 ELine, EColumn);
6459 clang_disposeString(EFileName);
6460 }
6461 clang_disposeString(BFileName);
6462 return *this;
6463}
6464
6465Logger &cxindex::Logger::operator<<(CXString Str) {
6466 *this << clang_getCString(Str);
6467 return *this;
6468}
6469
6470Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6471 LogOS << Fmt;
6472 return *this;
6473}
6474
6475cxindex::Logger::~Logger() {
6476 LogOS.flush();
6477
6478 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6479
6480 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6481
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006482 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006483 OS << "[libclang:" << Name << ':';
6484
6485 // FIXME: Portability.
6486#if HAVE_PTHREAD_H && __APPLE__
6487 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6488 OS << tid << ':';
6489#endif
6490
6491 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6492 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6493 OS << Msg.str() << '\n';
6494
6495 if (Trace) {
6496 llvm::sys::PrintStackTrace(stderr);
6497 OS << "--------------------------------------------------\n";
6498 }
6499}