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