blob: fd13401173fb6245de2837e6fcbb3d966618061a [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:
John McCall76da55d2013-04-16 07:28:30 +00004461 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004462 case Decl::IndirectField:
4463 case Decl::ObjCIvar:
4464 case Decl::ObjCAtDefsField:
4465 case Decl::ImplicitParam:
4466 case Decl::ParmVar:
4467 case Decl::NonTypeTemplateParm:
4468 case Decl::TemplateTemplateParm:
4469 case Decl::ObjCCategoryImpl:
4470 case Decl::ObjCImplementation:
4471 case Decl::AccessSpec:
4472 case Decl::LinkageSpec:
4473 case Decl::ObjCPropertyImpl:
4474 case Decl::FileScopeAsm:
4475 case Decl::StaticAssert:
4476 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004477 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004478 case Decl::Label: // FIXME: Is this right??
4479 case Decl::ClassScopeFunctionSpecialization:
4480 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004481 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004482 return C;
4483
4484 // Declaration kinds that don't make any sense here, but are
4485 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004486 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004487 case Decl::TranslationUnit:
4488 break;
4489
4490 // Declaration kinds for which the definition is not resolvable.
4491 case Decl::UnresolvedUsingTypename:
4492 case Decl::UnresolvedUsingValue:
4493 break;
4494
4495 case Decl::UsingDirective:
4496 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4497 TU);
4498
4499 case Decl::NamespaceAlias:
4500 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4501
4502 case Decl::Enum:
4503 case Decl::Record:
4504 case Decl::CXXRecord:
4505 case Decl::ClassTemplateSpecialization:
4506 case Decl::ClassTemplatePartialSpecialization:
4507 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4508 return MakeCXCursor(Def, TU);
4509 return clang_getNullCursor();
4510
4511 case Decl::Function:
4512 case Decl::CXXMethod:
4513 case Decl::CXXConstructor:
4514 case Decl::CXXDestructor:
4515 case Decl::CXXConversion: {
4516 const FunctionDecl *Def = 0;
4517 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004518 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004519 return clang_getNullCursor();
4520 }
4521
4522 case Decl::Var: {
4523 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004524 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004525 return MakeCXCursor(Def, TU);
4526 return clang_getNullCursor();
4527 }
4528
4529 case Decl::FunctionTemplate: {
4530 const FunctionDecl *Def = 0;
4531 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4532 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4533 return clang_getNullCursor();
4534 }
4535
4536 case Decl::ClassTemplate: {
4537 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4538 ->getDefinition())
4539 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4540 TU);
4541 return clang_getNullCursor();
4542 }
4543
4544 case Decl::Using:
4545 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4546 D->getLocation(), TU);
4547
4548 case Decl::UsingShadow:
4549 return clang_getCursorDefinition(
4550 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4551 TU));
4552
4553 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004554 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004555 if (Method->isThisDeclarationADefinition())
4556 return C;
4557
4558 // Dig out the method definition in the associated
4559 // @implementation, if we have it.
4560 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004561 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004562 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4563 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4564 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4565 Method->isInstanceMethod()))
4566 if (Def->isThisDeclarationADefinition())
4567 return MakeCXCursor(Def, TU);
4568
4569 return clang_getNullCursor();
4570 }
4571
4572 case Decl::ObjCCategory:
4573 if (ObjCCategoryImplDecl *Impl
4574 = cast<ObjCCategoryDecl>(D)->getImplementation())
4575 return MakeCXCursor(Impl, TU);
4576 return clang_getNullCursor();
4577
4578 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004579 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004580 return MakeCXCursor(Def, TU);
4581 return clang_getNullCursor();
4582
4583 case Decl::ObjCInterface: {
4584 // There are two notions of a "definition" for an Objective-C
4585 // class: the interface and its implementation. When we resolved a
4586 // reference to an Objective-C class, produce the @interface as
4587 // the definition; when we were provided with the interface,
4588 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004589 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004590 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004591 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004592 return MakeCXCursor(Def, TU);
4593 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4594 return MakeCXCursor(Impl, TU);
4595 return clang_getNullCursor();
4596 }
4597
4598 case Decl::ObjCProperty:
4599 // FIXME: We don't really know where to find the
4600 // ObjCPropertyImplDecls that implement this property.
4601 return clang_getNullCursor();
4602
4603 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004604 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004605 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004606 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004607 return MakeCXCursor(Def, TU);
4608
4609 return clang_getNullCursor();
4610
4611 case Decl::Friend:
4612 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4613 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4614 return clang_getNullCursor();
4615
4616 case Decl::FriendTemplate:
4617 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4618 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4619 return clang_getNullCursor();
4620 }
4621
4622 return clang_getNullCursor();
4623}
4624
4625unsigned clang_isCursorDefinition(CXCursor C) {
4626 if (!clang_isDeclaration(C.kind))
4627 return 0;
4628
4629 return clang_getCursorDefinition(C) == C;
4630}
4631
4632CXCursor clang_getCanonicalCursor(CXCursor C) {
4633 if (!clang_isDeclaration(C.kind))
4634 return C;
4635
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004636 if (const Decl *D = getCursorDecl(C)) {
4637 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004638 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4639 return MakeCXCursor(CatD, getCursorTU(C));
4640
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004641 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4642 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004643 return MakeCXCursor(IFD, getCursorTU(C));
4644
4645 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4646 }
4647
4648 return C;
4649}
4650
4651int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4652 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4653}
4654
4655unsigned clang_getNumOverloadedDecls(CXCursor C) {
4656 if (C.kind != CXCursor_OverloadedDeclRef)
4657 return 0;
4658
4659 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004660 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004661 return E->getNumDecls();
4662
4663 if (OverloadedTemplateStorage *S
4664 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4665 return S->size();
4666
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004667 const Decl *D = Storage.get<const Decl *>();
4668 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004669 return Using->shadow_size();
4670
4671 return 0;
4672}
4673
4674CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4675 if (cursor.kind != CXCursor_OverloadedDeclRef)
4676 return clang_getNullCursor();
4677
4678 if (index >= clang_getNumOverloadedDecls(cursor))
4679 return clang_getNullCursor();
4680
4681 CXTranslationUnit TU = getCursorTU(cursor);
4682 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004683 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004684 return MakeCXCursor(E->decls_begin()[index], TU);
4685
4686 if (OverloadedTemplateStorage *S
4687 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4688 return MakeCXCursor(S->begin()[index], TU);
4689
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004690 const Decl *D = Storage.get<const Decl *>();
4691 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004692 // FIXME: This is, unfortunately, linear time.
4693 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4694 std::advance(Pos, index);
4695 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4696 }
4697
4698 return clang_getNullCursor();
4699}
4700
4701void clang_getDefinitionSpellingAndExtent(CXCursor C,
4702 const char **startBuf,
4703 const char **endBuf,
4704 unsigned *startLine,
4705 unsigned *startColumn,
4706 unsigned *endLine,
4707 unsigned *endColumn) {
4708 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004709 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004710 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4711
4712 SourceManager &SM = FD->getASTContext().getSourceManager();
4713 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4714 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4715 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4716 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4717 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4718 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4719}
4720
4721
4722CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4723 unsigned PieceIndex) {
4724 RefNamePieces Pieces;
4725
4726 switch (C.kind) {
4727 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004728 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004729 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4730 E->getQualifierLoc().getSourceRange());
4731 break;
4732
4733 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004734 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004735 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4736 E->getQualifierLoc().getSourceRange(),
4737 E->getOptionalExplicitTemplateArgs());
4738 break;
4739
4740 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004741 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004742 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004743 const Expr *Callee = OCE->getCallee();
4744 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004745 Callee = ICE->getSubExpr();
4746
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004747 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004748 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4749 DRE->getQualifierLoc().getSourceRange());
4750 }
4751 break;
4752
4753 default:
4754 break;
4755 }
4756
4757 if (Pieces.empty()) {
4758 if (PieceIndex == 0)
4759 return clang_getCursorExtent(C);
4760 } else if (PieceIndex < Pieces.size()) {
4761 SourceRange R = Pieces[PieceIndex];
4762 if (R.isValid())
4763 return cxloc::translateSourceRange(getCursorContext(C), R);
4764 }
4765
4766 return clang_getNullRange();
4767}
4768
4769void clang_enableStackTraces(void) {
4770 llvm::sys::PrintStackTraceOnErrorSignal();
4771}
4772
4773void clang_executeOnThread(void (*fn)(void*), void *user_data,
4774 unsigned stack_size) {
4775 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4776}
4777
4778} // end: extern "C"
4779
4780//===----------------------------------------------------------------------===//
4781// Token-based Operations.
4782//===----------------------------------------------------------------------===//
4783
4784/* CXToken layout:
4785 * int_data[0]: a CXTokenKind
4786 * int_data[1]: starting token location
4787 * int_data[2]: token length
4788 * int_data[3]: reserved
4789 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4790 * otherwise unused.
4791 */
4792extern "C" {
4793
4794CXTokenKind clang_getTokenKind(CXToken CXTok) {
4795 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4796}
4797
4798CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4799 switch (clang_getTokenKind(CXTok)) {
4800 case CXToken_Identifier:
4801 case CXToken_Keyword:
4802 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004803 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004804 ->getNameStart());
4805
4806 case CXToken_Literal: {
4807 // We have stashed the starting pointer in the ptr_data field. Use it.
4808 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004809 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004810 }
4811
4812 case CXToken_Punctuation:
4813 case CXToken_Comment:
4814 break;
4815 }
4816
4817 // We have to find the starting buffer pointer the hard way, by
4818 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004819 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004820 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004821 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004822
4823 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4824 std::pair<FileID, unsigned> LocInfo
4825 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4826 bool Invalid = false;
4827 StringRef Buffer
4828 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4829 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004830 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004831
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004832 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004833}
4834
4835CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004836 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004837 if (!CXXUnit)
4838 return clang_getNullLocation();
4839
4840 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4841 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4842}
4843
4844CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004845 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004846 if (!CXXUnit)
4847 return clang_getNullRange();
4848
4849 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4850 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4851}
4852
4853static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4854 SmallVectorImpl<CXToken> &CXTokens) {
4855 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4856 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004857 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004858 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004859 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004860
4861 // Cannot tokenize across files.
4862 if (BeginLocInfo.first != EndLocInfo.first)
4863 return;
4864
4865 // Create a lexer
4866 bool Invalid = false;
4867 StringRef Buffer
4868 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4869 if (Invalid)
4870 return;
4871
4872 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4873 CXXUnit->getASTContext().getLangOpts(),
4874 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4875 Lex.SetCommentRetentionState(true);
4876
4877 // Lex tokens until we hit the end of the range.
4878 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4879 Token Tok;
4880 bool previousWasAt = false;
4881 do {
4882 // Lex the next token
4883 Lex.LexFromRawLexer(Tok);
4884 if (Tok.is(tok::eof))
4885 break;
4886
4887 // Initialize the CXToken.
4888 CXToken CXTok;
4889
4890 // - Common fields
4891 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4892 CXTok.int_data[2] = Tok.getLength();
4893 CXTok.int_data[3] = 0;
4894
4895 // - Kind-specific fields
4896 if (Tok.isLiteral()) {
4897 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004898 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004899 } else if (Tok.is(tok::raw_identifier)) {
4900 // Lookup the identifier to determine whether we have a keyword.
4901 IdentifierInfo *II
4902 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4903
4904 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4905 CXTok.int_data[0] = CXToken_Keyword;
4906 }
4907 else {
4908 CXTok.int_data[0] = Tok.is(tok::identifier)
4909 ? CXToken_Identifier
4910 : CXToken_Keyword;
4911 }
4912 CXTok.ptr_data = II;
4913 } else if (Tok.is(tok::comment)) {
4914 CXTok.int_data[0] = CXToken_Comment;
4915 CXTok.ptr_data = 0;
4916 } else {
4917 CXTok.int_data[0] = CXToken_Punctuation;
4918 CXTok.ptr_data = 0;
4919 }
4920 CXTokens.push_back(CXTok);
4921 previousWasAt = Tok.is(tok::at);
4922 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4923}
4924
4925void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4926 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004927 LOG_FUNC_SECTION {
4928 *Log << TU << ' ' << Range;
4929 }
4930
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004931 if (Tokens)
4932 *Tokens = 0;
4933 if (NumTokens)
4934 *NumTokens = 0;
4935
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004936 if (!TU)
4937 return;
4938
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004939 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004940 if (!CXXUnit || !Tokens || !NumTokens)
4941 return;
4942
4943 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4944
4945 SourceRange R = cxloc::translateCXSourceRange(Range);
4946 if (R.isInvalid())
4947 return;
4948
4949 SmallVector<CXToken, 32> CXTokens;
4950 getTokens(CXXUnit, R, CXTokens);
4951
4952 if (CXTokens.empty())
4953 return;
4954
4955 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4956 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4957 *NumTokens = CXTokens.size();
4958}
4959
4960void clang_disposeTokens(CXTranslationUnit TU,
4961 CXToken *Tokens, unsigned NumTokens) {
4962 free(Tokens);
4963}
4964
4965} // end: extern "C"
4966
4967//===----------------------------------------------------------------------===//
4968// Token annotation APIs.
4969//===----------------------------------------------------------------------===//
4970
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004971static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4972 CXCursor parent,
4973 CXClientData client_data);
4974static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4975 CXClientData client_data);
4976
4977namespace {
4978class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004979 CXToken *Tokens;
4980 CXCursor *Cursors;
4981 unsigned NumTokens;
4982 unsigned TokIdx;
4983 unsigned PreprocessingTokIdx;
4984 CursorVisitor AnnotateVis;
4985 SourceManager &SrcMgr;
4986 bool HasContextSensitiveKeywords;
4987
4988 struct PostChildrenInfo {
4989 CXCursor Cursor;
4990 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004991 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004992 unsigned BeforeChildrenTokenIdx;
4993 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004994 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004995
4996 bool MoreTokens() const { return TokIdx < NumTokens; }
4997 unsigned NextToken() const { return TokIdx; }
4998 void AdvanceToken() { ++TokIdx; }
4999 SourceLocation GetTokenLoc(unsigned tokI) {
5000 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5001 }
5002 bool isFunctionMacroToken(unsigned tokI) const {
5003 return Tokens[tokI].int_data[3] != 0;
5004 }
5005 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5006 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5007 }
5008
5009 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005010 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005011 SourceRange);
5012
5013public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005014 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005015 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005016 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005017 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005018 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005019 AnnotateTokensVisitor, this,
5020 /*VisitPreprocessorLast=*/true,
5021 /*VisitIncludedEntities=*/false,
5022 RegionOfInterest,
5023 /*VisitDeclsOnly=*/false,
5024 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005025 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005026 HasContextSensitiveKeywords(false) { }
5027
5028 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5029 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5030 bool postVisitChildren(CXCursor cursor);
5031 void AnnotateTokens();
5032
5033 /// \brief Determine whether the annotator saw any cursors that have
5034 /// context-sensitive keywords.
5035 bool hasContextSensitiveKeywords() const {
5036 return HasContextSensitiveKeywords;
5037 }
5038
5039 ~AnnotateTokensWorker() {
5040 assert(PostChildrenInfos.empty());
5041 }
5042};
5043}
5044
5045void AnnotateTokensWorker::AnnotateTokens() {
5046 // Walk the AST within the region of interest, annotating tokens
5047 // along the way.
5048 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005049}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005050
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005051static inline void updateCursorAnnotation(CXCursor &Cursor,
5052 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005053 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005054 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005055 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005056}
5057
5058/// \brief It annotates and advances tokens with a cursor until the comparison
5059//// between the cursor location and the source range is the same as
5060/// \arg compResult.
5061///
5062/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5063/// Pass RangeOverlap to annotate tokens inside a range.
5064void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5065 RangeComparisonResult compResult,
5066 SourceRange range) {
5067 while (MoreTokens()) {
5068 const unsigned I = NextToken();
5069 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005070 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5071 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005072
5073 SourceLocation TokLoc = GetTokenLoc(I);
5074 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005075 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005076 AdvanceToken();
5077 continue;
5078 }
5079 break;
5080 }
5081}
5082
5083/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005084/// \returns true if it advanced beyond all macro tokens, false otherwise.
5085bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005086 CXCursor updateC,
5087 RangeComparisonResult compResult,
5088 SourceRange range) {
5089 assert(MoreTokens());
5090 assert(isFunctionMacroToken(NextToken()) &&
5091 "Should be called only for macro arg tokens");
5092
5093 // This works differently than annotateAndAdvanceTokens; because expanded
5094 // macro arguments can have arbitrary translation-unit source order, we do not
5095 // advance the token index one by one until a token fails the range test.
5096 // We only advance once past all of the macro arg tokens if all of them
5097 // pass the range test. If one of them fails we keep the token index pointing
5098 // at the start of the macro arg tokens so that the failing token will be
5099 // annotated by a subsequent annotation try.
5100
5101 bool atLeastOneCompFail = false;
5102
5103 unsigned I = NextToken();
5104 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5105 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5106 if (TokLoc.isFileID())
5107 continue; // not macro arg token, it's parens or comma.
5108 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5109 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5110 Cursors[I] = updateC;
5111 } else
5112 atLeastOneCompFail = true;
5113 }
5114
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005115 if (atLeastOneCompFail)
5116 return false;
5117
5118 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5119 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005120}
5121
5122enum CXChildVisitResult
5123AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005124 SourceRange cursorRange = getRawCursorExtent(cursor);
5125 if (cursorRange.isInvalid())
5126 return CXChildVisit_Recurse;
5127
5128 if (!HasContextSensitiveKeywords) {
5129 // Objective-C properties can have context-sensitive keywords.
5130 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005131 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005132 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5133 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5134 }
5135 // Objective-C methods can have context-sensitive keywords.
5136 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5137 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005138 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005139 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5140 if (Method->getObjCDeclQualifier())
5141 HasContextSensitiveKeywords = true;
5142 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005143 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5144 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005145 P != PEnd; ++P) {
5146 if ((*P)->getObjCDeclQualifier()) {
5147 HasContextSensitiveKeywords = true;
5148 break;
5149 }
5150 }
5151 }
5152 }
5153 }
5154 // C++ methods can have context-sensitive keywords.
5155 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005156 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005157 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5158 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5159 HasContextSensitiveKeywords = true;
5160 }
5161 }
5162 // C++ classes can have context-sensitive keywords.
5163 else if (cursor.kind == CXCursor_StructDecl ||
5164 cursor.kind == CXCursor_ClassDecl ||
5165 cursor.kind == CXCursor_ClassTemplate ||
5166 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005167 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005168 if (D->hasAttr<FinalAttr>())
5169 HasContextSensitiveKeywords = true;
5170 }
5171 }
5172
5173 if (clang_isPreprocessing(cursor.kind)) {
5174 // Items in the preprocessing record are kept separate from items in
5175 // declarations, so we keep a separate token index.
5176 unsigned SavedTokIdx = TokIdx;
5177 TokIdx = PreprocessingTokIdx;
5178
5179 // Skip tokens up until we catch up to the beginning of the preprocessing
5180 // entry.
5181 while (MoreTokens()) {
5182 const unsigned I = NextToken();
5183 SourceLocation TokLoc = GetTokenLoc(I);
5184 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5185 case RangeBefore:
5186 AdvanceToken();
5187 continue;
5188 case RangeAfter:
5189 case RangeOverlap:
5190 break;
5191 }
5192 break;
5193 }
5194
5195 // Look at all of the tokens within this range.
5196 while (MoreTokens()) {
5197 const unsigned I = NextToken();
5198 SourceLocation TokLoc = GetTokenLoc(I);
5199 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5200 case RangeBefore:
5201 llvm_unreachable("Infeasible");
5202 case RangeAfter:
5203 break;
5204 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005205 // For macro expansions, just note where the beginning of the macro
5206 // expansion occurs.
5207 if (cursor.kind == CXCursor_MacroExpansion) {
5208 if (TokLoc == cursorRange.getBegin())
5209 Cursors[I] = cursor;
5210 AdvanceToken();
5211 break;
5212 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005213 // We may have already annotated macro names inside macro definitions.
5214 if (Cursors[I].kind != CXCursor_MacroExpansion)
5215 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005216 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005217 continue;
5218 }
5219 break;
5220 }
5221
5222 // Save the preprocessing token index; restore the non-preprocessing
5223 // token index.
5224 PreprocessingTokIdx = TokIdx;
5225 TokIdx = SavedTokIdx;
5226 return CXChildVisit_Recurse;
5227 }
5228
5229 if (cursorRange.isInvalid())
5230 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005231
5232 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005233 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005234 const enum CXCursorKind K = clang_getCursorKind(parent);
5235 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005236 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5237 // Attributes are annotated out-of-order, skip tokens until we reach it.
5238 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005239 ? clang_getNullCursor() : parent;
5240
5241 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5242
5243 // Avoid having the cursor of an expression "overwrite" the annotation of the
5244 // variable declaration that it belongs to.
5245 // This can happen for C++ constructor expressions whose range generally
5246 // include the variable declaration, e.g.:
5247 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5248 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005249 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005250 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005251 const unsigned I = NextToken();
5252 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5253 E->getLocStart() == D->getLocation() &&
5254 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005255 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005256 AdvanceToken();
5257 }
5258 }
5259 }
5260
5261 // Before recursing into the children keep some state that we are going
5262 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5263 // extra work after the child nodes are visited.
5264 // Note that we don't call VisitChildren here to avoid traversing statements
5265 // code-recursively which can blow the stack.
5266
5267 PostChildrenInfo Info;
5268 Info.Cursor = cursor;
5269 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005270 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005271 Info.BeforeChildrenTokenIdx = NextToken();
5272 PostChildrenInfos.push_back(Info);
5273
5274 return CXChildVisit_Recurse;
5275}
5276
5277bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5278 if (PostChildrenInfos.empty())
5279 return false;
5280 const PostChildrenInfo &Info = PostChildrenInfos.back();
5281 if (!clang_equalCursors(Info.Cursor, cursor))
5282 return false;
5283
5284 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5285 const unsigned AfterChildren = NextToken();
5286 SourceRange cursorRange = Info.CursorRange;
5287
5288 // Scan the tokens that are at the end of the cursor, but are not captured
5289 // but the child cursors.
5290 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5291
5292 // Scan the tokens that are at the beginning of the cursor, but are not
5293 // capture by the child cursors.
5294 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5295 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5296 break;
5297
5298 Cursors[I] = cursor;
5299 }
5300
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005301 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5302 // encountered the attribute cursor.
5303 if (clang_isAttribute(cursor.kind))
5304 TokIdx = Info.BeforeReachingCursorIdx;
5305
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005306 PostChildrenInfos.pop_back();
5307 return false;
5308}
5309
5310static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5311 CXCursor parent,
5312 CXClientData client_data) {
5313 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5314}
5315
5316static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5317 CXClientData client_data) {
5318 return static_cast<AnnotateTokensWorker*>(client_data)->
5319 postVisitChildren(cursor);
5320}
5321
5322namespace {
5323
5324/// \brief Uses the macro expansions in the preprocessing record to find
5325/// and mark tokens that are macro arguments. This info is used by the
5326/// AnnotateTokensWorker.
5327class MarkMacroArgTokensVisitor {
5328 SourceManager &SM;
5329 CXToken *Tokens;
5330 unsigned NumTokens;
5331 unsigned CurIdx;
5332
5333public:
5334 MarkMacroArgTokensVisitor(SourceManager &SM,
5335 CXToken *tokens, unsigned numTokens)
5336 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5337
5338 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5339 if (cursor.kind != CXCursor_MacroExpansion)
5340 return CXChildVisit_Continue;
5341
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005342 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005343 if (macroRange.getBegin() == macroRange.getEnd())
5344 return CXChildVisit_Continue; // it's not a function macro.
5345
5346 for (; CurIdx < NumTokens; ++CurIdx) {
5347 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5348 macroRange.getBegin()))
5349 break;
5350 }
5351
5352 if (CurIdx == NumTokens)
5353 return CXChildVisit_Break;
5354
5355 for (; CurIdx < NumTokens; ++CurIdx) {
5356 SourceLocation tokLoc = getTokenLoc(CurIdx);
5357 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5358 break;
5359
5360 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5361 }
5362
5363 if (CurIdx == NumTokens)
5364 return CXChildVisit_Break;
5365
5366 return CXChildVisit_Continue;
5367 }
5368
5369private:
5370 SourceLocation getTokenLoc(unsigned tokI) {
5371 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5372 }
5373
5374 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5375 // The third field is reserved and currently not used. Use it here
5376 // to mark macro arg expanded tokens with their expanded locations.
5377 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5378 }
5379};
5380
5381} // end anonymous namespace
5382
5383static CXChildVisitResult
5384MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5385 CXClientData client_data) {
5386 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5387 parent);
5388}
5389
5390namespace {
5391 struct clang_annotateTokens_Data {
5392 CXTranslationUnit TU;
5393 ASTUnit *CXXUnit;
5394 CXToken *Tokens;
5395 unsigned NumTokens;
5396 CXCursor *Cursors;
5397 };
5398}
5399
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005400/// \brief Used by \c annotatePreprocessorTokens.
5401/// \returns true if lexing was finished, false otherwise.
5402static bool lexNext(Lexer &Lex, Token &Tok,
5403 unsigned &NextIdx, unsigned NumTokens) {
5404 if (NextIdx >= NumTokens)
5405 return true;
5406
5407 ++NextIdx;
5408 Lex.LexFromRawLexer(Tok);
5409 if (Tok.is(tok::eof))
5410 return true;
5411
5412 return false;
5413}
5414
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005415static void annotatePreprocessorTokens(CXTranslationUnit TU,
5416 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005417 CXCursor *Cursors,
5418 CXToken *Tokens,
5419 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005420 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005421
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005422 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005423 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5424 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005425 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005426 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005427 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005428
5429 if (BeginLocInfo.first != EndLocInfo.first)
5430 return;
5431
5432 StringRef Buffer;
5433 bool Invalid = false;
5434 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5435 if (Buffer.empty() || Invalid)
5436 return;
5437
5438 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5439 CXXUnit->getASTContext().getLangOpts(),
5440 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5441 Buffer.end());
5442 Lex.SetCommentRetentionState(true);
5443
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005444 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005445 // Lex tokens in raw mode until we hit the end of the range, to avoid
5446 // entering #includes or expanding macros.
5447 while (true) {
5448 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005449 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5450 break;
5451 unsigned TokIdx = NextIdx-1;
5452 assert(Tok.getLocation() ==
5453 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005454
5455 reprocess:
5456 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005457 // We have found a preprocessing directive. Annotate the tokens
5458 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005459 //
5460 // FIXME: Some simple tests here could identify macro definitions and
5461 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005462
5463 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005464 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5465 break;
5466
5467 MacroInfo *MI = 0;
5468 if (Tok.is(tok::raw_identifier) &&
5469 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5470 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5471 break;
5472
5473 if (Tok.is(tok::raw_identifier)) {
5474 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5475 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5476 SourceLocation MappedTokLoc =
5477 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5478 MI = getMacroInfo(II, MappedTokLoc, TU);
5479 }
5480 }
5481
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005482 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005483 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005484 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5485 finished = true;
5486 break;
5487 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005488 // If we are in a macro definition, check if the token was ever a
5489 // macro name and annotate it if that's the case.
5490 if (MI) {
5491 SourceLocation SaveLoc = Tok.getLocation();
5492 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5493 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5494 Tok.setLocation(SaveLoc);
5495 if (MacroDef)
5496 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5497 Tok.getLocation(), TU);
5498 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005499 } while (!Tok.isAtStartOfLine());
5500
5501 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5502 assert(TokIdx <= LastIdx);
5503 SourceLocation EndLoc =
5504 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5505 CXCursor Cursor =
5506 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5507
5508 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005509 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005510
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005511 if (finished)
5512 break;
5513 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005514 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005515 }
5516}
5517
5518// This gets run a separate thread to avoid stack blowout.
5519static void clang_annotateTokensImpl(void *UserData) {
5520 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5521 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5522 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5523 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5524 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5525
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005526 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005527 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5528 setThreadBackgroundPriority();
5529
5530 // Determine the region of interest, which contains all of the tokens.
5531 SourceRange RegionOfInterest;
5532 RegionOfInterest.setBegin(
5533 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5534 RegionOfInterest.setEnd(
5535 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5536 Tokens[NumTokens-1])));
5537
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005538 // Relex the tokens within the source range to look for preprocessing
5539 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005540 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005541
5542 // If begin location points inside a macro argument, set it to the expansion
5543 // location so we can have the full context when annotating semantically.
5544 {
5545 SourceManager &SM = CXXUnit->getSourceManager();
5546 SourceLocation Loc =
5547 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5548 if (Loc.isMacroID())
5549 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5550 }
5551
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005552 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5553 // Search and mark tokens that are macro argument expansions.
5554 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5555 Tokens, NumTokens);
5556 CursorVisitor MacroArgMarker(TU,
5557 MarkMacroArgTokensVisitorDelegate, &Visitor,
5558 /*VisitPreprocessorLast=*/true,
5559 /*VisitIncludedEntities=*/false,
5560 RegionOfInterest);
5561 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5562 }
5563
5564 // Annotate all of the source locations in the region of interest that map to
5565 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005566 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005567
5568 // FIXME: We use a ridiculous stack size here because the data-recursion
5569 // algorithm uses a large stack frame than the non-data recursive version,
5570 // and AnnotationTokensWorker currently transforms the data-recursion
5571 // algorithm back into a traditional recursion by explicitly calling
5572 // VisitChildren(). We will need to remove this explicit recursive call.
5573 W.AnnotateTokens();
5574
5575 // If we ran into any entities that involve context-sensitive keywords,
5576 // take another pass through the tokens to mark them as such.
5577 if (W.hasContextSensitiveKeywords()) {
5578 for (unsigned I = 0; I != NumTokens; ++I) {
5579 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5580 continue;
5581
5582 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5583 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005584 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005585 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5586 if (Property->getPropertyAttributesAsWritten() != 0 &&
5587 llvm::StringSwitch<bool>(II->getName())
5588 .Case("readonly", true)
5589 .Case("assign", true)
5590 .Case("unsafe_unretained", true)
5591 .Case("readwrite", true)
5592 .Case("retain", true)
5593 .Case("copy", true)
5594 .Case("nonatomic", true)
5595 .Case("atomic", true)
5596 .Case("getter", true)
5597 .Case("setter", true)
5598 .Case("strong", true)
5599 .Case("weak", true)
5600 .Default(false))
5601 Tokens[I].int_data[0] = CXToken_Keyword;
5602 }
5603 continue;
5604 }
5605
5606 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5607 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5608 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5609 if (llvm::StringSwitch<bool>(II->getName())
5610 .Case("in", true)
5611 .Case("out", true)
5612 .Case("inout", true)
5613 .Case("oneway", true)
5614 .Case("bycopy", true)
5615 .Case("byref", true)
5616 .Default(false))
5617 Tokens[I].int_data[0] = CXToken_Keyword;
5618 continue;
5619 }
5620
5621 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5622 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5623 Tokens[I].int_data[0] = CXToken_Keyword;
5624 continue;
5625 }
5626 }
5627 }
5628}
5629
5630extern "C" {
5631
5632void clang_annotateTokens(CXTranslationUnit TU,
5633 CXToken *Tokens, unsigned NumTokens,
5634 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005635 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005636 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005637 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005638 }
5639
5640 LOG_FUNC_SECTION {
5641 *Log << TU << ' ';
5642 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5643 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5644 *Log << clang_getRange(bloc, eloc);
5645 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005646
5647 // Any token we don't specifically annotate will have a NULL cursor.
5648 CXCursor C = clang_getNullCursor();
5649 for (unsigned I = 0; I != NumTokens; ++I)
5650 Cursors[I] = C;
5651
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005652 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005653 if (!CXXUnit)
5654 return;
5655
5656 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5657
5658 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5659 llvm::CrashRecoveryContext CRC;
5660 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5661 GetSafetyThreadStackSize() * 2)) {
5662 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5663 }
5664}
5665
5666} // end: extern "C"
5667
5668//===----------------------------------------------------------------------===//
5669// Operations for querying linkage of a cursor.
5670//===----------------------------------------------------------------------===//
5671
5672extern "C" {
5673CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5674 if (!clang_isDeclaration(cursor.kind))
5675 return CXLinkage_Invalid;
5676
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005677 const Decl *D = cxcursor::getCursorDecl(cursor);
5678 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005679 switch (ND->getLinkage()) {
5680 case NoLinkage: return CXLinkage_NoLinkage;
5681 case InternalLinkage: return CXLinkage_Internal;
5682 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5683 case ExternalLinkage: return CXLinkage_External;
5684 };
5685
5686 return CXLinkage_Invalid;
5687}
5688} // end: extern "C"
5689
5690//===----------------------------------------------------------------------===//
5691// Operations for querying language of a cursor.
5692//===----------------------------------------------------------------------===//
5693
5694static CXLanguageKind getDeclLanguage(const Decl *D) {
5695 if (!D)
5696 return CXLanguage_C;
5697
5698 switch (D->getKind()) {
5699 default:
5700 break;
5701 case Decl::ImplicitParam:
5702 case Decl::ObjCAtDefsField:
5703 case Decl::ObjCCategory:
5704 case Decl::ObjCCategoryImpl:
5705 case Decl::ObjCCompatibleAlias:
5706 case Decl::ObjCImplementation:
5707 case Decl::ObjCInterface:
5708 case Decl::ObjCIvar:
5709 case Decl::ObjCMethod:
5710 case Decl::ObjCProperty:
5711 case Decl::ObjCPropertyImpl:
5712 case Decl::ObjCProtocol:
5713 return CXLanguage_ObjC;
5714 case Decl::CXXConstructor:
5715 case Decl::CXXConversion:
5716 case Decl::CXXDestructor:
5717 case Decl::CXXMethod:
5718 case Decl::CXXRecord:
5719 case Decl::ClassTemplate:
5720 case Decl::ClassTemplatePartialSpecialization:
5721 case Decl::ClassTemplateSpecialization:
5722 case Decl::Friend:
5723 case Decl::FriendTemplate:
5724 case Decl::FunctionTemplate:
5725 case Decl::LinkageSpec:
5726 case Decl::Namespace:
5727 case Decl::NamespaceAlias:
5728 case Decl::NonTypeTemplateParm:
5729 case Decl::StaticAssert:
5730 case Decl::TemplateTemplateParm:
5731 case Decl::TemplateTypeParm:
5732 case Decl::UnresolvedUsingTypename:
5733 case Decl::UnresolvedUsingValue:
5734 case Decl::Using:
5735 case Decl::UsingDirective:
5736 case Decl::UsingShadow:
5737 return CXLanguage_CPlusPlus;
5738 }
5739
5740 return CXLanguage_C;
5741}
5742
5743extern "C" {
5744
5745enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5746 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005747 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005748 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5749 return CXAvailability_Available;
5750
5751 switch (D->getAvailability()) {
5752 case AR_Available:
5753 case AR_NotYetIntroduced:
5754 return CXAvailability_Available;
5755
5756 case AR_Deprecated:
5757 return CXAvailability_Deprecated;
5758
5759 case AR_Unavailable:
5760 return CXAvailability_NotAvailable;
5761 }
5762 }
5763
5764 return CXAvailability_Available;
5765}
5766
5767static CXVersion convertVersion(VersionTuple In) {
5768 CXVersion Out = { -1, -1, -1 };
5769 if (In.empty())
5770 return Out;
5771
5772 Out.Major = In.getMajor();
5773
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005774 Optional<unsigned> Minor = In.getMinor();
5775 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005776 Out.Minor = *Minor;
5777 else
5778 return Out;
5779
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005780 Optional<unsigned> Subminor = In.getSubminor();
5781 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005782 Out.Subminor = *Subminor;
5783
5784 return Out;
5785}
5786
5787int clang_getCursorPlatformAvailability(CXCursor cursor,
5788 int *always_deprecated,
5789 CXString *deprecated_message,
5790 int *always_unavailable,
5791 CXString *unavailable_message,
5792 CXPlatformAvailability *availability,
5793 int availability_size) {
5794 if (always_deprecated)
5795 *always_deprecated = 0;
5796 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005797 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005798 if (always_unavailable)
5799 *always_unavailable = 0;
5800 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005801 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005802
5803 if (!clang_isDeclaration(cursor.kind))
5804 return 0;
5805
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005806 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005807 if (!D)
5808 return 0;
5809
5810 int N = 0;
5811 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5812 ++A) {
5813 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5814 if (always_deprecated)
5815 *always_deprecated = 1;
5816 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005817 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005818 continue;
5819 }
5820
5821 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5822 if (always_unavailable)
5823 *always_unavailable = 1;
5824 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005825 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005826 }
5827 continue;
5828 }
5829
5830 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5831 if (N < availability_size) {
5832 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005833 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005834 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5835 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5836 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5837 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005838 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005839 }
5840 ++N;
5841 }
5842 }
5843
5844 return N;
5845}
5846
5847void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5848 clang_disposeString(availability->Platform);
5849 clang_disposeString(availability->Message);
5850}
5851
5852CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5853 if (clang_isDeclaration(cursor.kind))
5854 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5855
5856 return CXLanguage_Invalid;
5857}
5858
5859 /// \brief If the given cursor is the "templated" declaration
5860 /// descibing a class or function template, return the class or
5861 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005862static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005863 if (!D)
5864 return 0;
5865
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005866 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005867 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5868 return FunTmpl;
5869
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005870 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005871 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5872 return ClassTmpl;
5873
5874 return D;
5875}
5876
5877CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5878 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005879 if (const Decl *D = getCursorDecl(cursor)) {
5880 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005881 if (!DC)
5882 return clang_getNullCursor();
5883
5884 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5885 getCursorTU(cursor));
5886 }
5887 }
5888
5889 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005890 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005891 return MakeCXCursor(D, getCursorTU(cursor));
5892 }
5893
5894 return clang_getNullCursor();
5895}
5896
5897CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5898 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005899 if (const Decl *D = getCursorDecl(cursor)) {
5900 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005901 if (!DC)
5902 return clang_getNullCursor();
5903
5904 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5905 getCursorTU(cursor));
5906 }
5907 }
5908
5909 // FIXME: Note that we can't easily compute the lexical context of a
5910 // statement or expression, so we return nothing.
5911 return clang_getNullCursor();
5912}
5913
5914CXFile clang_getIncludedFile(CXCursor cursor) {
5915 if (cursor.kind != CXCursor_InclusionDirective)
5916 return 0;
5917
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005918 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005919 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005920}
5921
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005922unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5923 if (C.kind != CXCursor_ObjCPropertyDecl)
5924 return CXObjCPropertyAttr_noattr;
5925
5926 unsigned Result = CXObjCPropertyAttr_noattr;
5927 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
5928 ObjCPropertyDecl::PropertyAttributeKind Attr =
5929 PD->getPropertyAttributesAsWritten();
5930
5931#define SET_CXOBJCPROP_ATTR(A) \
5932 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
5933 Result |= CXObjCPropertyAttr_##A
5934 SET_CXOBJCPROP_ATTR(readonly);
5935 SET_CXOBJCPROP_ATTR(getter);
5936 SET_CXOBJCPROP_ATTR(assign);
5937 SET_CXOBJCPROP_ATTR(readwrite);
5938 SET_CXOBJCPROP_ATTR(retain);
5939 SET_CXOBJCPROP_ATTR(copy);
5940 SET_CXOBJCPROP_ATTR(nonatomic);
5941 SET_CXOBJCPROP_ATTR(setter);
5942 SET_CXOBJCPROP_ATTR(atomic);
5943 SET_CXOBJCPROP_ATTR(weak);
5944 SET_CXOBJCPROP_ATTR(strong);
5945 SET_CXOBJCPROP_ATTR(unsafe_unretained);
5946#undef SET_CXOBJCPROP_ATTR
5947
5948 return Result;
5949}
5950
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005951CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5952 if (!clang_isDeclaration(C.kind))
5953 return clang_getNullRange();
5954
5955 const Decl *D = getCursorDecl(C);
5956 ASTContext &Context = getCursorContext(C);
5957 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5958 if (!RC)
5959 return clang_getNullRange();
5960
5961 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5962}
5963
5964CXString clang_Cursor_getRawCommentText(CXCursor C) {
5965 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005966 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005967
5968 const Decl *D = getCursorDecl(C);
5969 ASTContext &Context = getCursorContext(C);
5970 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5971 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5972 StringRef();
5973
5974 // Don't duplicate the string because RawText points directly into source
5975 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005976 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005977}
5978
5979CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5980 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005981 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005982
5983 const Decl *D = getCursorDecl(C);
5984 const ASTContext &Context = getCursorContext(C);
5985 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5986
5987 if (RC) {
5988 StringRef BriefText = RC->getBriefText(Context);
5989
5990 // Don't duplicate the string because RawComment ensures that this memory
5991 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005992 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005993 }
5994
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005995 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005996}
5997
5998CXComment clang_Cursor_getParsedComment(CXCursor C) {
5999 if (!clang_isDeclaration(C.kind))
6000 return cxcomment::createCXComment(NULL, NULL);
6001
6002 const Decl *D = getCursorDecl(C);
6003 const ASTContext &Context = getCursorContext(C);
6004 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6005
6006 return cxcomment::createCXComment(FC, getCursorTU(C));
6007}
6008
6009CXModule clang_Cursor_getModule(CXCursor C) {
6010 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006011 if (const ImportDecl *ImportD =
6012 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006013 return ImportD->getImportedModule();
6014 }
6015
6016 return 0;
6017}
6018
6019CXModule clang_Module_getParent(CXModule CXMod) {
6020 if (!CXMod)
6021 return 0;
6022 Module *Mod = static_cast<Module*>(CXMod);
6023 return Mod->Parent;
6024}
6025
6026CXString clang_Module_getName(CXModule CXMod) {
6027 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006028 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006029 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006030 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006031}
6032
6033CXString clang_Module_getFullName(CXModule CXMod) {
6034 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006035 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006036 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006037 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006038}
6039
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006040unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6041 CXModule CXMod) {
6042 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006043 return 0;
6044 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006045 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6046 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6047 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006048}
6049
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006050CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6051 CXModule CXMod, unsigned Index) {
6052 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006053 return 0;
6054 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006055 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006056
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006057 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6058 if (Index < TopHeaders.size())
6059 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006060
6061 return 0;
6062}
6063
6064} // end: extern "C"
6065
6066//===----------------------------------------------------------------------===//
6067// C++ AST instrospection.
6068//===----------------------------------------------------------------------===//
6069
6070extern "C" {
6071unsigned clang_CXXMethod_isStatic(CXCursor C) {
6072 if (!clang_isDeclaration(C.kind))
6073 return 0;
6074
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006075 const CXXMethodDecl *Method = 0;
6076 const Decl *D = cxcursor::getCursorDecl(C);
6077 if (const FunctionTemplateDecl *FunTmpl =
6078 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006079 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6080 else
6081 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6082 return (Method && Method->isStatic()) ? 1 : 0;
6083}
6084
6085unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6086 if (!clang_isDeclaration(C.kind))
6087 return 0;
6088
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006089 const CXXMethodDecl *Method = 0;
6090 const Decl *D = cxcursor::getCursorDecl(C);
6091 if (const FunctionTemplateDecl *FunTmpl =
6092 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006093 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6094 else
6095 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6096 return (Method && Method->isVirtual()) ? 1 : 0;
6097}
6098} // end: extern "C"
6099
6100//===----------------------------------------------------------------------===//
6101// Attribute introspection.
6102//===----------------------------------------------------------------------===//
6103
6104extern "C" {
6105CXType clang_getIBOutletCollectionType(CXCursor C) {
6106 if (C.kind != CXCursor_IBOutletCollectionAttr)
6107 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6108
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006109 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006110 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6111
6112 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6113}
6114} // end: extern "C"
6115
6116//===----------------------------------------------------------------------===//
6117// Inspecting memory usage.
6118//===----------------------------------------------------------------------===//
6119
6120typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6121
6122static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6123 enum CXTUResourceUsageKind k,
6124 unsigned long amount) {
6125 CXTUResourceUsageEntry entry = { k, amount };
6126 entries.push_back(entry);
6127}
6128
6129extern "C" {
6130
6131const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6132 const char *str = "";
6133 switch (kind) {
6134 case CXTUResourceUsage_AST:
6135 str = "ASTContext: expressions, declarations, and types";
6136 break;
6137 case CXTUResourceUsage_Identifiers:
6138 str = "ASTContext: identifiers";
6139 break;
6140 case CXTUResourceUsage_Selectors:
6141 str = "ASTContext: selectors";
6142 break;
6143 case CXTUResourceUsage_GlobalCompletionResults:
6144 str = "Code completion: cached global results";
6145 break;
6146 case CXTUResourceUsage_SourceManagerContentCache:
6147 str = "SourceManager: content cache allocator";
6148 break;
6149 case CXTUResourceUsage_AST_SideTables:
6150 str = "ASTContext: side tables";
6151 break;
6152 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6153 str = "SourceManager: malloc'ed memory buffers";
6154 break;
6155 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6156 str = "SourceManager: mmap'ed memory buffers";
6157 break;
6158 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6159 str = "ExternalASTSource: malloc'ed memory buffers";
6160 break;
6161 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6162 str = "ExternalASTSource: mmap'ed memory buffers";
6163 break;
6164 case CXTUResourceUsage_Preprocessor:
6165 str = "Preprocessor: malloc'ed memory";
6166 break;
6167 case CXTUResourceUsage_PreprocessingRecord:
6168 str = "Preprocessor: PreprocessingRecord";
6169 break;
6170 case CXTUResourceUsage_SourceManager_DataStructures:
6171 str = "SourceManager: data structures and tables";
6172 break;
6173 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6174 str = "Preprocessor: header search tables";
6175 break;
6176 }
6177 return str;
6178}
6179
6180CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6181 if (!TU) {
6182 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6183 return usage;
6184 }
6185
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006186 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006187 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6188 ASTContext &astContext = astUnit->getASTContext();
6189
6190 // How much memory is used by AST nodes and types?
6191 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6192 (unsigned long) astContext.getASTAllocatedMemory());
6193
6194 // How much memory is used by identifiers?
6195 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6196 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6197
6198 // How much memory is used for selectors?
6199 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6200 (unsigned long) astContext.Selectors.getTotalMemory());
6201
6202 // How much memory is used by ASTContext's side tables?
6203 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6204 (unsigned long) astContext.getSideTableAllocatedMemory());
6205
6206 // How much memory is used for caching global code completion results?
6207 unsigned long completionBytes = 0;
6208 if (GlobalCodeCompletionAllocator *completionAllocator =
6209 astUnit->getCachedCompletionAllocator().getPtr()) {
6210 completionBytes = completionAllocator->getTotalMemory();
6211 }
6212 createCXTUResourceUsageEntry(*entries,
6213 CXTUResourceUsage_GlobalCompletionResults,
6214 completionBytes);
6215
6216 // How much memory is being used by SourceManager's content cache?
6217 createCXTUResourceUsageEntry(*entries,
6218 CXTUResourceUsage_SourceManagerContentCache,
6219 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6220
6221 // How much memory is being used by the MemoryBuffer's in SourceManager?
6222 const SourceManager::MemoryBufferSizes &srcBufs =
6223 astUnit->getSourceManager().getMemoryBufferSizes();
6224
6225 createCXTUResourceUsageEntry(*entries,
6226 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6227 (unsigned long) srcBufs.malloc_bytes);
6228 createCXTUResourceUsageEntry(*entries,
6229 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6230 (unsigned long) srcBufs.mmap_bytes);
6231 createCXTUResourceUsageEntry(*entries,
6232 CXTUResourceUsage_SourceManager_DataStructures,
6233 (unsigned long) astContext.getSourceManager()
6234 .getDataStructureSizes());
6235
6236 // How much memory is being used by the ExternalASTSource?
6237 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6238 const ExternalASTSource::MemoryBufferSizes &sizes =
6239 esrc->getMemoryBufferSizes();
6240
6241 createCXTUResourceUsageEntry(*entries,
6242 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6243 (unsigned long) sizes.malloc_bytes);
6244 createCXTUResourceUsageEntry(*entries,
6245 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6246 (unsigned long) sizes.mmap_bytes);
6247 }
6248
6249 // How much memory is being used by the Preprocessor?
6250 Preprocessor &pp = astUnit->getPreprocessor();
6251 createCXTUResourceUsageEntry(*entries,
6252 CXTUResourceUsage_Preprocessor,
6253 pp.getTotalMemory());
6254
6255 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6256 createCXTUResourceUsageEntry(*entries,
6257 CXTUResourceUsage_PreprocessingRecord,
6258 pRec->getTotalMemory());
6259 }
6260
6261 createCXTUResourceUsageEntry(*entries,
6262 CXTUResourceUsage_Preprocessor_HeaderSearch,
6263 pp.getHeaderSearchInfo().getTotalMemory());
6264
6265 CXTUResourceUsage usage = { (void*) entries.get(),
6266 (unsigned) entries->size(),
6267 entries->size() ? &(*entries)[0] : 0 };
6268 entries.take();
6269 return usage;
6270}
6271
6272void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6273 if (usage.data)
6274 delete (MemUsageEntries*) usage.data;
6275}
6276
6277} // end extern "C"
6278
6279void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6280 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6281 for (unsigned I = 0; I != Usage.numEntries; ++I)
6282 fprintf(stderr, " %s: %lu\n",
6283 clang_getTUResourceUsageName(Usage.entries[I].kind),
6284 Usage.entries[I].amount);
6285
6286 clang_disposeCXTUResourceUsage(Usage);
6287}
6288
6289//===----------------------------------------------------------------------===//
6290// Misc. utility functions.
6291//===----------------------------------------------------------------------===//
6292
6293/// Default to using an 8 MB stack size on "safety" threads.
6294static unsigned SafetyStackThreadSize = 8 << 20;
6295
6296namespace clang {
6297
6298bool RunSafely(llvm::CrashRecoveryContext &CRC,
6299 void (*Fn)(void*), void *UserData,
6300 unsigned Size) {
6301 if (!Size)
6302 Size = GetSafetyThreadStackSize();
6303 if (Size)
6304 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6305 return CRC.RunSafely(Fn, UserData);
6306}
6307
6308unsigned GetSafetyThreadStackSize() {
6309 return SafetyStackThreadSize;
6310}
6311
6312void SetSafetyThreadStackSize(unsigned Value) {
6313 SafetyStackThreadSize = Value;
6314}
6315
6316}
6317
6318void clang::setThreadBackgroundPriority() {
6319 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6320 return;
6321
6322 // FIXME: Move to llvm/Support and make it cross-platform.
6323#ifdef __APPLE__
6324 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6325#endif
6326}
6327
6328void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6329 if (!Unit)
6330 return;
6331
6332 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6333 DEnd = Unit->stored_diag_end();
6334 D != DEnd; ++D) {
6335 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6336 CXString Msg = clang_formatDiagnostic(&Diag,
6337 clang_defaultDiagnosticDisplayOptions());
6338 fprintf(stderr, "%s\n", clang_getCString(Msg));
6339 clang_disposeString(Msg);
6340 }
6341#ifdef LLVM_ON_WIN32
6342 // On Windows, force a flush, since there may be multiple copies of
6343 // stderr and stdout in the file system, all with different buffers
6344 // but writing to the same device.
6345 fflush(stderr);
6346#endif
6347}
6348
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006349MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6350 SourceLocation MacroDefLoc,
6351 CXTranslationUnit TU){
6352 if (MacroDefLoc.isInvalid() || !TU)
6353 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006354 if (!II.hadMacroDefinition())
6355 return 0;
6356
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006357 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006358 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006359 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006360 if (MD) {
6361 for (MacroDirective::DefInfo
6362 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6363 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6364 return Def.getMacroInfo();
6365 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006366 }
6367
6368 return 0;
6369}
6370
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006371const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6372 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006373 if (!MacroDef || !TU)
6374 return 0;
6375 const IdentifierInfo *II = MacroDef->getName();
6376 if (!II)
6377 return 0;
6378
6379 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6380}
6381
6382MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6383 const Token &Tok,
6384 CXTranslationUnit TU) {
6385 if (!MI || !TU)
6386 return 0;
6387 if (Tok.isNot(tok::raw_identifier))
6388 return 0;
6389
6390 if (MI->getNumTokens() == 0)
6391 return 0;
6392 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6393 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006394 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006395
6396 // Check that the token is inside the definition and not its argument list.
6397 SourceManager &SM = Unit->getSourceManager();
6398 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6399 return 0;
6400 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6401 return 0;
6402
6403 Preprocessor &PP = Unit->getPreprocessor();
6404 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6405 if (!PPRec)
6406 return 0;
6407
6408 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6409 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6410 if (!II.hadMacroDefinition())
6411 return 0;
6412
6413 // Check that the identifier is not one of the macro arguments.
6414 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6415 return 0;
6416
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006417 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6418 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006419 return 0;
6420
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006421 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006422}
6423
6424MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6425 SourceLocation Loc,
6426 CXTranslationUnit TU) {
6427 if (Loc.isInvalid() || !MI || !TU)
6428 return 0;
6429
6430 if (MI->getNumTokens() == 0)
6431 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006432 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006433 Preprocessor &PP = Unit->getPreprocessor();
6434 if (!PP.getPreprocessingRecord())
6435 return 0;
6436 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6437 Token Tok;
6438 if (PP.getRawToken(Loc, Tok))
6439 return 0;
6440
6441 return checkForMacroInMacroDefinition(MI, Tok, TU);
6442}
6443
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006444extern "C" {
6445
6446CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006447 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006448}
6449
6450} // end: extern "C"
6451
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006452Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6453 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006454 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006455 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006456 if (Unit->isMainFileAST())
6457 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006458 return *this;
6459 }
6460 }
6461
6462 LogOS << "<NULL TU>";
6463 return *this;
6464}
6465
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006466Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6467 *this << FE->getName();
6468 return *this;
6469}
6470
6471Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6472 CXString cursorName = clang_getCursorDisplayName(cursor);
6473 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6474 clang_disposeString(cursorName);
6475 return *this;
6476}
6477
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006478Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6479 CXFile File;
6480 unsigned Line, Column;
6481 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6482 CXString FileName = clang_getFileName(File);
6483 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6484 clang_disposeString(FileName);
6485 return *this;
6486}
6487
6488Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6489 CXSourceLocation BLoc = clang_getRangeStart(range);
6490 CXSourceLocation ELoc = clang_getRangeEnd(range);
6491
6492 CXFile BFile;
6493 unsigned BLine, BColumn;
6494 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6495
6496 CXFile EFile;
6497 unsigned ELine, EColumn;
6498 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6499
6500 CXString BFileName = clang_getFileName(BFile);
6501 if (BFile == EFile) {
6502 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6503 BLine, BColumn, ELine, EColumn);
6504 } else {
6505 CXString EFileName = clang_getFileName(EFile);
6506 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6507 BLine, BColumn)
6508 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6509 ELine, EColumn);
6510 clang_disposeString(EFileName);
6511 }
6512 clang_disposeString(BFileName);
6513 return *this;
6514}
6515
6516Logger &cxindex::Logger::operator<<(CXString Str) {
6517 *this << clang_getCString(Str);
6518 return *this;
6519}
6520
6521Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6522 LogOS << Fmt;
6523 return *this;
6524}
6525
6526cxindex::Logger::~Logger() {
6527 LogOS.flush();
6528
6529 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6530
6531 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6532
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006533 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006534 OS << "[libclang:" << Name << ':';
6535
6536 // FIXME: Portability.
6537#if HAVE_PTHREAD_H && __APPLE__
6538 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6539 OS << tid << ':';
6540#endif
6541
6542 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6543 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6544 OS << Msg.str() << '\n';
6545
6546 if (Trace) {
6547 llvm::sys::PrintStackTrace(stderr);
6548 OS << "--------------------------------------------------\n";
6549 }
6550}