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