blob: 71827f8a23c3fd0af5d8b0186bc42d296a4d42b2 [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;
Argyrios Kyrtzidis333e44c2013-05-07 20:37:17 +0000429 if (!PPE)
430 continue;
431
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000432 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
433 if (Visit(MakeMacroExpansionCursor(ME, TU)))
434 return true;
435
436 continue;
437 }
438
439 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
440 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
441 return true;
442
443 continue;
444 }
445
446 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
447 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
448 return true;
449
450 continue;
451 }
452 }
453
454 return false;
455}
456
457/// \brief Visit the children of the given cursor.
458///
459/// \returns true if the visitation should be aborted, false if it
460/// should continue.
461bool CursorVisitor::VisitChildren(CXCursor Cursor) {
462 if (clang_isReference(Cursor.kind) &&
463 Cursor.kind != CXCursor_CXXBaseSpecifier) {
464 // By definition, references have no children.
465 return false;
466 }
467
468 // Set the Parent field to Cursor, then back to its old value once we're
469 // done.
470 SetParentRAII SetParent(Parent, StmtParent, Cursor);
471
472 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000473 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000474 if (!D)
475 return false;
476
477 return VisitAttributes(D) || Visit(D);
478 }
479
480 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000481 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000482 return Visit(S);
483
484 return false;
485 }
486
487 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000488 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000489 return Visit(E);
490
491 return false;
492 }
493
494 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000495 CXTranslationUnit TU = getCursorTU(Cursor);
496 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000497
498 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
499 for (unsigned I = 0; I != 2; ++I) {
500 if (VisitOrder[I]) {
501 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
502 RegionOfInterest.isInvalid()) {
503 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
504 TLEnd = CXXUnit->top_level_end();
505 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000506 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000507 return true;
508 }
509 } else if (VisitDeclContext(
510 CXXUnit->getASTContext().getTranslationUnitDecl()))
511 return true;
512 continue;
513 }
514
515 // Walk the preprocessing record.
516 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
517 visitPreprocessedEntitiesInRegion();
518 }
519
520 return false;
521 }
522
523 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000524 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000525 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
526 return Visit(BaseTSInfo->getTypeLoc());
527 }
528 }
529 }
530
531 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000532 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000533 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
534 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
535 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
536 A->getInterfaceLoc(), TU));
537 }
538
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000539 // If pointing inside a macro definition, check if the token is an identifier
540 // that was ever defined as a macro. In such a case, create a "pseudo" macro
541 // expansion cursor for that token.
542 SourceLocation BeginLoc = RegionOfInterest.getBegin();
543 if (Cursor.kind == CXCursor_MacroDefinition &&
544 BeginLoc == RegionOfInterest.getEnd()) {
545 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000546 const MacroInfo *MI =
547 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000548 if (MacroDefinition *MacroDef =
549 checkForMacroInMacroDefinition(MI, Loc, TU))
550 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
551 }
552
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000553 // Nothing to visit at the moment.
554 return false;
555}
556
557bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
558 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
559 if (Visit(TSInfo->getTypeLoc()))
560 return true;
561
562 if (Stmt *Body = B->getBody())
563 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
564
565 return false;
566}
567
Ted Kremenek943f9092013-02-21 01:29:01 +0000568Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000569 if (RegionOfInterest.isValid()) {
570 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
571 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000572 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000573
574 switch (CompareRegionOfInterest(Range)) {
575 case RangeBefore:
576 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000577 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000578
579 case RangeAfter:
580 // This declaration comes after the region of interest; we're done.
581 return false;
582
583 case RangeOverlap:
584 // This declaration overlaps the region of interest; visit it.
585 break;
586 }
587 }
588 return true;
589}
590
591bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
592 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
593
594 // FIXME: Eventually remove. This part of a hack to support proper
595 // iteration over all Decls contained lexically within an ObjC container.
596 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
597 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
598
599 for ( ; I != E; ++I) {
600 Decl *D = *I;
601 if (D->getLexicalDeclContext() != DC)
602 continue;
603 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
604
605 // Ignore synthesized ivars here, otherwise if we have something like:
606 // @synthesize prop = _prop;
607 // and '_prop' is not declared, we will encounter a '_prop' ivar before
608 // encountering the 'prop' synthesize declaration and we will think that
609 // we passed the region-of-interest.
610 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
611 if (ivarD->getSynthesize())
612 continue;
613 }
614
615 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
616 // declarations is a mismatch with the compiler semantics.
617 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
618 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
619 if (!ID->isThisDeclarationADefinition())
620 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
621
622 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
623 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
624 if (!PD->isThisDeclarationADefinition())
625 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
626 }
627
Ted Kremenek943f9092013-02-21 01:29:01 +0000628 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000629 if (!V.hasValue())
630 continue;
631 if (!V.getValue())
632 return false;
633 if (Visit(Cursor, true))
634 return true;
635 }
636 return false;
637}
638
639bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
640 llvm_unreachable("Translation units are visited directly by Visit()");
641}
642
643bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
644 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
645 return Visit(TSInfo->getTypeLoc());
646
647 return false;
648}
649
650bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
651 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
652 return Visit(TSInfo->getTypeLoc());
653
654 return false;
655}
656
657bool CursorVisitor::VisitTagDecl(TagDecl *D) {
658 return VisitDeclContext(D);
659}
660
661bool CursorVisitor::VisitClassTemplateSpecializationDecl(
662 ClassTemplateSpecializationDecl *D) {
663 bool ShouldVisitBody = false;
664 switch (D->getSpecializationKind()) {
665 case TSK_Undeclared:
666 case TSK_ImplicitInstantiation:
667 // Nothing to visit
668 return false;
669
670 case TSK_ExplicitInstantiationDeclaration:
671 case TSK_ExplicitInstantiationDefinition:
672 break;
673
674 case TSK_ExplicitSpecialization:
675 ShouldVisitBody = true;
676 break;
677 }
678
679 // Visit the template arguments used in the specialization.
680 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
681 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000682 if (TemplateSpecializationTypeLoc TSTLoc =
683 TL.getAs<TemplateSpecializationTypeLoc>()) {
684 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
685 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000686 return true;
687 }
688 }
689
690 if (ShouldVisitBody && VisitCXXRecordDecl(D))
691 return true;
692
693 return false;
694}
695
696bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
697 ClassTemplatePartialSpecializationDecl *D) {
698 // FIXME: Visit the "outer" template parameter lists on the TagDecl
699 // before visiting these template parameters.
700 if (VisitTemplateParameters(D->getTemplateParameters()))
701 return true;
702
703 // Visit the partial specialization arguments.
704 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
705 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
706 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
707 return true;
708
709 return VisitCXXRecordDecl(D);
710}
711
712bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
713 // Visit the default argument.
714 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
715 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
716 if (Visit(DefArg->getTypeLoc()))
717 return true;
718
719 return false;
720}
721
722bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
723 if (Expr *Init = D->getInitExpr())
724 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
725 return false;
726}
727
728bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000729 unsigned NumParamList = DD->getNumTemplateParameterLists();
730 for (unsigned i = 0; i < NumParamList; i++) {
731 TemplateParameterList* Params = DD->getTemplateParameterList(i);
732 if (VisitTemplateParameters(Params))
733 return true;
734 }
735
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000736 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
737 if (Visit(TSInfo->getTypeLoc()))
738 return true;
739
740 // Visit the nested-name-specifier, if present.
741 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
742 if (VisitNestedNameSpecifierLoc(QualifierLoc))
743 return true;
744
745 return false;
746}
747
748/// \brief Compare two base or member initializers based on their source order.
749static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
750 CXXCtorInitializer const * const *X
751 = static_cast<CXXCtorInitializer const * const *>(Xp);
752 CXXCtorInitializer const * const *Y
753 = static_cast<CXXCtorInitializer const * const *>(Yp);
754
755 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
756 return -1;
757 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
758 return 1;
759 else
760 return 0;
761}
762
763bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000764 unsigned NumParamList = ND->getNumTemplateParameterLists();
765 for (unsigned i = 0; i < NumParamList; i++) {
766 TemplateParameterList* Params = ND->getTemplateParameterList(i);
767 if (VisitTemplateParameters(Params))
768 return true;
769 }
770
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000771 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
772 // Visit the function declaration's syntactic components in the order
773 // written. This requires a bit of work.
774 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000775 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000776
777 // If we have a function declared directly (without the use of a typedef),
778 // visit just the return type. Otherwise, just visit the function's type
779 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000780 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000781 (!FTL && Visit(TL)))
782 return true;
783
784 // Visit the nested-name-specifier, if present.
785 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
786 if (VisitNestedNameSpecifierLoc(QualifierLoc))
787 return true;
788
789 // Visit the declaration name.
790 if (VisitDeclarationNameInfo(ND->getNameInfo()))
791 return true;
792
793 // FIXME: Visit explicitly-specified template arguments!
794
795 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000796 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000797 return true;
798
Bill Wendlingad017fa2012-12-20 19:22:21 +0000799 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000800 }
801
802 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
803 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
804 // Find the initializers that were written in the source.
805 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
806 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
807 IEnd = Constructor->init_end();
808 I != IEnd; ++I) {
809 if (!(*I)->isWritten())
810 continue;
811
812 WrittenInits.push_back(*I);
813 }
814
815 // Sort the initializers in source order
816 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
817 &CompareCXXCtorInitializers);
818
819 // Visit the initializers in source order
820 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
821 CXXCtorInitializer *Init = WrittenInits[I];
822 if (Init->isAnyMemberInitializer()) {
823 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
824 Init->getMemberLocation(), TU)))
825 return true;
826 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
827 if (Visit(TInfo->getTypeLoc()))
828 return true;
829 }
830
831 // Visit the initializer value.
832 if (Expr *Initializer = Init->getInit())
833 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
834 return true;
835 }
836 }
837
838 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
839 return true;
840 }
841
842 return false;
843}
844
845bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
846 if (VisitDeclaratorDecl(D))
847 return true;
848
849 if (Expr *BitWidth = D->getBitWidth())
850 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
851
852 return false;
853}
854
855bool CursorVisitor::VisitVarDecl(VarDecl *D) {
856 if (VisitDeclaratorDecl(D))
857 return true;
858
859 if (Expr *Init = D->getInit())
860 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
861
862 return false;
863}
864
865bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
866 if (VisitDeclaratorDecl(D))
867 return true;
868
869 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
870 if (Expr *DefArg = D->getDefaultArgument())
871 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
877 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
878 // before visiting these template parameters.
879 if (VisitTemplateParameters(D->getTemplateParameters()))
880 return true;
881
882 return VisitFunctionDecl(D->getTemplatedDecl());
883}
884
885bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the TagDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitCXXRecordDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
899 VisitTemplateArgumentLoc(D->getDefaultArgument()))
900 return true;
901
902 return false;
903}
904
905bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
906 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
907 if (Visit(TSInfo->getTypeLoc()))
908 return true;
909
910 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
911 PEnd = ND->param_end();
912 P != PEnd; ++P) {
913 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
914 return true;
915 }
916
917 if (ND->isThisDeclarationADefinition() &&
918 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
919 return true;
920
921 return false;
922}
923
924template <typename DeclIt>
925static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
926 SourceManager &SM, SourceLocation EndLoc,
927 SmallVectorImpl<Decl *> &Decls) {
928 DeclIt next = *DI_current;
929 while (++next != DE_current) {
930 Decl *D_next = *next;
931 if (!D_next)
932 break;
933 SourceLocation L = D_next->getLocStart();
934 if (!L.isValid())
935 break;
936 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
937 *DI_current = next;
938 Decls.push_back(D_next);
939 continue;
940 }
941 break;
942 }
943}
944
945namespace {
946 struct ContainerDeclsSort {
947 SourceManager &SM;
948 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
949 bool operator()(Decl *A, Decl *B) {
950 SourceLocation L_A = A->getLocStart();
951 SourceLocation L_B = B->getLocStart();
952 assert(L_A.isValid() && L_B.isValid());
953 return SM.isBeforeInTranslationUnit(L_A, L_B);
954 }
955 };
956}
957
958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
989 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
990 I!=E; ++I) {
991 Decl *subDecl = *I;
992 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
993 subDecl->getLocStart().isInvalid())
994 continue;
995 DeclsInContainer.push_back(subDecl);
996 }
997
998 // Now sort the Decls so that they appear in lexical order.
999 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1000 ContainerDeclsSort(SM));
1001
1002 // Now visit the decls.
1003 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1004 E = DeclsInContainer.end(); I != E; ++I) {
1005 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +00001006 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001007 if (!V.hasValue())
1008 continue;
1009 if (!V.getValue())
1010 return false;
1011 if (Visit(Cursor, true))
1012 return true;
1013 }
1014 return false;
1015}
1016
1017bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1018 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1019 TU)))
1020 return true;
1021
1022 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1023 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1024 E = ND->protocol_end(); I != E; ++I, ++PL)
1025 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1026 return true;
1027
1028 return VisitObjCContainerDecl(ND);
1029}
1030
1031bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1032 if (!PID->isThisDeclarationADefinition())
1033 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1034
1035 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1036 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1037 E = PID->protocol_end(); I != E; ++I, ++PL)
1038 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1039 return true;
1040
1041 return VisitObjCContainerDecl(PID);
1042}
1043
1044bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1045 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1046 return true;
1047
1048 // FIXME: This implements a workaround with @property declarations also being
1049 // installed in the DeclContext for the @interface. Eventually this code
1050 // should be removed.
1051 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1052 if (!CDecl || !CDecl->IsClassExtension())
1053 return false;
1054
1055 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1056 if (!ID)
1057 return false;
1058
1059 IdentifierInfo *PropertyId = PD->getIdentifier();
1060 ObjCPropertyDecl *prevDecl =
1061 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1062
1063 if (!prevDecl)
1064 return false;
1065
1066 // Visit synthesized methods since they will be skipped when visiting
1067 // the @interface.
1068 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1074 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1075 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1076 return true;
1077
1078 return false;
1079}
1080
1081bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1082 if (!D->isThisDeclarationADefinition()) {
1083 // Forward declaration is treated like a reference.
1084 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1085 }
1086
1087 // Issue callbacks for super class.
1088 if (D->getSuperClass() &&
1089 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1090 D->getSuperClassLoc(),
1091 TU)))
1092 return true;
1093
1094 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1095 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1096 E = D->protocol_end(); I != E; ++I, ++PL)
1097 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1098 return true;
1099
1100 return VisitObjCContainerDecl(D);
1101}
1102
1103bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1104 return VisitObjCContainerDecl(D);
1105}
1106
1107bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1108 // 'ID' could be null when dealing with invalid code.
1109 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1110 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1111 return true;
1112
1113 return VisitObjCImplDecl(D);
1114}
1115
1116bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1117#if 0
1118 // Issue callbacks for super class.
1119 // FIXME: No source location information!
1120 if (D->getSuperClass() &&
1121 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1122 D->getSuperClassLoc(),
1123 TU)))
1124 return true;
1125#endif
1126
1127 return VisitObjCImplDecl(D);
1128}
1129
1130bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1131 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1132 if (PD->isIvarNameSpecified())
1133 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1134
1135 return false;
1136}
1137
1138bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1139 return VisitDeclContext(D);
1140}
1141
1142bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1143 // Visit nested-name-specifier.
1144 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1145 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1146 return true;
1147
1148 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1149 D->getTargetNameLoc(), TU));
1150}
1151
1152bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1153 // Visit nested-name-specifier.
1154 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1155 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1156 return true;
1157 }
1158
1159 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1160 return true;
1161
1162 return VisitDeclarationNameInfo(D->getNameInfo());
1163}
1164
1165bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1166 // Visit nested-name-specifier.
1167 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1168 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1169 return true;
1170
1171 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1172 D->getIdentLocation(), TU));
1173}
1174
1175bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1176 // Visit nested-name-specifier.
1177 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1178 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1179 return true;
1180 }
1181
1182 return VisitDeclarationNameInfo(D->getNameInfo());
1183}
1184
1185bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1186 UnresolvedUsingTypenameDecl *D) {
1187 // Visit nested-name-specifier.
1188 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1189 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1190 return true;
1191
1192 return false;
1193}
1194
1195bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1196 switch (Name.getName().getNameKind()) {
1197 case clang::DeclarationName::Identifier:
1198 case clang::DeclarationName::CXXLiteralOperatorName:
1199 case clang::DeclarationName::CXXOperatorName:
1200 case clang::DeclarationName::CXXUsingDirective:
1201 return false;
1202
1203 case clang::DeclarationName::CXXConstructorName:
1204 case clang::DeclarationName::CXXDestructorName:
1205 case clang::DeclarationName::CXXConversionFunctionName:
1206 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1207 return Visit(TSInfo->getTypeLoc());
1208 return false;
1209
1210 case clang::DeclarationName::ObjCZeroArgSelector:
1211 case clang::DeclarationName::ObjCOneArgSelector:
1212 case clang::DeclarationName::ObjCMultiArgSelector:
1213 // FIXME: Per-identifier location info?
1214 return false;
1215 }
1216
1217 llvm_unreachable("Invalid DeclarationName::Kind!");
1218}
1219
1220bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1221 SourceRange Range) {
1222 // FIXME: This whole routine is a hack to work around the lack of proper
1223 // source information in nested-name-specifiers (PR5791). Since we do have
1224 // a beginning source location, we can visit the first component of the
1225 // nested-name-specifier, if it's a single-token component.
1226 if (!NNS)
1227 return false;
1228
1229 // Get the first component in the nested-name-specifier.
1230 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1231 NNS = Prefix;
1232
1233 switch (NNS->getKind()) {
1234 case NestedNameSpecifier::Namespace:
1235 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1236 TU));
1237
1238 case NestedNameSpecifier::NamespaceAlias:
1239 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1240 Range.getBegin(), TU));
1241
1242 case NestedNameSpecifier::TypeSpec: {
1243 // If the type has a form where we know that the beginning of the source
1244 // range matches up with a reference cursor. Visit the appropriate reference
1245 // cursor.
1246 const Type *T = NNS->getAsType();
1247 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1248 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1249 if (const TagType *Tag = dyn_cast<TagType>(T))
1250 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1251 if (const TemplateSpecializationType *TST
1252 = dyn_cast<TemplateSpecializationType>(T))
1253 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1254 break;
1255 }
1256
1257 case NestedNameSpecifier::TypeSpecWithTemplate:
1258 case NestedNameSpecifier::Global:
1259 case NestedNameSpecifier::Identifier:
1260 break;
1261 }
1262
1263 return false;
1264}
1265
1266bool
1267CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1268 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1269 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1270 Qualifiers.push_back(Qualifier);
1271
1272 while (!Qualifiers.empty()) {
1273 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1274 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1275 switch (NNS->getKind()) {
1276 case NestedNameSpecifier::Namespace:
1277 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1278 Q.getLocalBeginLoc(),
1279 TU)))
1280 return true;
1281
1282 break;
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Q.getLocalBeginLoc(),
1287 TU)))
1288 return true;
1289
1290 break;
1291
1292 case NestedNameSpecifier::TypeSpec:
1293 case NestedNameSpecifier::TypeSpecWithTemplate:
1294 if (Visit(Q.getTypeLoc()))
1295 return true;
1296
1297 break;
1298
1299 case NestedNameSpecifier::Global:
1300 case NestedNameSpecifier::Identifier:
1301 break;
1302 }
1303 }
1304
1305 return false;
1306}
1307
1308bool CursorVisitor::VisitTemplateParameters(
1309 const TemplateParameterList *Params) {
1310 if (!Params)
1311 return false;
1312
1313 for (TemplateParameterList::const_iterator P = Params->begin(),
1314 PEnd = Params->end();
1315 P != PEnd; ++P) {
1316 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1317 return true;
1318 }
1319
1320 return false;
1321}
1322
1323bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1324 switch (Name.getKind()) {
1325 case TemplateName::Template:
1326 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1327
1328 case TemplateName::OverloadedTemplate:
1329 // Visit the overloaded template set.
1330 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1331 return true;
1332
1333 return false;
1334
1335 case TemplateName::DependentTemplate:
1336 // FIXME: Visit nested-name-specifier.
1337 return false;
1338
1339 case TemplateName::QualifiedTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsQualifiedTemplateName()->getDecl(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParm:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1348 Loc, TU));
1349
1350 case TemplateName::SubstTemplateTemplateParmPack:
1351 return Visit(MakeCursorTemplateRef(
1352 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1353 Loc, TU));
1354 }
1355
1356 llvm_unreachable("Invalid TemplateName::Kind!");
1357}
1358
1359bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1360 switch (TAL.getArgument().getKind()) {
1361 case TemplateArgument::Null:
1362 case TemplateArgument::Integral:
1363 case TemplateArgument::Pack:
1364 return false;
1365
1366 case TemplateArgument::Type:
1367 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1368 return Visit(TSInfo->getTypeLoc());
1369 return false;
1370
1371 case TemplateArgument::Declaration:
1372 if (Expr *E = TAL.getSourceDeclExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::NullPtr:
1377 if (Expr *E = TAL.getSourceNullPtrExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Expression:
1382 if (Expr *E = TAL.getSourceExpression())
1383 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384 return false;
1385
1386 case TemplateArgument::Template:
1387 case TemplateArgument::TemplateExpansion:
1388 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1389 return true;
1390
1391 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1392 TAL.getTemplateNameLoc());
1393 }
1394
1395 llvm_unreachable("Invalid TemplateArgument::Kind!");
1396}
1397
1398bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1399 return VisitDeclContext(D);
1400}
1401
1402bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1403 return Visit(TL.getUnqualifiedLoc());
1404}
1405
1406bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1407 ASTContext &Context = AU->getASTContext();
1408
1409 // Some builtin types (such as Objective-C's "id", "sel", and
1410 // "Class") have associated declarations. Create cursors for those.
1411 QualType VisitType;
1412 switch (TL.getTypePtr()->getKind()) {
1413
1414 case BuiltinType::Void:
1415 case BuiltinType::NullPtr:
1416 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001417 case BuiltinType::OCLImage1d:
1418 case BuiltinType::OCLImage1dArray:
1419 case BuiltinType::OCLImage1dBuffer:
1420 case BuiltinType::OCLImage2d:
1421 case BuiltinType::OCLImage2dArray:
1422 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001423 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001424 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001425#define BUILTIN_TYPE(Id, SingletonId)
1426#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#include "clang/AST/BuiltinTypes.def"
1431 break;
1432
1433 case BuiltinType::ObjCId:
1434 VisitType = Context.getObjCIdType();
1435 break;
1436
1437 case BuiltinType::ObjCClass:
1438 VisitType = Context.getObjCClassType();
1439 break;
1440
1441 case BuiltinType::ObjCSel:
1442 VisitType = Context.getObjCSelType();
1443 break;
1444 }
1445
1446 if (!VisitType.isNull()) {
1447 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1448 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1449 TU));
1450 }
1451
1452 return false;
1453}
1454
1455bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1456 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1457}
1458
1459bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1464 if (TL.isDefinition())
1465 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1466
1467 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1468}
1469
1470bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1475 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1476 return true;
1477
1478 return false;
1479}
1480
1481bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1482 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1483 return true;
1484
1485 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1486 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1487 TU)))
1488 return true;
1489 }
1490
1491 return false;
1492}
1493
1494bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1495 return Visit(TL.getPointeeLoc());
1496}
1497
1498bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1499 return Visit(TL.getInnerLoc());
1500}
1501
1502bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1503 return Visit(TL.getPointeeLoc());
1504}
1505
1506bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1523 return Visit(TL.getModifiedLoc());
1524}
1525
1526bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1527 bool SkipResultType) {
1528 if (!SkipResultType && Visit(TL.getResultLoc()))
1529 return true;
1530
1531 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1532 if (Decl *D = TL.getArg(I))
1533 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1534 return true;
1535
1536 return false;
1537}
1538
1539bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1540 if (Visit(TL.getElementLoc()))
1541 return true;
1542
1543 if (Expr *Size = TL.getSizeExpr())
1544 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1545
1546 return false;
1547}
1548
1549bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1550 TemplateSpecializationTypeLoc TL) {
1551 // Visit the template name.
1552 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1553 TL.getTemplateNameLoc()))
1554 return true;
1555
1556 // Visit the template arguments.
1557 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1558 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1559 return true;
1560
1561 return false;
1562}
1563
1564bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1565 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1566}
1567
1568bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1569 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1570 return Visit(TSInfo->getTypeLoc());
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1583 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1584 return true;
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1590 DependentTemplateSpecializationTypeLoc TL) {
1591 // Visit the nested-name-specifier, if there is one.
1592 if (TL.getQualifierLoc() &&
1593 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1594 return true;
1595
1596 // Visit the template arguments.
1597 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1598 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1599 return true;
1600
1601 return false;
1602}
1603
1604bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1605 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 return Visit(TL.getNamedTypeLoc());
1609}
1610
1611bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1612 return Visit(TL.getPatternLoc());
1613}
1614
1615bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1616 if (Expr *E = TL.getUnderlyingExpr())
1617 return Visit(MakeCXCursor(E, StmtParent, TU));
1618
1619 return false;
1620}
1621
1622bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1623 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1624}
1625
1626bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1627 return Visit(TL.getValueLoc());
1628}
1629
1630#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1631bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1632 return Visit##PARENT##Loc(TL); \
1633}
1634
1635DEFAULT_TYPELOC_IMPL(Complex, Type)
1636DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1638DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1641DEFAULT_TYPELOC_IMPL(Vector, Type)
1642DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1643DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1644DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1645DEFAULT_TYPELOC_IMPL(Record, TagType)
1646DEFAULT_TYPELOC_IMPL(Enum, TagType)
1647DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1648DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1649DEFAULT_TYPELOC_IMPL(Auto, Type)
1650
1651bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1652 // Visit the nested-name-specifier, if present.
1653 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1654 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1655 return true;
1656
1657 if (D->isCompleteDefinition()) {
1658 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1659 E = D->bases_end(); I != E; ++I) {
1660 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1661 return true;
1662 }
1663 }
1664
1665 return VisitTagDecl(D);
1666}
1667
1668bool CursorVisitor::VisitAttributes(Decl *D) {
1669 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1670 i != e; ++i)
1671 if (Visit(MakeCXCursor(*i, D, TU)))
1672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001706 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001801 VisitorWorkList &WL;
1802 CXCursor Parent;
1803public:
1804 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1805 : WL(wl), Parent(parent) {}
1806
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001807 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1808 void VisitBlockExpr(const BlockExpr *B);
1809 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1810 void VisitCompoundStmt(const CompoundStmt *S);
1811 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1812 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1813 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1814 void VisitCXXNewExpr(const CXXNewExpr *E);
1815 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1816 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1817 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1818 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1819 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1820 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1821 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1822 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1823 void VisitDeclRefExpr(const DeclRefExpr *D);
1824 void VisitDeclStmt(const DeclStmt *S);
1825 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1826 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1827 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1828 void VisitForStmt(const ForStmt *FS);
1829 void VisitGotoStmt(const GotoStmt *GS);
1830 void VisitIfStmt(const IfStmt *If);
1831 void VisitInitListExpr(const InitListExpr *IE);
1832 void VisitMemberExpr(const MemberExpr *M);
1833 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1834 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1835 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1836 void VisitOverloadExpr(const OverloadExpr *E);
1837 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1838 void VisitStmt(const Stmt *S);
1839 void VisitSwitchStmt(const SwitchStmt *S);
1840 void VisitWhileStmt(const WhileStmt *W);
1841 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1842 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
1852
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001853private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001854 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001855 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1856 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001857 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1858 void AddStmt(const Stmt *S);
1859 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001860 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001861 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001862};
1863} // end anonyous namespace
1864
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001865void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001866 // 'S' should always be non-null, since it comes from the
1867 // statement we are visiting.
1868 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1869}
1870
1871void
1872EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1873 if (Qualifier)
1874 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1875}
1876
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001877void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001878 if (S)
1879 WL.push_back(StmtVisit(S, Parent));
1880}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001881void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001882 if (D)
1883 WL.push_back(DeclVisit(D, Parent, isFirst));
1884}
1885void EnqueueVisitor::
1886 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1887 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001888 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001889}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001890void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001891 if (D)
1892 WL.push_back(MemberRefVisit(D, L, Parent));
1893}
1894void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1895 if (TI)
1896 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1897 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001898void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001899 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001900 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001901 AddStmt(*Child);
1902 }
1903 if (size == WL.size())
1904 return;
1905 // Now reverse the entries we just added. This will match the DFS
1906 // ordering performed by the worklist.
1907 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1908 std::reverse(I, E);
1909}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001910void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001911 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1912}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001913void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001914 AddDecl(B->getBlockDecl());
1915}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001916void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001917 EnqueueChildren(E);
1918 AddTypeLoc(E->getTypeSourceInfo());
1919}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001920void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1921 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001922 E = S->body_rend(); I != E; ++I) {
1923 AddStmt(*I);
1924 }
1925}
1926void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001927VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001928 AddStmt(S->getSubStmt());
1929 AddDeclarationNameInfo(S);
1930 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1931 AddNestedNameSpecifierLoc(QualifierLoc);
1932}
1933
1934void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001935VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001936 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1937 AddDeclarationNameInfo(E);
1938 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1939 AddNestedNameSpecifierLoc(QualifierLoc);
1940 if (!E->isImplicitAccess())
1941 AddStmt(E->getBase());
1942}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001943void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001944 // Enqueue the initializer , if any.
1945 AddStmt(E->getInitializer());
1946 // Enqueue the array size, if any.
1947 AddStmt(E->getArraySize());
1948 // Enqueue the allocated type.
1949 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1950 // Enqueue the placement arguments.
1951 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1952 AddStmt(E->getPlacementArg(I-1));
1953}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001954void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001955 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1956 AddStmt(CE->getArg(I-1));
1957 AddStmt(CE->getCallee());
1958 AddStmt(CE->getArg(0));
1959}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1961 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001962 // Visit the name of the type being destroyed.
1963 AddTypeLoc(E->getDestroyedTypeInfo());
1964 // Visit the scope type that looks disturbingly like the nested-name-specifier
1965 // but isn't.
1966 AddTypeLoc(E->getScopeTypeInfo());
1967 // Visit the nested-name-specifier.
1968 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1969 AddNestedNameSpecifierLoc(QualifierLoc);
1970 // Visit base expression.
1971 AddStmt(E->getBase());
1972}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001973void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1974 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001975 AddTypeLoc(E->getTypeSourceInfo());
1976}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1978 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001979 EnqueueChildren(E);
1980 AddTypeLoc(E->getTypeSourceInfo());
1981}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 EnqueueChildren(E);
1984 if (E->isTypeOperand())
1985 AddTypeLoc(E->getTypeOperandSourceInfo());
1986}
1987
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001988void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1989 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001990 EnqueueChildren(E);
1991 AddTypeLoc(E->getTypeSourceInfo());
1992}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001994 EnqueueChildren(E);
1995 if (E->isTypeOperand())
1996 AddTypeLoc(E->getTypeOperandSourceInfo());
1997}
1998
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002000 EnqueueChildren(S);
2001 AddDecl(S->getExceptionDecl());
2002}
2003
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002005 if (DR->hasExplicitTemplateArgs()) {
2006 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2007 }
2008 WL.push_back(DeclRefExprParts(DR, Parent));
2009}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2011 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002012 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2013 AddDeclarationNameInfo(E);
2014 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2015}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002017 unsigned size = WL.size();
2018 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002019 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002020 D != DEnd; ++D) {
2021 AddDecl(*D, isFirst);
2022 isFirst = false;
2023 }
2024 if (size == WL.size())
2025 return;
2026 // Now reverse the entries we just added. This will match the DFS
2027 // ordering performed by the worklist.
2028 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2029 std::reverse(I, E);
2030}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002031void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002032 AddStmt(E->getInit());
2033 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002034 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002035 D = E->designators_rbegin(), DEnd = E->designators_rend();
2036 D != DEnd; ++D) {
2037 if (D->isFieldDesignator()) {
2038 if (FieldDecl *Field = D->getField())
2039 AddMemberRef(Field, D->getFieldLoc());
2040 continue;
2041 }
2042 if (D->isArrayDesignator()) {
2043 AddStmt(E->getArrayIndex(*D));
2044 continue;
2045 }
2046 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2047 AddStmt(E->getArrayRangeEnd(*D));
2048 AddStmt(E->getArrayRangeStart(*D));
2049 }
2050}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 AddTypeLoc(E->getTypeInfoAsWritten());
2054}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002056 AddStmt(FS->getBody());
2057 AddStmt(FS->getInc());
2058 AddStmt(FS->getCond());
2059 AddDecl(FS->getConditionVariable());
2060 AddStmt(FS->getInit());
2061}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002063 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2064}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002066 AddStmt(If->getElse());
2067 AddStmt(If->getThen());
2068 AddStmt(If->getCond());
2069 AddDecl(If->getConditionVariable());
2070}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002072 // We care about the syntactic form of the initializer list, only.
2073 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2074 IE = Syntactic;
2075 EnqueueChildren(IE);
2076}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002078 WL.push_back(MemberExprParts(M, Parent));
2079
2080 // If the base of the member access expression is an implicit 'this', don't
2081 // visit it.
2082 // FIXME: If we ever want to show these implicit accesses, this will be
2083 // unfortunate. However, clang_getCursor() relies on this behavior.
2084 if (!M->isImplicitAccess())
2085 AddStmt(M->getBase());
2086}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002088 AddTypeLoc(E->getEncodedTypeSourceInfo());
2089}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002091 EnqueueChildren(M);
2092 AddTypeLoc(M->getClassReceiverTypeInfo());
2093}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002094void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002095 // Visit the components of the offsetof expression.
2096 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2097 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2098 const OffsetOfNode &Node = E->getComponent(I-1);
2099 switch (Node.getKind()) {
2100 case OffsetOfNode::Array:
2101 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2102 break;
2103 case OffsetOfNode::Field:
2104 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2105 break;
2106 case OffsetOfNode::Identifier:
2107 case OffsetOfNode::Base:
2108 continue;
2109 }
2110 }
2111 // Visit the type into which we're computing the offset.
2112 AddTypeLoc(E->getTypeSourceInfo());
2113}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002115 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2116 WL.push_back(OverloadExprParts(E, Parent));
2117}
2118void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002119 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002120 EnqueueChildren(E);
2121 if (E->isArgumentType())
2122 AddTypeLoc(E->getArgumentTypeInfo());
2123}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002125 EnqueueChildren(S);
2126}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002128 AddStmt(S->getBody());
2129 AddStmt(S->getCond());
2130 AddDecl(S->getConditionVariable());
2131}
2132
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002134 AddStmt(W->getBody());
2135 AddStmt(W->getCond());
2136 AddDecl(W->getConditionVariable());
2137}
2138
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002140 AddTypeLoc(E->getQueriedTypeSourceInfo());
2141}
2142
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002144 AddTypeLoc(E->getRhsTypeSourceInfo());
2145 AddTypeLoc(E->getLhsTypeSourceInfo());
2146}
2147
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002149 for (unsigned I = E->getNumArgs(); I > 0; --I)
2150 AddTypeLoc(E->getArg(I-1));
2151}
2152
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002154 AddTypeLoc(E->getQueriedTypeSourceInfo());
2155}
2156
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002158 EnqueueChildren(E);
2159}
2160
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002162 VisitOverloadExpr(U);
2163 if (!U->isImplicitAccess())
2164 AddStmt(U->getBase());
2165}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 AddStmt(E->getSubExpr());
2168 AddTypeLoc(E->getWrittenTypeInfo());
2169}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002171 WL.push_back(SizeOfPackExprParts(E, Parent));
2172}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002174 // If the opaque value has a source expression, just transparently
2175 // visit that. This is useful for (e.g.) pseudo-object expressions.
2176 if (Expr *SourceExpr = E->getSourceExpr())
2177 return Visit(SourceExpr);
2178}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002180 AddStmt(E->getBody());
2181 WL.push_back(LambdaExprParts(E, Parent));
2182}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002184 // Treat the expression like its syntactic form.
2185 Visit(E->getSyntacticForm());
2186}
2187
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002188void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002189 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2190}
2191
2192bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2193 if (RegionOfInterest.isValid()) {
2194 SourceRange Range = getRawCursorExtent(C);
2195 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2196 return false;
2197 }
2198 return true;
2199}
2200
2201bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2202 while (!WL.empty()) {
2203 // Dequeue the worklist item.
2204 VisitorJob LI = WL.back();
2205 WL.pop_back();
2206
2207 // Set the Parent field, then back to its old value once we're done.
2208 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2209
2210 switch (LI.getKind()) {
2211 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002212 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002213 if (!D)
2214 continue;
2215
2216 // For now, perform default visitation for Decls.
2217 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2218 cast<DeclVisit>(&LI)->isFirst())))
2219 return true;
2220
2221 continue;
2222 }
2223 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2224 const ASTTemplateArgumentListInfo *ArgList =
2225 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2226 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2227 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2228 Arg != ArgEnd; ++Arg) {
2229 if (VisitTemplateArgumentLoc(*Arg))
2230 return true;
2231 }
2232 continue;
2233 }
2234 case VisitorJob::TypeLocVisitKind: {
2235 // Perform default visitation for TypeLocs.
2236 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2237 return true;
2238 continue;
2239 }
2240 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002241 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002242 if (LabelStmt *stmt = LS->getStmt()) {
2243 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2244 TU))) {
2245 return true;
2246 }
2247 }
2248 continue;
2249 }
2250
2251 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2252 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2253 if (VisitNestedNameSpecifierLoc(V->get()))
2254 return true;
2255 continue;
2256 }
2257
2258 case VisitorJob::DeclarationNameInfoVisitKind: {
2259 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2260 ->get()))
2261 return true;
2262 continue;
2263 }
2264 case VisitorJob::MemberRefVisitKind: {
2265 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2266 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2267 return true;
2268 continue;
2269 }
2270 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002271 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002272 if (!S)
2273 continue;
2274
2275 // Update the current cursor.
2276 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2277 if (!IsInRegionOfInterest(Cursor))
2278 continue;
2279 switch (Visitor(Cursor, Parent, ClientData)) {
2280 case CXChildVisit_Break: return true;
2281 case CXChildVisit_Continue: break;
2282 case CXChildVisit_Recurse:
2283 if (PostChildrenVisitor)
2284 WL.push_back(PostChildrenVisit(0, Cursor));
2285 EnqueueWorkList(WL, S);
2286 break;
2287 }
2288 continue;
2289 }
2290 case VisitorJob::MemberExprPartsKind: {
2291 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002292 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002293
2294 // Visit the nested-name-specifier
2295 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2296 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2297 return true;
2298
2299 // Visit the declaration name.
2300 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2301 return true;
2302
2303 // Visit the explicitly-specified template arguments, if any.
2304 if (M->hasExplicitTemplateArgs()) {
2305 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2306 *ArgEnd = Arg + M->getNumTemplateArgs();
2307 Arg != ArgEnd; ++Arg) {
2308 if (VisitTemplateArgumentLoc(*Arg))
2309 return true;
2310 }
2311 }
2312 continue;
2313 }
2314 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002315 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002316 // Visit nested-name-specifier, if present.
2317 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2318 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2319 return true;
2320 // Visit declaration name.
2321 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2322 return true;
2323 continue;
2324 }
2325 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002326 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002327 // Visit the nested-name-specifier.
2328 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2329 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2330 return true;
2331 // Visit the declaration name.
2332 if (VisitDeclarationNameInfo(O->getNameInfo()))
2333 return true;
2334 // Visit the overloaded declaration reference.
2335 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2336 return true;
2337 continue;
2338 }
2339 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002340 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002341 NamedDecl *Pack = E->getPack();
2342 if (isa<TemplateTypeParmDecl>(Pack)) {
2343 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2344 E->getPackLoc(), TU)))
2345 return true;
2346
2347 continue;
2348 }
2349
2350 if (isa<TemplateTemplateParmDecl>(Pack)) {
2351 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2352 E->getPackLoc(), TU)))
2353 return true;
2354
2355 continue;
2356 }
2357
2358 // Non-type template parameter packs and function parameter packs are
2359 // treated like DeclRefExpr cursors.
2360 continue;
2361 }
2362
2363 case VisitorJob::LambdaExprPartsKind: {
2364 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002365 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002366 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2367 CEnd = E->explicit_capture_end();
2368 C != CEnd; ++C) {
2369 if (C->capturesThis())
2370 continue;
2371
2372 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2373 C->getLocation(),
2374 TU)))
2375 return true;
2376 }
2377
2378 // Visit parameters and return type, if present.
2379 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2380 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2381 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2382 // Visit the whole type.
2383 if (Visit(TL))
2384 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002385 } else if (FunctionProtoTypeLoc Proto =
2386 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002387 if (E->hasExplicitParameters()) {
2388 // Visit parameters.
2389 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2390 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2391 return true;
2392 } else {
2393 // Visit result type.
2394 if (Visit(Proto.getResultLoc()))
2395 return true;
2396 }
2397 }
2398 }
2399 break;
2400 }
2401
2402 case VisitorJob::PostChildrenVisitKind:
2403 if (PostChildrenVisitor(Parent, ClientData))
2404 return true;
2405 break;
2406 }
2407 }
2408 return false;
2409}
2410
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002411bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002412 VisitorWorkList *WL = 0;
2413 if (!WorkListFreeList.empty()) {
2414 WL = WorkListFreeList.back();
2415 WL->clear();
2416 WorkListFreeList.pop_back();
2417 }
2418 else {
2419 WL = new VisitorWorkList();
2420 WorkListCache.push_back(WL);
2421 }
2422 EnqueueWorkList(*WL, S);
2423 bool result = RunVisitorWorkList(*WL);
2424 WorkListFreeList.push_back(WL);
2425 return result;
2426}
2427
2428namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002429typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002430RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2431 const DeclarationNameInfo &NI,
2432 const SourceRange &QLoc,
2433 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2434 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2435 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2436 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2437
2438 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2439
2440 RefNamePieces Pieces;
2441
2442 if (WantQualifier && QLoc.isValid())
2443 Pieces.push_back(QLoc);
2444
2445 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2446 Pieces.push_back(NI.getLoc());
2447
2448 if (WantTemplateArgs && TemplateArgs)
2449 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2450 TemplateArgs->RAngleLoc));
2451
2452 if (Kind == DeclarationName::CXXOperatorName) {
2453 Pieces.push_back(SourceLocation::getFromRawEncoding(
2454 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2455 Pieces.push_back(SourceLocation::getFromRawEncoding(
2456 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2457 }
2458
2459 if (WantSinglePiece) {
2460 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2461 Pieces.clear();
2462 Pieces.push_back(R);
2463 }
2464
2465 return Pieces;
2466}
2467}
2468
2469//===----------------------------------------------------------------------===//
2470// Misc. API hooks.
2471//===----------------------------------------------------------------------===//
2472
2473static llvm::sys::Mutex EnableMultithreadingMutex;
2474static bool EnabledMultithreading;
2475
Chad Rosier90836282013-03-27 18:28:23 +00002476static void fatal_error_handler(void *user_data, const std::string& reason,
2477 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002478 // Write the result out to stderr avoiding errs() because raw_ostreams can
2479 // call report_fatal_error.
2480 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2481 ::abort();
2482}
2483
2484extern "C" {
2485CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2486 int displayDiagnostics) {
2487 // Disable pretty stack trace functionality, which will otherwise be a very
2488 // poor citizen of the world and set up all sorts of signal handlers.
2489 llvm::DisablePrettyStackTrace = true;
2490
2491 // We use crash recovery to make some of our APIs more reliable, implicitly
2492 // enable it.
2493 llvm::CrashRecoveryContext::Enable();
2494
2495 // Enable support for multithreading in LLVM.
2496 {
2497 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2498 if (!EnabledMultithreading) {
2499 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2500 llvm::llvm_start_multithreaded();
2501 EnabledMultithreading = true;
2502 }
2503 }
2504
2505 CIndexer *CIdxr = new CIndexer();
2506 if (excludeDeclarationsFromPCH)
2507 CIdxr->setOnlyLocalDecls();
2508 if (displayDiagnostics)
2509 CIdxr->setDisplayDiagnostics();
2510
2511 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2512 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2513 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2514 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2515 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2516 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2517
2518 return CIdxr;
2519}
2520
2521void clang_disposeIndex(CXIndex CIdx) {
2522 if (CIdx)
2523 delete static_cast<CIndexer *>(CIdx);
2524}
2525
2526void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2527 if (CIdx)
2528 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2529}
2530
2531unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2532 if (CIdx)
2533 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2534 return 0;
2535}
2536
2537void clang_toggleCrashRecovery(unsigned isEnabled) {
2538 if (isEnabled)
2539 llvm::CrashRecoveryContext::Enable();
2540 else
2541 llvm::CrashRecoveryContext::Disable();
2542}
2543
2544CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2545 const char *ast_filename) {
2546 if (!CIdx)
2547 return 0;
2548
2549 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2550 FileSystemOptions FileSystemOpts;
2551
2552 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2553 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2554 CXXIdx->getOnlyLocalDecls(),
2555 0, 0,
2556 /*CaptureDiagnostics=*/true,
2557 /*AllowPCHWithCompilerErrors=*/true,
2558 /*UserFilesAreVolatile=*/true);
2559 return MakeCXTranslationUnit(CXXIdx, TU);
2560}
2561
2562unsigned clang_defaultEditingTranslationUnitOptions() {
2563 return CXTranslationUnit_PrecompiledPreamble |
2564 CXTranslationUnit_CacheCompletionResults;
2565}
2566
2567CXTranslationUnit
2568clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2569 const char *source_filename,
2570 int num_command_line_args,
2571 const char * const *command_line_args,
2572 unsigned num_unsaved_files,
2573 struct CXUnsavedFile *unsaved_files) {
2574 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2575 return clang_parseTranslationUnit(CIdx, source_filename,
2576 command_line_args, num_command_line_args,
2577 unsaved_files, num_unsaved_files,
2578 Options);
2579}
2580
2581struct ParseTranslationUnitInfo {
2582 CXIndex CIdx;
2583 const char *source_filename;
2584 const char *const *command_line_args;
2585 int num_command_line_args;
2586 struct CXUnsavedFile *unsaved_files;
2587 unsigned num_unsaved_files;
2588 unsigned options;
2589 CXTranslationUnit result;
2590};
2591static void clang_parseTranslationUnit_Impl(void *UserData) {
2592 ParseTranslationUnitInfo *PTUI =
2593 static_cast<ParseTranslationUnitInfo*>(UserData);
2594 CXIndex CIdx = PTUI->CIdx;
2595 const char *source_filename = PTUI->source_filename;
2596 const char * const *command_line_args = PTUI->command_line_args;
2597 int num_command_line_args = PTUI->num_command_line_args;
2598 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2599 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2600 unsigned options = PTUI->options;
2601 PTUI->result = 0;
2602
2603 if (!CIdx)
2604 return;
2605
2606 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2607
2608 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2609 setThreadBackgroundPriority();
2610
2611 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2612 // FIXME: Add a flag for modules.
2613 TranslationUnitKind TUKind
2614 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2615 bool CacheCodeCompetionResults
2616 = options & CXTranslationUnit_CacheCompletionResults;
2617 bool IncludeBriefCommentsInCodeCompletion
2618 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2619 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2620 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2621
2622 // Configure the diagnostics.
2623 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002624 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002625
2626 // Recover resources if we crash before exiting this function.
2627 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2628 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2629 DiagCleanup(Diags.getPtr());
2630
2631 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2632 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2633
2634 // Recover resources if we crash before exiting this function.
2635 llvm::CrashRecoveryContextCleanupRegistrar<
2636 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2637
2638 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2639 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2640 const llvm::MemoryBuffer *Buffer
2641 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2642 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2643 Buffer));
2644 }
2645
2646 OwningPtr<std::vector<const char *> >
2647 Args(new std::vector<const char*>());
2648
2649 // Recover resources if we crash before exiting this method.
2650 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2651 ArgsCleanup(Args.get());
2652
2653 // Since the Clang C library is primarily used by batch tools dealing with
2654 // (often very broken) source code, where spell-checking can have a
2655 // significant negative impact on performance (particularly when
2656 // precompiled headers are involved), we disable it by default.
2657 // Only do this if we haven't found a spell-checking-related argument.
2658 bool FoundSpellCheckingArgument = false;
2659 for (int I = 0; I != num_command_line_args; ++I) {
2660 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2661 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2662 FoundSpellCheckingArgument = true;
2663 break;
2664 }
2665 }
2666 if (!FoundSpellCheckingArgument)
2667 Args->push_back("-fno-spell-checking");
2668
2669 Args->insert(Args->end(), command_line_args,
2670 command_line_args + num_command_line_args);
2671
2672 // The 'source_filename' argument is optional. If the caller does not
2673 // specify it then it is assumed that the source file is specified
2674 // in the actual argument list.
2675 // Put the source file after command_line_args otherwise if '-x' flag is
2676 // present it will be unused.
2677 if (source_filename)
2678 Args->push_back(source_filename);
2679
2680 // Do we need the detailed preprocessing record?
2681 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2682 Args->push_back("-Xclang");
2683 Args->push_back("-detailed-preprocessing-record");
2684 }
2685
2686 unsigned NumErrors = Diags->getClient()->getNumErrors();
2687 OwningPtr<ASTUnit> ErrUnit;
2688 OwningPtr<ASTUnit> Unit(
2689 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2690 /* vector::data() not portable */,
2691 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2692 Diags,
2693 CXXIdx->getClangResourcesPath(),
2694 CXXIdx->getOnlyLocalDecls(),
2695 /*CaptureDiagnostics=*/true,
2696 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2697 RemappedFiles->size(),
2698 /*RemappedFilesKeepOriginalName=*/true,
2699 PrecompilePreamble,
2700 TUKind,
2701 CacheCodeCompetionResults,
2702 IncludeBriefCommentsInCodeCompletion,
2703 /*AllowPCHWithCompilerErrors=*/true,
2704 SkipFunctionBodies,
2705 /*UserFilesAreVolatile=*/true,
2706 ForSerialization,
2707 &ErrUnit));
2708
2709 if (NumErrors != Diags->getClient()->getNumErrors()) {
2710 // Make sure to check that 'Unit' is non-NULL.
2711 if (CXXIdx->getDisplayDiagnostics())
2712 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2713 }
2714
2715 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2716}
2717CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2718 const char *source_filename,
2719 const char * const *command_line_args,
2720 int num_command_line_args,
2721 struct CXUnsavedFile *unsaved_files,
2722 unsigned num_unsaved_files,
2723 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002724 LOG_FUNC_SECTION {
2725 *Log << source_filename << ": ";
2726 for (int i = 0; i != num_command_line_args; ++i)
2727 *Log << command_line_args[i] << " ";
2728 }
2729
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002730 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2731 num_command_line_args, unsaved_files,
2732 num_unsaved_files, options, 0 };
2733 llvm::CrashRecoveryContext CRC;
2734
2735 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2736 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2737 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2738 fprintf(stderr, " 'command_line_args' : [");
2739 for (int i = 0; i != num_command_line_args; ++i) {
2740 if (i)
2741 fprintf(stderr, ", ");
2742 fprintf(stderr, "'%s'", command_line_args[i]);
2743 }
2744 fprintf(stderr, "],\n");
2745 fprintf(stderr, " 'unsaved_files' : [");
2746 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2747 if (i)
2748 fprintf(stderr, ", ");
2749 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2750 unsaved_files[i].Length);
2751 }
2752 fprintf(stderr, "],\n");
2753 fprintf(stderr, " 'options' : %d,\n", options);
2754 fprintf(stderr, "}\n");
2755
2756 return 0;
2757 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2758 PrintLibclangResourceUsage(PTUI.result);
2759 }
2760
2761 return PTUI.result;
2762}
2763
2764unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2765 return CXSaveTranslationUnit_None;
2766}
2767
2768namespace {
2769
2770struct SaveTranslationUnitInfo {
2771 CXTranslationUnit TU;
2772 const char *FileName;
2773 unsigned options;
2774 CXSaveError result;
2775};
2776
2777}
2778
2779static void clang_saveTranslationUnit_Impl(void *UserData) {
2780 SaveTranslationUnitInfo *STUI =
2781 static_cast<SaveTranslationUnitInfo*>(UserData);
2782
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002783 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002784 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2785 setThreadBackgroundPriority();
2786
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002787 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002788 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2789}
2790
2791int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2792 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002793 LOG_FUNC_SECTION {
2794 *Log << TU << ' ' << FileName;
2795 }
2796
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002797 if (!TU)
2798 return CXSaveError_InvalidTU;
2799
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002800 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002801 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2802 if (!CXXUnit->hasSema())
2803 return CXSaveError_InvalidTU;
2804
2805 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2806
2807 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2808 getenv("LIBCLANG_NOTHREADS")) {
2809 clang_saveTranslationUnit_Impl(&STUI);
2810
2811 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2812 PrintLibclangResourceUsage(TU);
2813
2814 return STUI.result;
2815 }
2816
2817 // We have an AST that has invalid nodes due to compiler errors.
2818 // Use a crash recovery thread for protection.
2819
2820 llvm::CrashRecoveryContext CRC;
2821
2822 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2823 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2824 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2825 fprintf(stderr, " 'options' : %d,\n", options);
2826 fprintf(stderr, "}\n");
2827
2828 return CXSaveError_Unknown;
2829
2830 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2831 PrintLibclangResourceUsage(TU);
2832 }
2833
2834 return STUI.result;
2835}
2836
2837void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2838 if (CTUnit) {
2839 // If the translation unit has been marked as unsafe to free, just discard
2840 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002841 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002842 return;
2843
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002844 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002845 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002846 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2847 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002848 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002849 delete CTUnit;
2850 }
2851}
2852
2853unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2854 return CXReparse_None;
2855}
2856
2857struct ReparseTranslationUnitInfo {
2858 CXTranslationUnit TU;
2859 unsigned num_unsaved_files;
2860 struct CXUnsavedFile *unsaved_files;
2861 unsigned options;
2862 int result;
2863};
2864
2865static void clang_reparseTranslationUnit_Impl(void *UserData) {
2866 ReparseTranslationUnitInfo *RTUI =
2867 static_cast<ReparseTranslationUnitInfo*>(UserData);
2868 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002869 if (!TU)
2870 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002871
2872 // Reset the associated diagnostics.
2873 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2874 TU->Diagnostics = 0;
2875
2876 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2877 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2878 unsigned options = RTUI->options;
2879 (void) options;
2880 RTUI->result = 1;
2881
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002882 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002883 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2884 setThreadBackgroundPriority();
2885
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002886 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002887 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2888
2889 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2890 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2891
2892 // Recover resources if we crash before exiting this function.
2893 llvm::CrashRecoveryContextCleanupRegistrar<
2894 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2895
2896 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2897 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2898 const llvm::MemoryBuffer *Buffer
2899 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2900 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2901 Buffer));
2902 }
2903
2904 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2905 RemappedFiles->size()))
2906 RTUI->result = 0;
2907}
2908
2909int clang_reparseTranslationUnit(CXTranslationUnit TU,
2910 unsigned num_unsaved_files,
2911 struct CXUnsavedFile *unsaved_files,
2912 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002913 LOG_FUNC_SECTION {
2914 *Log << TU;
2915 }
2916
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002917 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2918 options, 0 };
2919
2920 if (getenv("LIBCLANG_NOTHREADS")) {
2921 clang_reparseTranslationUnit_Impl(&RTUI);
2922 return RTUI.result;
2923 }
2924
2925 llvm::CrashRecoveryContext CRC;
2926
2927 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2928 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002929 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002930 return 1;
2931 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2932 PrintLibclangResourceUsage(TU);
2933
2934 return RTUI.result;
2935}
2936
2937
2938CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2939 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002940 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002941
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002942 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002943 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002944}
2945
2946CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00002947 if (!TU)
2948 return clang_getNullCursor();
2949
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002950 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002951 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2952}
2953
2954} // end: extern "C"
2955
2956//===----------------------------------------------------------------------===//
2957// CXFile Operations.
2958//===----------------------------------------------------------------------===//
2959
2960extern "C" {
2961CXString clang_getFileName(CXFile SFile) {
2962 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002963 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002964
2965 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002966 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002967}
2968
2969time_t clang_getFileTime(CXFile SFile) {
2970 if (!SFile)
2971 return 0;
2972
2973 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2974 return FEnt->getModificationTime();
2975}
2976
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002977CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2978 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002979 return 0;
2980
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002981 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002982
2983 FileManager &FMgr = CXXUnit->getFileManager();
2984 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2985}
2986
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002987unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2988 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002989 return 0;
2990
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002991 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002992 FileEntry *FEnt = static_cast<FileEntry *>(file);
2993 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2994 .isFileMultipleIncludeGuarded(FEnt);
2995}
2996
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002997int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2998 if (!file || !outID)
2999 return 1;
3000
3001#ifdef LLVM_ON_WIN32
3002 return 1; // inodes not supported on windows.
3003#else
3004 FileEntry *FEnt = static_cast<FileEntry *>(file);
3005 outID->data[0] = FEnt->getDevice();
3006 outID->data[1] = FEnt->getInode();
3007 outID->data[2] = FEnt->getModificationTime();
3008 return 0;
3009#endif
3010}
3011
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003012} // end: extern "C"
3013
3014//===----------------------------------------------------------------------===//
3015// CXCursor Operations.
3016//===----------------------------------------------------------------------===//
3017
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003018static const Decl *getDeclFromExpr(const Stmt *E) {
3019 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003020 return getDeclFromExpr(CE->getSubExpr());
3021
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003022 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003023 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003024 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003025 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003026 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003027 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003028 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003029 if (PRE->isExplicitProperty())
3030 return PRE->getExplicitProperty();
3031 // It could be messaging both getter and setter as in:
3032 // ++myobj.myprop;
3033 // in which case prefer to associate the setter since it is less obvious
3034 // from inspecting the source that the setter is going to get called.
3035 if (PRE->isMessagingSetter())
3036 return PRE->getImplicitPropertySetter();
3037 return PRE->getImplicitPropertyGetter();
3038 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003039 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003040 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003041 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003042 if (Expr *Src = OVE->getSourceExpr())
3043 return getDeclFromExpr(Src);
3044
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003045 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003046 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003047 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003048 if (!CE->isElidable())
3049 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003050 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return OME->getMethodDecl();
3052
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003053 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003054 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003055 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003056 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3057 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003058 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003059 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3060 isa<ParmVarDecl>(SizeOfPack->getPack()))
3061 return SizeOfPack->getPack();
3062
3063 return 0;
3064}
3065
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003066static SourceLocation getLocationFromExpr(const Expr *E) {
3067 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003068 return getLocationFromExpr(CE->getSubExpr());
3069
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003070 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003071 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003072 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003073 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003074 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003075 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003076 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003077 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003078 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003079 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003080 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003081 return PropRef->getLocation();
3082
3083 return E->getLocStart();
3084}
3085
3086extern "C" {
3087
3088unsigned clang_visitChildren(CXCursor parent,
3089 CXCursorVisitor visitor,
3090 CXClientData client_data) {
3091 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3092 /*VisitPreprocessorLast=*/false);
3093 return CursorVis.VisitChildren(parent);
3094}
3095
3096#ifndef __has_feature
3097#define __has_feature(x) 0
3098#endif
3099#if __has_feature(blocks)
3100typedef enum CXChildVisitResult
3101 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3102
3103static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3104 CXClientData client_data) {
3105 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3106 return block(cursor, parent);
3107}
3108#else
3109// If we are compiled with a compiler that doesn't have native blocks support,
3110// define and call the block manually, so the
3111typedef struct _CXChildVisitResult
3112{
3113 void *isa;
3114 int flags;
3115 int reserved;
3116 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3117 CXCursor);
3118} *CXCursorVisitorBlock;
3119
3120static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3121 CXClientData client_data) {
3122 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3123 return block->invoke(block, cursor, parent);
3124}
3125#endif
3126
3127
3128unsigned clang_visitChildrenWithBlock(CXCursor parent,
3129 CXCursorVisitorBlock block) {
3130 return clang_visitChildren(parent, visitWithBlock, block);
3131}
3132
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003133static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003134 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003135 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003136
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003137 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003138 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003139 if (const ObjCPropertyImplDecl *PropImpl =
3140 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003141 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003142 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003143
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003144 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003145 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003146 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003147
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003148 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003149 }
3150
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003151 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003152 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003153
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003154 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003155 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3156 // and returns different names. NamedDecl returns the class name and
3157 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003158 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003159
3160 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003161 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003162
3163 SmallString<1024> S;
3164 llvm::raw_svector_ostream os(S);
3165 ND->printName(os);
3166
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003167 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003168}
3169
3170CXString clang_getCursorSpelling(CXCursor C) {
3171 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003172 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003173
3174 if (clang_isReference(C.kind)) {
3175 switch (C.kind) {
3176 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003177 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003178 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003179 }
3180 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003181 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003182 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003183 }
3184 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003185 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003186 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003187 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003188 }
3189 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003190 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003191 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 }
3193 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003194 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195 assert(Type && "Missing type decl");
3196
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003197 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003198 getAsString());
3199 }
3200 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003201 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003202 assert(Template && "Missing template decl");
3203
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003204 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205 }
3206
3207 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003208 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209 assert(NS && "Missing namespace decl");
3210
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003211 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003212 }
3213
3214 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003215 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003216 assert(Field && "Missing member decl");
3217
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003218 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003219 }
3220
3221 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003222 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003223 assert(Label && "Missing label");
3224
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003225 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003226 }
3227
3228 case CXCursor_OverloadedDeclRef: {
3229 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003230 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3231 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003232 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003233 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003234 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003235 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003236 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003237 OverloadedTemplateStorage *Ovl
3238 = Storage.get<OverloadedTemplateStorage*>();
3239 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003240 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003241 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 }
3243
3244 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003245 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246 assert(Var && "Missing variable decl");
3247
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003248 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003249 }
3250
3251 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003252 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003253 }
3254 }
3255
3256 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003257 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 if (D)
3259 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003260 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003261 }
3262
3263 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003264 const Stmt *S = getCursorStmt(C);
3265 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003266 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003267
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003268 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003269 }
3270
3271 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003272 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003273 ->getNameStart());
3274
3275 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003276 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003277 ->getNameStart());
3278
3279 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003280 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003281
3282 if (clang_isDeclaration(C.kind))
3283 return getDeclSpelling(getCursorDecl(C));
3284
3285 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003286 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003287 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003288 }
3289
3290 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003291 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003292 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293 }
3294
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003295 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003296}
3297
3298CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3299 unsigned pieceIndex,
3300 unsigned options) {
3301 if (clang_Cursor_isNull(C))
3302 return clang_getNullRange();
3303
3304 ASTContext &Ctx = getCursorContext(C);
3305
3306 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003307 const Stmt *S = getCursorStmt(C);
3308 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003309 if (pieceIndex > 0)
3310 return clang_getNullRange();
3311 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3312 }
3313
3314 return clang_getNullRange();
3315 }
3316
3317 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003318 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003319 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3320 if (pieceIndex >= ME->getNumSelectorLocs())
3321 return clang_getNullRange();
3322 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3323 }
3324 }
3325
3326 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3327 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003328 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003329 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3330 if (pieceIndex >= MD->getNumSelectorLocs())
3331 return clang_getNullRange();
3332 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3333 }
3334 }
3335
3336 if (C.kind == CXCursor_ObjCCategoryDecl ||
3337 C.kind == CXCursor_ObjCCategoryImplDecl) {
3338 if (pieceIndex > 0)
3339 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003340 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003341 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3342 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003343 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003344 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3345 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3346 }
3347
3348 if (C.kind == CXCursor_ModuleImportDecl) {
3349 if (pieceIndex > 0)
3350 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003351 if (const ImportDecl *ImportD =
3352 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003353 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3354 if (!Locs.empty())
3355 return cxloc::translateSourceRange(Ctx,
3356 SourceRange(Locs.front(), Locs.back()));
3357 }
3358 return clang_getNullRange();
3359 }
3360
3361 // FIXME: A CXCursor_InclusionDirective should give the location of the
3362 // filename, but we don't keep track of this.
3363
3364 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3365 // but we don't keep track of this.
3366
3367 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3368 // but we don't keep track of this.
3369
3370 // Default handling, give the location of the cursor.
3371
3372 if (pieceIndex > 0)
3373 return clang_getNullRange();
3374
3375 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3376 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3377 return cxloc::translateSourceRange(Ctx, Loc);
3378}
3379
3380CXString clang_getCursorDisplayName(CXCursor C) {
3381 if (!clang_isDeclaration(C.kind))
3382 return clang_getCursorSpelling(C);
3383
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003384 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003385 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003386 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003387
3388 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003389 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003390 D = FunTmpl->getTemplatedDecl();
3391
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003392 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003393 SmallString<64> Str;
3394 llvm::raw_svector_ostream OS(Str);
3395 OS << *Function;
3396 if (Function->getPrimaryTemplate())
3397 OS << "<>";
3398 OS << "(";
3399 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3400 if (I)
3401 OS << ", ";
3402 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3403 }
3404
3405 if (Function->isVariadic()) {
3406 if (Function->getNumParams())
3407 OS << ", ";
3408 OS << "...";
3409 }
3410 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003411 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003412 }
3413
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003414 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003415 SmallString<64> Str;
3416 llvm::raw_svector_ostream OS(Str);
3417 OS << *ClassTemplate;
3418 OS << "<";
3419 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3420 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3421 if (I)
3422 OS << ", ";
3423
3424 NamedDecl *Param = Params->getParam(I);
3425 if (Param->getIdentifier()) {
3426 OS << Param->getIdentifier()->getName();
3427 continue;
3428 }
3429
3430 // There is no parameter name, which makes this tricky. Try to come up
3431 // with something useful that isn't too long.
3432 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3433 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3434 else if (NonTypeTemplateParmDecl *NTTP
3435 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3436 OS << NTTP->getType().getAsString(Policy);
3437 else
3438 OS << "template<...> class";
3439 }
3440
3441 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003442 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003443 }
3444
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003445 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003446 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3447 // If the type was explicitly written, use that.
3448 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003449 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003450
Benjamin Kramer5eada842013-02-22 15:46:01 +00003451 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003452 llvm::raw_svector_ostream OS(Str);
3453 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003454 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003455 ClassSpec->getTemplateArgs().data(),
3456 ClassSpec->getTemplateArgs().size(),
3457 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003458 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003459 }
3460
3461 return clang_getCursorSpelling(C);
3462}
3463
3464CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3465 switch (Kind) {
3466 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003467 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003468 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003469 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003470 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003471 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003472 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003473 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003474 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003475 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003476 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003477 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003478 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003479 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003480 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003481 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003482 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003483 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003484 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003485 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003486 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003487 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003488 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003489 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003490 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003491 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003492 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003493 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003494 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003495 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003496 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003497 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003498 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003499 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003500 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003501 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003502 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003503 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003504 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003505 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003506 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003507 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003508 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003509 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003511 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003512 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003513 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003514 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003515 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003516 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003517 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003518 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003519 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003520 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003521 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003522 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003523 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003524 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003525 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003526 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003594 case CXCursor_ObjCSelfExpr:
3595 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003739 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003740 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003741 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003742 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003743 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003744 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003745 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003746 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003747 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003748 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003749 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003750 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003751 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003752 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003754 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003756 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003757 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003758 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003759 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003760 }
3761
3762 llvm_unreachable("Unhandled CXCursorKind");
3763}
3764
3765struct GetCursorData {
3766 SourceLocation TokenBeginLoc;
3767 bool PointsAtMacroArgExpansion;
3768 bool VisitedObjCPropertyImplDecl;
3769 SourceLocation VisitedDeclaratorDeclStartLoc;
3770 CXCursor &BestCursor;
3771
3772 GetCursorData(SourceManager &SM,
3773 SourceLocation tokenBegin, CXCursor &outputCursor)
3774 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3775 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3776 VisitedObjCPropertyImplDecl = false;
3777 }
3778};
3779
3780static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3781 CXCursor parent,
3782 CXClientData client_data) {
3783 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3784 CXCursor *BestCursor = &Data->BestCursor;
3785
3786 // If we point inside a macro argument we should provide info of what the
3787 // token is so use the actual cursor, don't replace it with a macro expansion
3788 // cursor.
3789 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3790 return CXChildVisit_Recurse;
3791
3792 if (clang_isDeclaration(cursor.kind)) {
3793 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003794 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003795 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3796 if (MD->isImplicit())
3797 return CXChildVisit_Break;
3798
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003799 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3801 // Check that when we have multiple @class references in the same line,
3802 // that later ones do not override the previous ones.
3803 // If we have:
3804 // @class Foo, Bar;
3805 // source ranges for both start at '@', so 'Bar' will end up overriding
3806 // 'Foo' even though the cursor location was at 'Foo'.
3807 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3808 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003809 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003810 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3811 if (PrevID != ID &&
3812 !PrevID->isThisDeclarationADefinition() &&
3813 !ID->isThisDeclarationADefinition())
3814 return CXChildVisit_Break;
3815 }
3816
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003817 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003818 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3819 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3820 // Check that when we have multiple declarators in the same line,
3821 // that later ones do not override the previous ones.
3822 // If we have:
3823 // int Foo, Bar;
3824 // source ranges for both start at 'int', so 'Bar' will end up overriding
3825 // 'Foo' even though the cursor location was at 'Foo'.
3826 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3827 return CXChildVisit_Break;
3828 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3829
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003830 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003831 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3832 (void)PropImp;
3833 // Check that when we have multiple @synthesize in the same line,
3834 // that later ones do not override the previous ones.
3835 // If we have:
3836 // @synthesize Foo, Bar;
3837 // source ranges for both start at '@', so 'Bar' will end up overriding
3838 // 'Foo' even though the cursor location was at 'Foo'.
3839 if (Data->VisitedObjCPropertyImplDecl)
3840 return CXChildVisit_Break;
3841 Data->VisitedObjCPropertyImplDecl = true;
3842 }
3843 }
3844
3845 if (clang_isExpression(cursor.kind) &&
3846 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003847 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003848 // Avoid having the cursor of an expression replace the declaration cursor
3849 // when the expression source range overlaps the declaration range.
3850 // This can happen for C++ constructor expressions whose range generally
3851 // include the variable declaration, e.g.:
3852 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3853 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3854 D->getLocation() == Data->TokenBeginLoc)
3855 return CXChildVisit_Break;
3856 }
3857 }
3858
3859 // If our current best cursor is the construction of a temporary object,
3860 // don't replace that cursor with a type reference, because we want
3861 // clang_getCursor() to point at the constructor.
3862 if (clang_isExpression(BestCursor->kind) &&
3863 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3864 cursor.kind == CXCursor_TypeRef) {
3865 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3866 // as having the actual point on the type reference.
3867 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3868 return CXChildVisit_Recurse;
3869 }
3870
3871 *BestCursor = cursor;
3872 return CXChildVisit_Recurse;
3873}
3874
3875CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3876 if (!TU)
3877 return clang_getNullCursor();
3878
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003879 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003880 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3881
3882 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3883 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3884
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003885 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003886 CXFile SearchFile;
3887 unsigned SearchLine, SearchColumn;
3888 CXFile ResultFile;
3889 unsigned ResultLine, ResultColumn;
3890 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3891 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3892 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3893
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003894 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3895 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003896 &ResultColumn, 0);
3897 SearchFileName = clang_getFileName(SearchFile);
3898 ResultFileName = clang_getFileName(ResultFile);
3899 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3900 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003901 *Log << llvm::format("(%s:%d:%d) = %s",
3902 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3903 clang_getCString(KindSpelling))
3904 << llvm::format("(%s:%d:%d):%s%s",
3905 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3906 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003907 clang_disposeString(SearchFileName);
3908 clang_disposeString(ResultFileName);
3909 clang_disposeString(KindSpelling);
3910 clang_disposeString(USR);
3911
3912 CXCursor Definition = clang_getCursorDefinition(Result);
3913 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3914 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3915 CXString DefinitionKindSpelling
3916 = clang_getCursorKindSpelling(Definition.kind);
3917 CXFile DefinitionFile;
3918 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003919 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003920 &DefinitionLine, &DefinitionColumn, 0);
3921 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003922 *Log << llvm::format(" -> %s(%s:%d:%d)",
3923 clang_getCString(DefinitionKindSpelling),
3924 clang_getCString(DefinitionFileName),
3925 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003926 clang_disposeString(DefinitionFileName);
3927 clang_disposeString(DefinitionKindSpelling);
3928 }
3929 }
3930
3931 return Result;
3932}
3933
3934CXCursor clang_getNullCursor(void) {
3935 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3936}
3937
3938unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003939 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3940 // can't set consistently. For example, when visiting a DeclStmt we will set
3941 // it but we don't set it on the result of clang_getCursorDefinition for
3942 // a reference of the same declaration.
3943 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3944 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3945 // to provide that kind of info.
3946 if (clang_isDeclaration(X.kind))
3947 X.data[1] = 0;
3948 if (clang_isDeclaration(Y.kind))
3949 Y.data[1] = 0;
3950
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003951 return X == Y;
3952}
3953
3954unsigned clang_hashCursor(CXCursor C) {
3955 unsigned Index = 0;
3956 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3957 Index = 1;
3958
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003959 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003960 std::make_pair(C.kind, C.data[Index]));
3961}
3962
3963unsigned clang_isInvalid(enum CXCursorKind K) {
3964 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3965}
3966
3967unsigned clang_isDeclaration(enum CXCursorKind K) {
3968 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3969 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3970}
3971
3972unsigned clang_isReference(enum CXCursorKind K) {
3973 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3974}
3975
3976unsigned clang_isExpression(enum CXCursorKind K) {
3977 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3978}
3979
3980unsigned clang_isStatement(enum CXCursorKind K) {
3981 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3982}
3983
3984unsigned clang_isAttribute(enum CXCursorKind K) {
3985 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3986}
3987
3988unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3989 return K == CXCursor_TranslationUnit;
3990}
3991
3992unsigned clang_isPreprocessing(enum CXCursorKind K) {
3993 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3994}
3995
3996unsigned clang_isUnexposed(enum CXCursorKind K) {
3997 switch (K) {
3998 case CXCursor_UnexposedDecl:
3999 case CXCursor_UnexposedExpr:
4000 case CXCursor_UnexposedStmt:
4001 case CXCursor_UnexposedAttr:
4002 return true;
4003 default:
4004 return false;
4005 }
4006}
4007
4008CXCursorKind clang_getCursorKind(CXCursor C) {
4009 return C.kind;
4010}
4011
4012CXSourceLocation clang_getCursorLocation(CXCursor C) {
4013 if (clang_isReference(C.kind)) {
4014 switch (C.kind) {
4015 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004016 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004017 = getCursorObjCSuperClassRef(C);
4018 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4019 }
4020
4021 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004022 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004023 = getCursorObjCProtocolRef(C);
4024 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4025 }
4026
4027 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004028 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004029 = getCursorObjCClassRef(C);
4030 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4031 }
4032
4033 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004034 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004035 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4036 }
4037
4038 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004039 std::pair<const TemplateDecl *, SourceLocation> P =
4040 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004041 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4042 }
4043
4044 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004045 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004046 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4047 }
4048
4049 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004050 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004051 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4052 }
4053
4054 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004055 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004056 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4057 }
4058
4059 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004060 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004061 if (!BaseSpec)
4062 return clang_getNullLocation();
4063
4064 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4065 return cxloc::translateSourceLocation(getCursorContext(C),
4066 TSInfo->getTypeLoc().getBeginLoc());
4067
4068 return cxloc::translateSourceLocation(getCursorContext(C),
4069 BaseSpec->getLocStart());
4070 }
4071
4072 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004073 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004074 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4075 }
4076
4077 case CXCursor_OverloadedDeclRef:
4078 return cxloc::translateSourceLocation(getCursorContext(C),
4079 getCursorOverloadedDeclRef(C).second);
4080
4081 default:
4082 // FIXME: Need a way to enumerate all non-reference cases.
4083 llvm_unreachable("Missed a reference kind");
4084 }
4085 }
4086
4087 if (clang_isExpression(C.kind))
4088 return cxloc::translateSourceLocation(getCursorContext(C),
4089 getLocationFromExpr(getCursorExpr(C)));
4090
4091 if (clang_isStatement(C.kind))
4092 return cxloc::translateSourceLocation(getCursorContext(C),
4093 getCursorStmt(C)->getLocStart());
4094
4095 if (C.kind == CXCursor_PreprocessingDirective) {
4096 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4097 return cxloc::translateSourceLocation(getCursorContext(C), L);
4098 }
4099
4100 if (C.kind == CXCursor_MacroExpansion) {
4101 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004102 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004103 return cxloc::translateSourceLocation(getCursorContext(C), L);
4104 }
4105
4106 if (C.kind == CXCursor_MacroDefinition) {
4107 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4108 return cxloc::translateSourceLocation(getCursorContext(C), L);
4109 }
4110
4111 if (C.kind == CXCursor_InclusionDirective) {
4112 SourceLocation L
4113 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4114 return cxloc::translateSourceLocation(getCursorContext(C), L);
4115 }
4116
4117 if (!clang_isDeclaration(C.kind))
4118 return clang_getNullLocation();
4119
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004120 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004121 if (!D)
4122 return clang_getNullLocation();
4123
4124 SourceLocation Loc = D->getLocation();
4125 // FIXME: Multiple variables declared in a single declaration
4126 // currently lack the information needed to correctly determine their
4127 // ranges when accounting for the type-specifier. We use context
4128 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4129 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004130 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004131 if (!cxcursor::isFirstInDeclGroup(C))
4132 Loc = VD->getLocation();
4133 }
4134
4135 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004136 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004137 Loc = MD->getSelectorStartLoc();
4138
4139 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4140}
4141
4142} // end extern "C"
4143
4144CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4145 assert(TU);
4146
4147 // Guard against an invalid SourceLocation, or we may assert in one
4148 // of the following calls.
4149 if (SLoc.isInvalid())
4150 return clang_getNullCursor();
4151
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004152 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004153
4154 // Translate the given source location to make it point at the beginning of
4155 // the token under the cursor.
4156 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4157 CXXUnit->getASTContext().getLangOpts());
4158
4159 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4160 if (SLoc.isValid()) {
4161 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4162 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4163 /*VisitPreprocessorLast=*/true,
4164 /*VisitIncludedEntities=*/false,
4165 SourceLocation(SLoc));
4166 CursorVis.visitFileRegion();
4167 }
4168
4169 return Result;
4170}
4171
4172static SourceRange getRawCursorExtent(CXCursor C) {
4173 if (clang_isReference(C.kind)) {
4174 switch (C.kind) {
4175 case CXCursor_ObjCSuperClassRef:
4176 return getCursorObjCSuperClassRef(C).second;
4177
4178 case CXCursor_ObjCProtocolRef:
4179 return getCursorObjCProtocolRef(C).second;
4180
4181 case CXCursor_ObjCClassRef:
4182 return getCursorObjCClassRef(C).second;
4183
4184 case CXCursor_TypeRef:
4185 return getCursorTypeRef(C).second;
4186
4187 case CXCursor_TemplateRef:
4188 return getCursorTemplateRef(C).second;
4189
4190 case CXCursor_NamespaceRef:
4191 return getCursorNamespaceRef(C).second;
4192
4193 case CXCursor_MemberRef:
4194 return getCursorMemberRef(C).second;
4195
4196 case CXCursor_CXXBaseSpecifier:
4197 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4198
4199 case CXCursor_LabelRef:
4200 return getCursorLabelRef(C).second;
4201
4202 case CXCursor_OverloadedDeclRef:
4203 return getCursorOverloadedDeclRef(C).second;
4204
4205 case CXCursor_VariableRef:
4206 return getCursorVariableRef(C).second;
4207
4208 default:
4209 // FIXME: Need a way to enumerate all non-reference cases.
4210 llvm_unreachable("Missed a reference kind");
4211 }
4212 }
4213
4214 if (clang_isExpression(C.kind))
4215 return getCursorExpr(C)->getSourceRange();
4216
4217 if (clang_isStatement(C.kind))
4218 return getCursorStmt(C)->getSourceRange();
4219
4220 if (clang_isAttribute(C.kind))
4221 return getCursorAttr(C)->getRange();
4222
4223 if (C.kind == CXCursor_PreprocessingDirective)
4224 return cxcursor::getCursorPreprocessingDirective(C);
4225
4226 if (C.kind == CXCursor_MacroExpansion) {
4227 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004228 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004229 return TU->mapRangeFromPreamble(Range);
4230 }
4231
4232 if (C.kind == CXCursor_MacroDefinition) {
4233 ASTUnit *TU = getCursorASTUnit(C);
4234 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4235 return TU->mapRangeFromPreamble(Range);
4236 }
4237
4238 if (C.kind == CXCursor_InclusionDirective) {
4239 ASTUnit *TU = getCursorASTUnit(C);
4240 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4241 return TU->mapRangeFromPreamble(Range);
4242 }
4243
4244 if (C.kind == CXCursor_TranslationUnit) {
4245 ASTUnit *TU = getCursorASTUnit(C);
4246 FileID MainID = TU->getSourceManager().getMainFileID();
4247 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4248 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4249 return SourceRange(Start, End);
4250 }
4251
4252 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004253 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004254 if (!D)
4255 return SourceRange();
4256
4257 SourceRange R = D->getSourceRange();
4258 // FIXME: Multiple variables declared in a single declaration
4259 // currently lack the information needed to correctly determine their
4260 // ranges when accounting for the type-specifier. We use context
4261 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4262 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004263 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004264 if (!cxcursor::isFirstInDeclGroup(C))
4265 R.setBegin(VD->getLocation());
4266 }
4267 return R;
4268 }
4269 return SourceRange();
4270}
4271
4272/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4273/// the decl-specifier-seq for declarations.
4274static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4275 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004276 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004277 if (!D)
4278 return SourceRange();
4279
4280 SourceRange R = D->getSourceRange();
4281
4282 // Adjust the start of the location for declarations preceded by
4283 // declaration specifiers.
4284 SourceLocation StartLoc;
4285 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4286 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4287 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004288 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004289 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4290 StartLoc = TI->getTypeLoc().getLocStart();
4291 }
4292
4293 if (StartLoc.isValid() && R.getBegin().isValid() &&
4294 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4295 R.setBegin(StartLoc);
4296
4297 // FIXME: Multiple variables declared in a single declaration
4298 // currently lack the information needed to correctly determine their
4299 // ranges when accounting for the type-specifier. We use context
4300 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4301 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004302 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004303 if (!cxcursor::isFirstInDeclGroup(C))
4304 R.setBegin(VD->getLocation());
4305 }
4306
4307 return R;
4308 }
4309
4310 return getRawCursorExtent(C);
4311}
4312
4313extern "C" {
4314
4315CXSourceRange clang_getCursorExtent(CXCursor C) {
4316 SourceRange R = getRawCursorExtent(C);
4317 if (R.isInvalid())
4318 return clang_getNullRange();
4319
4320 return cxloc::translateSourceRange(getCursorContext(C), R);
4321}
4322
4323CXCursor clang_getCursorReferenced(CXCursor C) {
4324 if (clang_isInvalid(C.kind))
4325 return clang_getNullCursor();
4326
4327 CXTranslationUnit tu = getCursorTU(C);
4328 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004329 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004330 if (!D)
4331 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004332 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004333 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004334 if (const ObjCPropertyImplDecl *PropImpl =
4335 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004336 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4337 return MakeCXCursor(Property, tu);
4338
4339 return C;
4340 }
4341
4342 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004343 const Expr *E = getCursorExpr(C);
4344 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004345 if (D) {
4346 CXCursor declCursor = MakeCXCursor(D, tu);
4347 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4348 declCursor);
4349 return declCursor;
4350 }
4351
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004352 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004353 return MakeCursorOverloadedDeclRef(Ovl, tu);
4354
4355 return clang_getNullCursor();
4356 }
4357
4358 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004359 const Stmt *S = getCursorStmt(C);
4360 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004361 if (LabelDecl *label = Goto->getLabel())
4362 if (LabelStmt *labelS = label->getStmt())
4363 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4364
4365 return clang_getNullCursor();
4366 }
4367
4368 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004369 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004370 return MakeMacroDefinitionCursor(Def, tu);
4371 }
4372
4373 if (!clang_isReference(C.kind))
4374 return clang_getNullCursor();
4375
4376 switch (C.kind) {
4377 case CXCursor_ObjCSuperClassRef:
4378 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4379
4380 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004381 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4382 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004383 return MakeCXCursor(Def, tu);
4384
4385 return MakeCXCursor(Prot, tu);
4386 }
4387
4388 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004389 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4390 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004391 return MakeCXCursor(Def, tu);
4392
4393 return MakeCXCursor(Class, tu);
4394 }
4395
4396 case CXCursor_TypeRef:
4397 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4398
4399 case CXCursor_TemplateRef:
4400 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4401
4402 case CXCursor_NamespaceRef:
4403 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4404
4405 case CXCursor_MemberRef:
4406 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4407
4408 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004409 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004410 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4411 tu ));
4412 }
4413
4414 case CXCursor_LabelRef:
4415 // FIXME: We end up faking the "parent" declaration here because we
4416 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004417 return MakeCXCursor(getCursorLabelRef(C).first,
4418 cxtu::getASTUnit(tu)->getASTContext()
4419 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004420 tu);
4421
4422 case CXCursor_OverloadedDeclRef:
4423 return C;
4424
4425 case CXCursor_VariableRef:
4426 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4427
4428 default:
4429 // We would prefer to enumerate all non-reference cursor kinds here.
4430 llvm_unreachable("Unhandled reference cursor kind");
4431 }
4432}
4433
4434CXCursor clang_getCursorDefinition(CXCursor C) {
4435 if (clang_isInvalid(C.kind))
4436 return clang_getNullCursor();
4437
4438 CXTranslationUnit TU = getCursorTU(C);
4439
4440 bool WasReference = false;
4441 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4442 C = clang_getCursorReferenced(C);
4443 WasReference = true;
4444 }
4445
4446 if (C.kind == CXCursor_MacroExpansion)
4447 return clang_getCursorReferenced(C);
4448
4449 if (!clang_isDeclaration(C.kind))
4450 return clang_getNullCursor();
4451
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004452 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004453 if (!D)
4454 return clang_getNullCursor();
4455
4456 switch (D->getKind()) {
4457 // Declaration kinds that don't really separate the notions of
4458 // declaration and definition.
4459 case Decl::Namespace:
4460 case Decl::Typedef:
4461 case Decl::TypeAlias:
4462 case Decl::TypeAliasTemplate:
4463 case Decl::TemplateTypeParm:
4464 case Decl::EnumConstant:
4465 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004466 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004467 case Decl::IndirectField:
4468 case Decl::ObjCIvar:
4469 case Decl::ObjCAtDefsField:
4470 case Decl::ImplicitParam:
4471 case Decl::ParmVar:
4472 case Decl::NonTypeTemplateParm:
4473 case Decl::TemplateTemplateParm:
4474 case Decl::ObjCCategoryImpl:
4475 case Decl::ObjCImplementation:
4476 case Decl::AccessSpec:
4477 case Decl::LinkageSpec:
4478 case Decl::ObjCPropertyImpl:
4479 case Decl::FileScopeAsm:
4480 case Decl::StaticAssert:
4481 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004482 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004483 case Decl::Label: // FIXME: Is this right??
4484 case Decl::ClassScopeFunctionSpecialization:
4485 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004486 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004487 return C;
4488
4489 // Declaration kinds that don't make any sense here, but are
4490 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004491 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004492 case Decl::TranslationUnit:
4493 break;
4494
4495 // Declaration kinds for which the definition is not resolvable.
4496 case Decl::UnresolvedUsingTypename:
4497 case Decl::UnresolvedUsingValue:
4498 break;
4499
4500 case Decl::UsingDirective:
4501 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4502 TU);
4503
4504 case Decl::NamespaceAlias:
4505 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4506
4507 case Decl::Enum:
4508 case Decl::Record:
4509 case Decl::CXXRecord:
4510 case Decl::ClassTemplateSpecialization:
4511 case Decl::ClassTemplatePartialSpecialization:
4512 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4513 return MakeCXCursor(Def, TU);
4514 return clang_getNullCursor();
4515
4516 case Decl::Function:
4517 case Decl::CXXMethod:
4518 case Decl::CXXConstructor:
4519 case Decl::CXXDestructor:
4520 case Decl::CXXConversion: {
4521 const FunctionDecl *Def = 0;
4522 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004523 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004524 return clang_getNullCursor();
4525 }
4526
4527 case Decl::Var: {
4528 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004529 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004530 return MakeCXCursor(Def, TU);
4531 return clang_getNullCursor();
4532 }
4533
4534 case Decl::FunctionTemplate: {
4535 const FunctionDecl *Def = 0;
4536 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4537 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4538 return clang_getNullCursor();
4539 }
4540
4541 case Decl::ClassTemplate: {
4542 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4543 ->getDefinition())
4544 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4545 TU);
4546 return clang_getNullCursor();
4547 }
4548
4549 case Decl::Using:
4550 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4551 D->getLocation(), TU);
4552
4553 case Decl::UsingShadow:
4554 return clang_getCursorDefinition(
4555 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4556 TU));
4557
4558 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004559 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004560 if (Method->isThisDeclarationADefinition())
4561 return C;
4562
4563 // Dig out the method definition in the associated
4564 // @implementation, if we have it.
4565 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004566 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004567 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4568 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4569 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4570 Method->isInstanceMethod()))
4571 if (Def->isThisDeclarationADefinition())
4572 return MakeCXCursor(Def, TU);
4573
4574 return clang_getNullCursor();
4575 }
4576
4577 case Decl::ObjCCategory:
4578 if (ObjCCategoryImplDecl *Impl
4579 = cast<ObjCCategoryDecl>(D)->getImplementation())
4580 return MakeCXCursor(Impl, TU);
4581 return clang_getNullCursor();
4582
4583 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004584 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004585 return MakeCXCursor(Def, TU);
4586 return clang_getNullCursor();
4587
4588 case Decl::ObjCInterface: {
4589 // There are two notions of a "definition" for an Objective-C
4590 // class: the interface and its implementation. When we resolved a
4591 // reference to an Objective-C class, produce the @interface as
4592 // the definition; when we were provided with the interface,
4593 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004594 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004595 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004596 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004597 return MakeCXCursor(Def, TU);
4598 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4599 return MakeCXCursor(Impl, TU);
4600 return clang_getNullCursor();
4601 }
4602
4603 case Decl::ObjCProperty:
4604 // FIXME: We don't really know where to find the
4605 // ObjCPropertyImplDecls that implement this property.
4606 return clang_getNullCursor();
4607
4608 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004609 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004610 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004611 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004612 return MakeCXCursor(Def, TU);
4613
4614 return clang_getNullCursor();
4615
4616 case Decl::Friend:
4617 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4618 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4619 return clang_getNullCursor();
4620
4621 case Decl::FriendTemplate:
4622 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4623 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4624 return clang_getNullCursor();
4625 }
4626
4627 return clang_getNullCursor();
4628}
4629
4630unsigned clang_isCursorDefinition(CXCursor C) {
4631 if (!clang_isDeclaration(C.kind))
4632 return 0;
4633
4634 return clang_getCursorDefinition(C) == C;
4635}
4636
4637CXCursor clang_getCanonicalCursor(CXCursor C) {
4638 if (!clang_isDeclaration(C.kind))
4639 return C;
4640
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004641 if (const Decl *D = getCursorDecl(C)) {
4642 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004643 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4644 return MakeCXCursor(CatD, getCursorTU(C));
4645
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004646 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4647 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004648 return MakeCXCursor(IFD, getCursorTU(C));
4649
4650 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4651 }
4652
4653 return C;
4654}
4655
4656int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4657 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4658}
4659
4660unsigned clang_getNumOverloadedDecls(CXCursor C) {
4661 if (C.kind != CXCursor_OverloadedDeclRef)
4662 return 0;
4663
4664 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004665 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004666 return E->getNumDecls();
4667
4668 if (OverloadedTemplateStorage *S
4669 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4670 return S->size();
4671
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004672 const Decl *D = Storage.get<const Decl *>();
4673 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004674 return Using->shadow_size();
4675
4676 return 0;
4677}
4678
4679CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4680 if (cursor.kind != CXCursor_OverloadedDeclRef)
4681 return clang_getNullCursor();
4682
4683 if (index >= clang_getNumOverloadedDecls(cursor))
4684 return clang_getNullCursor();
4685
4686 CXTranslationUnit TU = getCursorTU(cursor);
4687 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004688 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004689 return MakeCXCursor(E->decls_begin()[index], TU);
4690
4691 if (OverloadedTemplateStorage *S
4692 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4693 return MakeCXCursor(S->begin()[index], TU);
4694
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004695 const Decl *D = Storage.get<const Decl *>();
4696 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004697 // FIXME: This is, unfortunately, linear time.
4698 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4699 std::advance(Pos, index);
4700 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4701 }
4702
4703 return clang_getNullCursor();
4704}
4705
4706void clang_getDefinitionSpellingAndExtent(CXCursor C,
4707 const char **startBuf,
4708 const char **endBuf,
4709 unsigned *startLine,
4710 unsigned *startColumn,
4711 unsigned *endLine,
4712 unsigned *endColumn) {
4713 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004714 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004715 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4716
4717 SourceManager &SM = FD->getASTContext().getSourceManager();
4718 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4719 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4720 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4721 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4722 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4723 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4724}
4725
4726
4727CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4728 unsigned PieceIndex) {
4729 RefNamePieces Pieces;
4730
4731 switch (C.kind) {
4732 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004733 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004734 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4735 E->getQualifierLoc().getSourceRange());
4736 break;
4737
4738 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004739 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004740 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4741 E->getQualifierLoc().getSourceRange(),
4742 E->getOptionalExplicitTemplateArgs());
4743 break;
4744
4745 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004746 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004747 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004748 const Expr *Callee = OCE->getCallee();
4749 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004750 Callee = ICE->getSubExpr();
4751
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004752 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004753 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4754 DRE->getQualifierLoc().getSourceRange());
4755 }
4756 break;
4757
4758 default:
4759 break;
4760 }
4761
4762 if (Pieces.empty()) {
4763 if (PieceIndex == 0)
4764 return clang_getCursorExtent(C);
4765 } else if (PieceIndex < Pieces.size()) {
4766 SourceRange R = Pieces[PieceIndex];
4767 if (R.isValid())
4768 return cxloc::translateSourceRange(getCursorContext(C), R);
4769 }
4770
4771 return clang_getNullRange();
4772}
4773
4774void clang_enableStackTraces(void) {
4775 llvm::sys::PrintStackTraceOnErrorSignal();
4776}
4777
4778void clang_executeOnThread(void (*fn)(void*), void *user_data,
4779 unsigned stack_size) {
4780 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4781}
4782
4783} // end: extern "C"
4784
4785//===----------------------------------------------------------------------===//
4786// Token-based Operations.
4787//===----------------------------------------------------------------------===//
4788
4789/* CXToken layout:
4790 * int_data[0]: a CXTokenKind
4791 * int_data[1]: starting token location
4792 * int_data[2]: token length
4793 * int_data[3]: reserved
4794 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4795 * otherwise unused.
4796 */
4797extern "C" {
4798
4799CXTokenKind clang_getTokenKind(CXToken CXTok) {
4800 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4801}
4802
4803CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4804 switch (clang_getTokenKind(CXTok)) {
4805 case CXToken_Identifier:
4806 case CXToken_Keyword:
4807 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004808 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004809 ->getNameStart());
4810
4811 case CXToken_Literal: {
4812 // We have stashed the starting pointer in the ptr_data field. Use it.
4813 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004814 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004815 }
4816
4817 case CXToken_Punctuation:
4818 case CXToken_Comment:
4819 break;
4820 }
4821
4822 // We have to find the starting buffer pointer the hard way, by
4823 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004824 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004825 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004826 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004827
4828 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4829 std::pair<FileID, unsigned> LocInfo
4830 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4831 bool Invalid = false;
4832 StringRef Buffer
4833 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4834 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004835 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004836
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004837 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004838}
4839
4840CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004841 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004842 if (!CXXUnit)
4843 return clang_getNullLocation();
4844
4845 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4846 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4847}
4848
4849CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004850 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004851 if (!CXXUnit)
4852 return clang_getNullRange();
4853
4854 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4855 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4856}
4857
4858static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4859 SmallVectorImpl<CXToken> &CXTokens) {
4860 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4861 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004862 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004863 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004864 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004865
4866 // Cannot tokenize across files.
4867 if (BeginLocInfo.first != EndLocInfo.first)
4868 return;
4869
4870 // Create a lexer
4871 bool Invalid = false;
4872 StringRef Buffer
4873 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4874 if (Invalid)
4875 return;
4876
4877 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4878 CXXUnit->getASTContext().getLangOpts(),
4879 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4880 Lex.SetCommentRetentionState(true);
4881
4882 // Lex tokens until we hit the end of the range.
4883 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4884 Token Tok;
4885 bool previousWasAt = false;
4886 do {
4887 // Lex the next token
4888 Lex.LexFromRawLexer(Tok);
4889 if (Tok.is(tok::eof))
4890 break;
4891
4892 // Initialize the CXToken.
4893 CXToken CXTok;
4894
4895 // - Common fields
4896 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4897 CXTok.int_data[2] = Tok.getLength();
4898 CXTok.int_data[3] = 0;
4899
4900 // - Kind-specific fields
4901 if (Tok.isLiteral()) {
4902 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004903 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004904 } else if (Tok.is(tok::raw_identifier)) {
4905 // Lookup the identifier to determine whether we have a keyword.
4906 IdentifierInfo *II
4907 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4908
4909 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4910 CXTok.int_data[0] = CXToken_Keyword;
4911 }
4912 else {
4913 CXTok.int_data[0] = Tok.is(tok::identifier)
4914 ? CXToken_Identifier
4915 : CXToken_Keyword;
4916 }
4917 CXTok.ptr_data = II;
4918 } else if (Tok.is(tok::comment)) {
4919 CXTok.int_data[0] = CXToken_Comment;
4920 CXTok.ptr_data = 0;
4921 } else {
4922 CXTok.int_data[0] = CXToken_Punctuation;
4923 CXTok.ptr_data = 0;
4924 }
4925 CXTokens.push_back(CXTok);
4926 previousWasAt = Tok.is(tok::at);
4927 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4928}
4929
4930void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4931 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004932 LOG_FUNC_SECTION {
4933 *Log << TU << ' ' << Range;
4934 }
4935
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004936 if (Tokens)
4937 *Tokens = 0;
4938 if (NumTokens)
4939 *NumTokens = 0;
4940
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004941 if (!TU)
4942 return;
4943
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004944 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004945 if (!CXXUnit || !Tokens || !NumTokens)
4946 return;
4947
4948 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4949
4950 SourceRange R = cxloc::translateCXSourceRange(Range);
4951 if (R.isInvalid())
4952 return;
4953
4954 SmallVector<CXToken, 32> CXTokens;
4955 getTokens(CXXUnit, R, CXTokens);
4956
4957 if (CXTokens.empty())
4958 return;
4959
4960 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4961 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4962 *NumTokens = CXTokens.size();
4963}
4964
4965void clang_disposeTokens(CXTranslationUnit TU,
4966 CXToken *Tokens, unsigned NumTokens) {
4967 free(Tokens);
4968}
4969
4970} // end: extern "C"
4971
4972//===----------------------------------------------------------------------===//
4973// Token annotation APIs.
4974//===----------------------------------------------------------------------===//
4975
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004976static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4977 CXCursor parent,
4978 CXClientData client_data);
4979static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4980 CXClientData client_data);
4981
4982namespace {
4983class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004984 CXToken *Tokens;
4985 CXCursor *Cursors;
4986 unsigned NumTokens;
4987 unsigned TokIdx;
4988 unsigned PreprocessingTokIdx;
4989 CursorVisitor AnnotateVis;
4990 SourceManager &SrcMgr;
4991 bool HasContextSensitiveKeywords;
4992
4993 struct PostChildrenInfo {
4994 CXCursor Cursor;
4995 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004996 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004997 unsigned BeforeChildrenTokenIdx;
4998 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004999 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005000
5001 bool MoreTokens() const { return TokIdx < NumTokens; }
5002 unsigned NextToken() const { return TokIdx; }
5003 void AdvanceToken() { ++TokIdx; }
5004 SourceLocation GetTokenLoc(unsigned tokI) {
5005 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5006 }
5007 bool isFunctionMacroToken(unsigned tokI) const {
5008 return Tokens[tokI].int_data[3] != 0;
5009 }
5010 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5011 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5012 }
5013
5014 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005015 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005016 SourceRange);
5017
5018public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005019 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005020 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005021 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005022 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005023 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005024 AnnotateTokensVisitor, this,
5025 /*VisitPreprocessorLast=*/true,
5026 /*VisitIncludedEntities=*/false,
5027 RegionOfInterest,
5028 /*VisitDeclsOnly=*/false,
5029 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005030 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005031 HasContextSensitiveKeywords(false) { }
5032
5033 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5034 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5035 bool postVisitChildren(CXCursor cursor);
5036 void AnnotateTokens();
5037
5038 /// \brief Determine whether the annotator saw any cursors that have
5039 /// context-sensitive keywords.
5040 bool hasContextSensitiveKeywords() const {
5041 return HasContextSensitiveKeywords;
5042 }
5043
5044 ~AnnotateTokensWorker() {
5045 assert(PostChildrenInfos.empty());
5046 }
5047};
5048}
5049
5050void AnnotateTokensWorker::AnnotateTokens() {
5051 // Walk the AST within the region of interest, annotating tokens
5052 // along the way.
5053 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005054}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005055
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005056static inline void updateCursorAnnotation(CXCursor &Cursor,
5057 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005058 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005059 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005060 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005061}
5062
5063/// \brief It annotates and advances tokens with a cursor until the comparison
5064//// between the cursor location and the source range is the same as
5065/// \arg compResult.
5066///
5067/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5068/// Pass RangeOverlap to annotate tokens inside a range.
5069void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5070 RangeComparisonResult compResult,
5071 SourceRange range) {
5072 while (MoreTokens()) {
5073 const unsigned I = NextToken();
5074 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005075 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5076 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005077
5078 SourceLocation TokLoc = GetTokenLoc(I);
5079 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005080 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005081 AdvanceToken();
5082 continue;
5083 }
5084 break;
5085 }
5086}
5087
5088/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005089/// \returns true if it advanced beyond all macro tokens, false otherwise.
5090bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005091 CXCursor updateC,
5092 RangeComparisonResult compResult,
5093 SourceRange range) {
5094 assert(MoreTokens());
5095 assert(isFunctionMacroToken(NextToken()) &&
5096 "Should be called only for macro arg tokens");
5097
5098 // This works differently than annotateAndAdvanceTokens; because expanded
5099 // macro arguments can have arbitrary translation-unit source order, we do not
5100 // advance the token index one by one until a token fails the range test.
5101 // We only advance once past all of the macro arg tokens if all of them
5102 // pass the range test. If one of them fails we keep the token index pointing
5103 // at the start of the macro arg tokens so that the failing token will be
5104 // annotated by a subsequent annotation try.
5105
5106 bool atLeastOneCompFail = false;
5107
5108 unsigned I = NextToken();
5109 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5110 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5111 if (TokLoc.isFileID())
5112 continue; // not macro arg token, it's parens or comma.
5113 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5114 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5115 Cursors[I] = updateC;
5116 } else
5117 atLeastOneCompFail = true;
5118 }
5119
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005120 if (atLeastOneCompFail)
5121 return false;
5122
5123 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5124 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005125}
5126
5127enum CXChildVisitResult
5128AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005129 SourceRange cursorRange = getRawCursorExtent(cursor);
5130 if (cursorRange.isInvalid())
5131 return CXChildVisit_Recurse;
5132
5133 if (!HasContextSensitiveKeywords) {
5134 // Objective-C properties can have context-sensitive keywords.
5135 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005136 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005137 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5138 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5139 }
5140 // Objective-C methods can have context-sensitive keywords.
5141 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5142 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005143 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005144 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5145 if (Method->getObjCDeclQualifier())
5146 HasContextSensitiveKeywords = true;
5147 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005148 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5149 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005150 P != PEnd; ++P) {
5151 if ((*P)->getObjCDeclQualifier()) {
5152 HasContextSensitiveKeywords = true;
5153 break;
5154 }
5155 }
5156 }
5157 }
5158 }
5159 // C++ methods can have context-sensitive keywords.
5160 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005161 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005162 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5163 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5164 HasContextSensitiveKeywords = true;
5165 }
5166 }
5167 // C++ classes can have context-sensitive keywords.
5168 else if (cursor.kind == CXCursor_StructDecl ||
5169 cursor.kind == CXCursor_ClassDecl ||
5170 cursor.kind == CXCursor_ClassTemplate ||
5171 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005172 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005173 if (D->hasAttr<FinalAttr>())
5174 HasContextSensitiveKeywords = true;
5175 }
5176 }
5177
5178 if (clang_isPreprocessing(cursor.kind)) {
5179 // Items in the preprocessing record are kept separate from items in
5180 // declarations, so we keep a separate token index.
5181 unsigned SavedTokIdx = TokIdx;
5182 TokIdx = PreprocessingTokIdx;
5183
5184 // Skip tokens up until we catch up to the beginning of the preprocessing
5185 // entry.
5186 while (MoreTokens()) {
5187 const unsigned I = NextToken();
5188 SourceLocation TokLoc = GetTokenLoc(I);
5189 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5190 case RangeBefore:
5191 AdvanceToken();
5192 continue;
5193 case RangeAfter:
5194 case RangeOverlap:
5195 break;
5196 }
5197 break;
5198 }
5199
5200 // Look at all of the tokens within this range.
5201 while (MoreTokens()) {
5202 const unsigned I = NextToken();
5203 SourceLocation TokLoc = GetTokenLoc(I);
5204 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5205 case RangeBefore:
5206 llvm_unreachable("Infeasible");
5207 case RangeAfter:
5208 break;
5209 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005210 // For macro expansions, just note where the beginning of the macro
5211 // expansion occurs.
5212 if (cursor.kind == CXCursor_MacroExpansion) {
5213 if (TokLoc == cursorRange.getBegin())
5214 Cursors[I] = cursor;
5215 AdvanceToken();
5216 break;
5217 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005218 // We may have already annotated macro names inside macro definitions.
5219 if (Cursors[I].kind != CXCursor_MacroExpansion)
5220 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005221 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005222 continue;
5223 }
5224 break;
5225 }
5226
5227 // Save the preprocessing token index; restore the non-preprocessing
5228 // token index.
5229 PreprocessingTokIdx = TokIdx;
5230 TokIdx = SavedTokIdx;
5231 return CXChildVisit_Recurse;
5232 }
5233
5234 if (cursorRange.isInvalid())
5235 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005236
5237 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005238 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005239 const enum CXCursorKind K = clang_getCursorKind(parent);
5240 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005241 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5242 // Attributes are annotated out-of-order, skip tokens until we reach it.
5243 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005244 ? clang_getNullCursor() : parent;
5245
5246 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5247
5248 // Avoid having the cursor of an expression "overwrite" the annotation of the
5249 // variable declaration that it belongs to.
5250 // This can happen for C++ constructor expressions whose range generally
5251 // include the variable declaration, e.g.:
5252 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5253 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005254 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005255 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005256 const unsigned I = NextToken();
5257 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5258 E->getLocStart() == D->getLocation() &&
5259 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005260 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005261 AdvanceToken();
5262 }
5263 }
5264 }
5265
5266 // Before recursing into the children keep some state that we are going
5267 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5268 // extra work after the child nodes are visited.
5269 // Note that we don't call VisitChildren here to avoid traversing statements
5270 // code-recursively which can blow the stack.
5271
5272 PostChildrenInfo Info;
5273 Info.Cursor = cursor;
5274 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005275 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005276 Info.BeforeChildrenTokenIdx = NextToken();
5277 PostChildrenInfos.push_back(Info);
5278
5279 return CXChildVisit_Recurse;
5280}
5281
5282bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5283 if (PostChildrenInfos.empty())
5284 return false;
5285 const PostChildrenInfo &Info = PostChildrenInfos.back();
5286 if (!clang_equalCursors(Info.Cursor, cursor))
5287 return false;
5288
5289 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5290 const unsigned AfterChildren = NextToken();
5291 SourceRange cursorRange = Info.CursorRange;
5292
5293 // Scan the tokens that are at the end of the cursor, but are not captured
5294 // but the child cursors.
5295 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5296
5297 // Scan the tokens that are at the beginning of the cursor, but are not
5298 // capture by the child cursors.
5299 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5300 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5301 break;
5302
5303 Cursors[I] = cursor;
5304 }
5305
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005306 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5307 // encountered the attribute cursor.
5308 if (clang_isAttribute(cursor.kind))
5309 TokIdx = Info.BeforeReachingCursorIdx;
5310
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005311 PostChildrenInfos.pop_back();
5312 return false;
5313}
5314
5315static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5316 CXCursor parent,
5317 CXClientData client_data) {
5318 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5319}
5320
5321static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5322 CXClientData client_data) {
5323 return static_cast<AnnotateTokensWorker*>(client_data)->
5324 postVisitChildren(cursor);
5325}
5326
5327namespace {
5328
5329/// \brief Uses the macro expansions in the preprocessing record to find
5330/// and mark tokens that are macro arguments. This info is used by the
5331/// AnnotateTokensWorker.
5332class MarkMacroArgTokensVisitor {
5333 SourceManager &SM;
5334 CXToken *Tokens;
5335 unsigned NumTokens;
5336 unsigned CurIdx;
5337
5338public:
5339 MarkMacroArgTokensVisitor(SourceManager &SM,
5340 CXToken *tokens, unsigned numTokens)
5341 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5342
5343 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5344 if (cursor.kind != CXCursor_MacroExpansion)
5345 return CXChildVisit_Continue;
5346
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005347 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005348 if (macroRange.getBegin() == macroRange.getEnd())
5349 return CXChildVisit_Continue; // it's not a function macro.
5350
5351 for (; CurIdx < NumTokens; ++CurIdx) {
5352 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5353 macroRange.getBegin()))
5354 break;
5355 }
5356
5357 if (CurIdx == NumTokens)
5358 return CXChildVisit_Break;
5359
5360 for (; CurIdx < NumTokens; ++CurIdx) {
5361 SourceLocation tokLoc = getTokenLoc(CurIdx);
5362 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5363 break;
5364
5365 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5366 }
5367
5368 if (CurIdx == NumTokens)
5369 return CXChildVisit_Break;
5370
5371 return CXChildVisit_Continue;
5372 }
5373
5374private:
5375 SourceLocation getTokenLoc(unsigned tokI) {
5376 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5377 }
5378
5379 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5380 // The third field is reserved and currently not used. Use it here
5381 // to mark macro arg expanded tokens with their expanded locations.
5382 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5383 }
5384};
5385
5386} // end anonymous namespace
5387
5388static CXChildVisitResult
5389MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5390 CXClientData client_data) {
5391 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5392 parent);
5393}
5394
5395namespace {
5396 struct clang_annotateTokens_Data {
5397 CXTranslationUnit TU;
5398 ASTUnit *CXXUnit;
5399 CXToken *Tokens;
5400 unsigned NumTokens;
5401 CXCursor *Cursors;
5402 };
5403}
5404
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005405/// \brief Used by \c annotatePreprocessorTokens.
5406/// \returns true if lexing was finished, false otherwise.
5407static bool lexNext(Lexer &Lex, Token &Tok,
5408 unsigned &NextIdx, unsigned NumTokens) {
5409 if (NextIdx >= NumTokens)
5410 return true;
5411
5412 ++NextIdx;
5413 Lex.LexFromRawLexer(Tok);
5414 if (Tok.is(tok::eof))
5415 return true;
5416
5417 return false;
5418}
5419
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005420static void annotatePreprocessorTokens(CXTranslationUnit TU,
5421 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005422 CXCursor *Cursors,
5423 CXToken *Tokens,
5424 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005425 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005426
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005427 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005428 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5429 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005430 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005431 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005432 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005433
5434 if (BeginLocInfo.first != EndLocInfo.first)
5435 return;
5436
5437 StringRef Buffer;
5438 bool Invalid = false;
5439 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5440 if (Buffer.empty() || Invalid)
5441 return;
5442
5443 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5444 CXXUnit->getASTContext().getLangOpts(),
5445 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5446 Buffer.end());
5447 Lex.SetCommentRetentionState(true);
5448
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005449 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005450 // Lex tokens in raw mode until we hit the end of the range, to avoid
5451 // entering #includes or expanding macros.
5452 while (true) {
5453 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005454 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5455 break;
5456 unsigned TokIdx = NextIdx-1;
5457 assert(Tok.getLocation() ==
5458 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005459
5460 reprocess:
5461 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005462 // We have found a preprocessing directive. Annotate the tokens
5463 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005464 //
5465 // FIXME: Some simple tests here could identify macro definitions and
5466 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005467
5468 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005469 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5470 break;
5471
5472 MacroInfo *MI = 0;
5473 if (Tok.is(tok::raw_identifier) &&
5474 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5475 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5476 break;
5477
5478 if (Tok.is(tok::raw_identifier)) {
5479 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5480 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5481 SourceLocation MappedTokLoc =
5482 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5483 MI = getMacroInfo(II, MappedTokLoc, TU);
5484 }
5485 }
5486
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005487 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005488 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005489 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5490 finished = true;
5491 break;
5492 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005493 // If we are in a macro definition, check if the token was ever a
5494 // macro name and annotate it if that's the case.
5495 if (MI) {
5496 SourceLocation SaveLoc = Tok.getLocation();
5497 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5498 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5499 Tok.setLocation(SaveLoc);
5500 if (MacroDef)
5501 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5502 Tok.getLocation(), TU);
5503 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005504 } while (!Tok.isAtStartOfLine());
5505
5506 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5507 assert(TokIdx <= LastIdx);
5508 SourceLocation EndLoc =
5509 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5510 CXCursor Cursor =
5511 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5512
5513 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005514 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005515
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005516 if (finished)
5517 break;
5518 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005519 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005520 }
5521}
5522
5523// This gets run a separate thread to avoid stack blowout.
5524static void clang_annotateTokensImpl(void *UserData) {
5525 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5526 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5527 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5528 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5529 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5530
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005531 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005532 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5533 setThreadBackgroundPriority();
5534
5535 // Determine the region of interest, which contains all of the tokens.
5536 SourceRange RegionOfInterest;
5537 RegionOfInterest.setBegin(
5538 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5539 RegionOfInterest.setEnd(
5540 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5541 Tokens[NumTokens-1])));
5542
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005543 // Relex the tokens within the source range to look for preprocessing
5544 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005545 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005546
5547 // If begin location points inside a macro argument, set it to the expansion
5548 // location so we can have the full context when annotating semantically.
5549 {
5550 SourceManager &SM = CXXUnit->getSourceManager();
5551 SourceLocation Loc =
5552 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5553 if (Loc.isMacroID())
5554 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5555 }
5556
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005557 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5558 // Search and mark tokens that are macro argument expansions.
5559 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5560 Tokens, NumTokens);
5561 CursorVisitor MacroArgMarker(TU,
5562 MarkMacroArgTokensVisitorDelegate, &Visitor,
5563 /*VisitPreprocessorLast=*/true,
5564 /*VisitIncludedEntities=*/false,
5565 RegionOfInterest);
5566 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5567 }
5568
5569 // Annotate all of the source locations in the region of interest that map to
5570 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005571 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005572
5573 // FIXME: We use a ridiculous stack size here because the data-recursion
5574 // algorithm uses a large stack frame than the non-data recursive version,
5575 // and AnnotationTokensWorker currently transforms the data-recursion
5576 // algorithm back into a traditional recursion by explicitly calling
5577 // VisitChildren(). We will need to remove this explicit recursive call.
5578 W.AnnotateTokens();
5579
5580 // If we ran into any entities that involve context-sensitive keywords,
5581 // take another pass through the tokens to mark them as such.
5582 if (W.hasContextSensitiveKeywords()) {
5583 for (unsigned I = 0; I != NumTokens; ++I) {
5584 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5585 continue;
5586
5587 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5588 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005589 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005590 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5591 if (Property->getPropertyAttributesAsWritten() != 0 &&
5592 llvm::StringSwitch<bool>(II->getName())
5593 .Case("readonly", true)
5594 .Case("assign", true)
5595 .Case("unsafe_unretained", true)
5596 .Case("readwrite", true)
5597 .Case("retain", true)
5598 .Case("copy", true)
5599 .Case("nonatomic", true)
5600 .Case("atomic", true)
5601 .Case("getter", true)
5602 .Case("setter", true)
5603 .Case("strong", true)
5604 .Case("weak", true)
5605 .Default(false))
5606 Tokens[I].int_data[0] = CXToken_Keyword;
5607 }
5608 continue;
5609 }
5610
5611 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5612 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5613 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5614 if (llvm::StringSwitch<bool>(II->getName())
5615 .Case("in", true)
5616 .Case("out", true)
5617 .Case("inout", true)
5618 .Case("oneway", true)
5619 .Case("bycopy", true)
5620 .Case("byref", true)
5621 .Default(false))
5622 Tokens[I].int_data[0] = CXToken_Keyword;
5623 continue;
5624 }
5625
5626 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5627 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5628 Tokens[I].int_data[0] = CXToken_Keyword;
5629 continue;
5630 }
5631 }
5632 }
5633}
5634
5635extern "C" {
5636
5637void clang_annotateTokens(CXTranslationUnit TU,
5638 CXToken *Tokens, unsigned NumTokens,
5639 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005640 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005641 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005642 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005643 }
5644
5645 LOG_FUNC_SECTION {
5646 *Log << TU << ' ';
5647 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5648 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5649 *Log << clang_getRange(bloc, eloc);
5650 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005651
5652 // Any token we don't specifically annotate will have a NULL cursor.
5653 CXCursor C = clang_getNullCursor();
5654 for (unsigned I = 0; I != NumTokens; ++I)
5655 Cursors[I] = C;
5656
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005657 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005658 if (!CXXUnit)
5659 return;
5660
5661 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5662
5663 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5664 llvm::CrashRecoveryContext CRC;
5665 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5666 GetSafetyThreadStackSize() * 2)) {
5667 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5668 }
5669}
5670
5671} // end: extern "C"
5672
5673//===----------------------------------------------------------------------===//
5674// Operations for querying linkage of a cursor.
5675//===----------------------------------------------------------------------===//
5676
5677extern "C" {
5678CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5679 if (!clang_isDeclaration(cursor.kind))
5680 return CXLinkage_Invalid;
5681
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005682 const Decl *D = cxcursor::getCursorDecl(cursor);
5683 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005684 switch (ND->getLinkageInternal()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005685 case NoLinkage: return CXLinkage_NoLinkage;
5686 case InternalLinkage: return CXLinkage_Internal;
5687 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5688 case ExternalLinkage: return CXLinkage_External;
5689 };
5690
5691 return CXLinkage_Invalid;
5692}
5693} // end: extern "C"
5694
5695//===----------------------------------------------------------------------===//
5696// Operations for querying language of a cursor.
5697//===----------------------------------------------------------------------===//
5698
5699static CXLanguageKind getDeclLanguage(const Decl *D) {
5700 if (!D)
5701 return CXLanguage_C;
5702
5703 switch (D->getKind()) {
5704 default:
5705 break;
5706 case Decl::ImplicitParam:
5707 case Decl::ObjCAtDefsField:
5708 case Decl::ObjCCategory:
5709 case Decl::ObjCCategoryImpl:
5710 case Decl::ObjCCompatibleAlias:
5711 case Decl::ObjCImplementation:
5712 case Decl::ObjCInterface:
5713 case Decl::ObjCIvar:
5714 case Decl::ObjCMethod:
5715 case Decl::ObjCProperty:
5716 case Decl::ObjCPropertyImpl:
5717 case Decl::ObjCProtocol:
5718 return CXLanguage_ObjC;
5719 case Decl::CXXConstructor:
5720 case Decl::CXXConversion:
5721 case Decl::CXXDestructor:
5722 case Decl::CXXMethod:
5723 case Decl::CXXRecord:
5724 case Decl::ClassTemplate:
5725 case Decl::ClassTemplatePartialSpecialization:
5726 case Decl::ClassTemplateSpecialization:
5727 case Decl::Friend:
5728 case Decl::FriendTemplate:
5729 case Decl::FunctionTemplate:
5730 case Decl::LinkageSpec:
5731 case Decl::Namespace:
5732 case Decl::NamespaceAlias:
5733 case Decl::NonTypeTemplateParm:
5734 case Decl::StaticAssert:
5735 case Decl::TemplateTemplateParm:
5736 case Decl::TemplateTypeParm:
5737 case Decl::UnresolvedUsingTypename:
5738 case Decl::UnresolvedUsingValue:
5739 case Decl::Using:
5740 case Decl::UsingDirective:
5741 case Decl::UsingShadow:
5742 return CXLanguage_CPlusPlus;
5743 }
5744
5745 return CXLanguage_C;
5746}
5747
5748extern "C" {
5749
5750enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5751 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005752 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005753 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5754 return CXAvailability_Available;
5755
5756 switch (D->getAvailability()) {
5757 case AR_Available:
5758 case AR_NotYetIntroduced:
5759 return CXAvailability_Available;
5760
5761 case AR_Deprecated:
5762 return CXAvailability_Deprecated;
5763
5764 case AR_Unavailable:
5765 return CXAvailability_NotAvailable;
5766 }
5767 }
5768
5769 return CXAvailability_Available;
5770}
5771
5772static CXVersion convertVersion(VersionTuple In) {
5773 CXVersion Out = { -1, -1, -1 };
5774 if (In.empty())
5775 return Out;
5776
5777 Out.Major = In.getMajor();
5778
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005779 Optional<unsigned> Minor = In.getMinor();
5780 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005781 Out.Minor = *Minor;
5782 else
5783 return Out;
5784
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005785 Optional<unsigned> Subminor = In.getSubminor();
5786 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005787 Out.Subminor = *Subminor;
5788
5789 return Out;
5790}
5791
5792int clang_getCursorPlatformAvailability(CXCursor cursor,
5793 int *always_deprecated,
5794 CXString *deprecated_message,
5795 int *always_unavailable,
5796 CXString *unavailable_message,
5797 CXPlatformAvailability *availability,
5798 int availability_size) {
5799 if (always_deprecated)
5800 *always_deprecated = 0;
5801 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005802 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005803 if (always_unavailable)
5804 *always_unavailable = 0;
5805 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005806 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005807
5808 if (!clang_isDeclaration(cursor.kind))
5809 return 0;
5810
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005811 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005812 if (!D)
5813 return 0;
5814
5815 int N = 0;
5816 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5817 ++A) {
5818 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5819 if (always_deprecated)
5820 *always_deprecated = 1;
5821 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005822 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005823 continue;
5824 }
5825
5826 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5827 if (always_unavailable)
5828 *always_unavailable = 1;
5829 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005830 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005831 }
5832 continue;
5833 }
5834
5835 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5836 if (N < availability_size) {
5837 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005838 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005839 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5840 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5841 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5842 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005843 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005844 }
5845 ++N;
5846 }
5847 }
5848
5849 return N;
5850}
5851
5852void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5853 clang_disposeString(availability->Platform);
5854 clang_disposeString(availability->Message);
5855}
5856
5857CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5858 if (clang_isDeclaration(cursor.kind))
5859 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5860
5861 return CXLanguage_Invalid;
5862}
5863
5864 /// \brief If the given cursor is the "templated" declaration
5865 /// descibing a class or function template, return the class or
5866 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005867static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005868 if (!D)
5869 return 0;
5870
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005871 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005872 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5873 return FunTmpl;
5874
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005875 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005876 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5877 return ClassTmpl;
5878
5879 return D;
5880}
5881
5882CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5883 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005884 if (const Decl *D = getCursorDecl(cursor)) {
5885 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005886 if (!DC)
5887 return clang_getNullCursor();
5888
5889 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5890 getCursorTU(cursor));
5891 }
5892 }
5893
5894 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005895 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005896 return MakeCXCursor(D, getCursorTU(cursor));
5897 }
5898
5899 return clang_getNullCursor();
5900}
5901
5902CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5903 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005904 if (const Decl *D = getCursorDecl(cursor)) {
5905 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005906 if (!DC)
5907 return clang_getNullCursor();
5908
5909 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5910 getCursorTU(cursor));
5911 }
5912 }
5913
5914 // FIXME: Note that we can't easily compute the lexical context of a
5915 // statement or expression, so we return nothing.
5916 return clang_getNullCursor();
5917}
5918
5919CXFile clang_getIncludedFile(CXCursor cursor) {
5920 if (cursor.kind != CXCursor_InclusionDirective)
5921 return 0;
5922
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005923 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005924 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005925}
5926
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005927unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5928 if (C.kind != CXCursor_ObjCPropertyDecl)
5929 return CXObjCPropertyAttr_noattr;
5930
5931 unsigned Result = CXObjCPropertyAttr_noattr;
5932 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
5933 ObjCPropertyDecl::PropertyAttributeKind Attr =
5934 PD->getPropertyAttributesAsWritten();
5935
5936#define SET_CXOBJCPROP_ATTR(A) \
5937 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
5938 Result |= CXObjCPropertyAttr_##A
5939 SET_CXOBJCPROP_ATTR(readonly);
5940 SET_CXOBJCPROP_ATTR(getter);
5941 SET_CXOBJCPROP_ATTR(assign);
5942 SET_CXOBJCPROP_ATTR(readwrite);
5943 SET_CXOBJCPROP_ATTR(retain);
5944 SET_CXOBJCPROP_ATTR(copy);
5945 SET_CXOBJCPROP_ATTR(nonatomic);
5946 SET_CXOBJCPROP_ATTR(setter);
5947 SET_CXOBJCPROP_ATTR(atomic);
5948 SET_CXOBJCPROP_ATTR(weak);
5949 SET_CXOBJCPROP_ATTR(strong);
5950 SET_CXOBJCPROP_ATTR(unsafe_unretained);
5951#undef SET_CXOBJCPROP_ATTR
5952
5953 return Result;
5954}
5955
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00005956unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
5957 if (!clang_isDeclaration(C.kind))
5958 return CXObjCDeclQualifier_None;
5959
5960 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
5961 const Decl *D = getCursorDecl(C);
5962 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5963 QT = MD->getObjCDeclQualifier();
5964 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
5965 QT = PD->getObjCDeclQualifier();
5966 if (QT == Decl::OBJC_TQ_None)
5967 return CXObjCDeclQualifier_None;
5968
5969 unsigned Result = CXObjCDeclQualifier_None;
5970 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
5971 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
5972 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
5973 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
5974 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
5975 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
5976
5977 return Result;
5978}
5979
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00005980unsigned clang_Cursor_isVariadic(CXCursor C) {
5981 if (!clang_isDeclaration(C.kind))
5982 return 0;
5983
5984 const Decl *D = getCursorDecl(C);
5985 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5986 return FD->isVariadic();
5987 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5988 return MD->isVariadic();
5989
5990 return 0;
5991}
5992
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005993CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5994 if (!clang_isDeclaration(C.kind))
5995 return clang_getNullRange();
5996
5997 const Decl *D = getCursorDecl(C);
5998 ASTContext &Context = getCursorContext(C);
5999 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6000 if (!RC)
6001 return clang_getNullRange();
6002
6003 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6004}
6005
6006CXString clang_Cursor_getRawCommentText(CXCursor C) {
6007 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006008 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006009
6010 const Decl *D = getCursorDecl(C);
6011 ASTContext &Context = getCursorContext(C);
6012 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6013 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6014 StringRef();
6015
6016 // Don't duplicate the string because RawText points directly into source
6017 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006018 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006019}
6020
6021CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6022 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006023 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006024
6025 const Decl *D = getCursorDecl(C);
6026 const ASTContext &Context = getCursorContext(C);
6027 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6028
6029 if (RC) {
6030 StringRef BriefText = RC->getBriefText(Context);
6031
6032 // Don't duplicate the string because RawComment ensures that this memory
6033 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006034 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006035 }
6036
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006037 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006038}
6039
6040CXComment clang_Cursor_getParsedComment(CXCursor C) {
6041 if (!clang_isDeclaration(C.kind))
6042 return cxcomment::createCXComment(NULL, NULL);
6043
6044 const Decl *D = getCursorDecl(C);
6045 const ASTContext &Context = getCursorContext(C);
6046 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6047
6048 return cxcomment::createCXComment(FC, getCursorTU(C));
6049}
6050
6051CXModule clang_Cursor_getModule(CXCursor C) {
6052 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006053 if (const ImportDecl *ImportD =
6054 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006055 return ImportD->getImportedModule();
6056 }
6057
6058 return 0;
6059}
6060
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006061CXFile clang_Module_getASTFile(CXModule CXMod) {
6062 if (!CXMod)
6063 return 0;
6064 Module *Mod = static_cast<Module*>(CXMod);
6065 return const_cast<FileEntry *>(Mod->getASTFile());
6066}
6067
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006068CXModule clang_Module_getParent(CXModule CXMod) {
6069 if (!CXMod)
6070 return 0;
6071 Module *Mod = static_cast<Module*>(CXMod);
6072 return Mod->Parent;
6073}
6074
6075CXString clang_Module_getName(CXModule CXMod) {
6076 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006077 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006078 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006079 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006080}
6081
6082CXString clang_Module_getFullName(CXModule CXMod) {
6083 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006084 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006085 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006086 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006087}
6088
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006089unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6090 CXModule CXMod) {
6091 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006092 return 0;
6093 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006094 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6095 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6096 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006097}
6098
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006099CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6100 CXModule CXMod, unsigned Index) {
6101 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006102 return 0;
6103 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006104 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006105
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006106 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6107 if (Index < TopHeaders.size())
6108 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006109
6110 return 0;
6111}
6112
6113} // end: extern "C"
6114
6115//===----------------------------------------------------------------------===//
6116// C++ AST instrospection.
6117//===----------------------------------------------------------------------===//
6118
6119extern "C" {
6120unsigned clang_CXXMethod_isStatic(CXCursor C) {
6121 if (!clang_isDeclaration(C.kind))
6122 return 0;
6123
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006124 const CXXMethodDecl *Method = 0;
6125 const Decl *D = cxcursor::getCursorDecl(C);
6126 if (const FunctionTemplateDecl *FunTmpl =
6127 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006128 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6129 else
6130 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6131 return (Method && Method->isStatic()) ? 1 : 0;
6132}
6133
6134unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6135 if (!clang_isDeclaration(C.kind))
6136 return 0;
6137
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006138 const CXXMethodDecl *Method = 0;
6139 const Decl *D = cxcursor::getCursorDecl(C);
6140 if (const FunctionTemplateDecl *FunTmpl =
6141 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006142 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6143 else
6144 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6145 return (Method && Method->isVirtual()) ? 1 : 0;
6146}
6147} // end: extern "C"
6148
6149//===----------------------------------------------------------------------===//
6150// Attribute introspection.
6151//===----------------------------------------------------------------------===//
6152
6153extern "C" {
6154CXType clang_getIBOutletCollectionType(CXCursor C) {
6155 if (C.kind != CXCursor_IBOutletCollectionAttr)
6156 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6157
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006158 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006159 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6160
6161 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6162}
6163} // end: extern "C"
6164
6165//===----------------------------------------------------------------------===//
6166// Inspecting memory usage.
6167//===----------------------------------------------------------------------===//
6168
6169typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6170
6171static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6172 enum CXTUResourceUsageKind k,
6173 unsigned long amount) {
6174 CXTUResourceUsageEntry entry = { k, amount };
6175 entries.push_back(entry);
6176}
6177
6178extern "C" {
6179
6180const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6181 const char *str = "";
6182 switch (kind) {
6183 case CXTUResourceUsage_AST:
6184 str = "ASTContext: expressions, declarations, and types";
6185 break;
6186 case CXTUResourceUsage_Identifiers:
6187 str = "ASTContext: identifiers";
6188 break;
6189 case CXTUResourceUsage_Selectors:
6190 str = "ASTContext: selectors";
6191 break;
6192 case CXTUResourceUsage_GlobalCompletionResults:
6193 str = "Code completion: cached global results";
6194 break;
6195 case CXTUResourceUsage_SourceManagerContentCache:
6196 str = "SourceManager: content cache allocator";
6197 break;
6198 case CXTUResourceUsage_AST_SideTables:
6199 str = "ASTContext: side tables";
6200 break;
6201 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6202 str = "SourceManager: malloc'ed memory buffers";
6203 break;
6204 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6205 str = "SourceManager: mmap'ed memory buffers";
6206 break;
6207 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6208 str = "ExternalASTSource: malloc'ed memory buffers";
6209 break;
6210 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6211 str = "ExternalASTSource: mmap'ed memory buffers";
6212 break;
6213 case CXTUResourceUsage_Preprocessor:
6214 str = "Preprocessor: malloc'ed memory";
6215 break;
6216 case CXTUResourceUsage_PreprocessingRecord:
6217 str = "Preprocessor: PreprocessingRecord";
6218 break;
6219 case CXTUResourceUsage_SourceManager_DataStructures:
6220 str = "SourceManager: data structures and tables";
6221 break;
6222 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6223 str = "Preprocessor: header search tables";
6224 break;
6225 }
6226 return str;
6227}
6228
6229CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6230 if (!TU) {
6231 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6232 return usage;
6233 }
6234
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006235 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006236 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6237 ASTContext &astContext = astUnit->getASTContext();
6238
6239 // How much memory is used by AST nodes and types?
6240 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6241 (unsigned long) astContext.getASTAllocatedMemory());
6242
6243 // How much memory is used by identifiers?
6244 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6245 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6246
6247 // How much memory is used for selectors?
6248 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6249 (unsigned long) astContext.Selectors.getTotalMemory());
6250
6251 // How much memory is used by ASTContext's side tables?
6252 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6253 (unsigned long) astContext.getSideTableAllocatedMemory());
6254
6255 // How much memory is used for caching global code completion results?
6256 unsigned long completionBytes = 0;
6257 if (GlobalCodeCompletionAllocator *completionAllocator =
6258 astUnit->getCachedCompletionAllocator().getPtr()) {
6259 completionBytes = completionAllocator->getTotalMemory();
6260 }
6261 createCXTUResourceUsageEntry(*entries,
6262 CXTUResourceUsage_GlobalCompletionResults,
6263 completionBytes);
6264
6265 // How much memory is being used by SourceManager's content cache?
6266 createCXTUResourceUsageEntry(*entries,
6267 CXTUResourceUsage_SourceManagerContentCache,
6268 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6269
6270 // How much memory is being used by the MemoryBuffer's in SourceManager?
6271 const SourceManager::MemoryBufferSizes &srcBufs =
6272 astUnit->getSourceManager().getMemoryBufferSizes();
6273
6274 createCXTUResourceUsageEntry(*entries,
6275 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6276 (unsigned long) srcBufs.malloc_bytes);
6277 createCXTUResourceUsageEntry(*entries,
6278 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6279 (unsigned long) srcBufs.mmap_bytes);
6280 createCXTUResourceUsageEntry(*entries,
6281 CXTUResourceUsage_SourceManager_DataStructures,
6282 (unsigned long) astContext.getSourceManager()
6283 .getDataStructureSizes());
6284
6285 // How much memory is being used by the ExternalASTSource?
6286 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6287 const ExternalASTSource::MemoryBufferSizes &sizes =
6288 esrc->getMemoryBufferSizes();
6289
6290 createCXTUResourceUsageEntry(*entries,
6291 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6292 (unsigned long) sizes.malloc_bytes);
6293 createCXTUResourceUsageEntry(*entries,
6294 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6295 (unsigned long) sizes.mmap_bytes);
6296 }
6297
6298 // How much memory is being used by the Preprocessor?
6299 Preprocessor &pp = astUnit->getPreprocessor();
6300 createCXTUResourceUsageEntry(*entries,
6301 CXTUResourceUsage_Preprocessor,
6302 pp.getTotalMemory());
6303
6304 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6305 createCXTUResourceUsageEntry(*entries,
6306 CXTUResourceUsage_PreprocessingRecord,
6307 pRec->getTotalMemory());
6308 }
6309
6310 createCXTUResourceUsageEntry(*entries,
6311 CXTUResourceUsage_Preprocessor_HeaderSearch,
6312 pp.getHeaderSearchInfo().getTotalMemory());
6313
6314 CXTUResourceUsage usage = { (void*) entries.get(),
6315 (unsigned) entries->size(),
6316 entries->size() ? &(*entries)[0] : 0 };
6317 entries.take();
6318 return usage;
6319}
6320
6321void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6322 if (usage.data)
6323 delete (MemUsageEntries*) usage.data;
6324}
6325
6326} // end extern "C"
6327
6328void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6329 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6330 for (unsigned I = 0; I != Usage.numEntries; ++I)
6331 fprintf(stderr, " %s: %lu\n",
6332 clang_getTUResourceUsageName(Usage.entries[I].kind),
6333 Usage.entries[I].amount);
6334
6335 clang_disposeCXTUResourceUsage(Usage);
6336}
6337
6338//===----------------------------------------------------------------------===//
6339// Misc. utility functions.
6340//===----------------------------------------------------------------------===//
6341
6342/// Default to using an 8 MB stack size on "safety" threads.
6343static unsigned SafetyStackThreadSize = 8 << 20;
6344
6345namespace clang {
6346
6347bool RunSafely(llvm::CrashRecoveryContext &CRC,
6348 void (*Fn)(void*), void *UserData,
6349 unsigned Size) {
6350 if (!Size)
6351 Size = GetSafetyThreadStackSize();
6352 if (Size)
6353 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6354 return CRC.RunSafely(Fn, UserData);
6355}
6356
6357unsigned GetSafetyThreadStackSize() {
6358 return SafetyStackThreadSize;
6359}
6360
6361void SetSafetyThreadStackSize(unsigned Value) {
6362 SafetyStackThreadSize = Value;
6363}
6364
6365}
6366
6367void clang::setThreadBackgroundPriority() {
6368 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6369 return;
6370
6371 // FIXME: Move to llvm/Support and make it cross-platform.
6372#ifdef __APPLE__
6373 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6374#endif
6375}
6376
6377void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6378 if (!Unit)
6379 return;
6380
6381 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6382 DEnd = Unit->stored_diag_end();
6383 D != DEnd; ++D) {
6384 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6385 CXString Msg = clang_formatDiagnostic(&Diag,
6386 clang_defaultDiagnosticDisplayOptions());
6387 fprintf(stderr, "%s\n", clang_getCString(Msg));
6388 clang_disposeString(Msg);
6389 }
6390#ifdef LLVM_ON_WIN32
6391 // On Windows, force a flush, since there may be multiple copies of
6392 // stderr and stdout in the file system, all with different buffers
6393 // but writing to the same device.
6394 fflush(stderr);
6395#endif
6396}
6397
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006398MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6399 SourceLocation MacroDefLoc,
6400 CXTranslationUnit TU){
6401 if (MacroDefLoc.isInvalid() || !TU)
6402 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006403 if (!II.hadMacroDefinition())
6404 return 0;
6405
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006406 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006407 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006408 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006409 if (MD) {
6410 for (MacroDirective::DefInfo
6411 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6412 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6413 return Def.getMacroInfo();
6414 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006415 }
6416
6417 return 0;
6418}
6419
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006420const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6421 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006422 if (!MacroDef || !TU)
6423 return 0;
6424 const IdentifierInfo *II = MacroDef->getName();
6425 if (!II)
6426 return 0;
6427
6428 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6429}
6430
6431MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6432 const Token &Tok,
6433 CXTranslationUnit TU) {
6434 if (!MI || !TU)
6435 return 0;
6436 if (Tok.isNot(tok::raw_identifier))
6437 return 0;
6438
6439 if (MI->getNumTokens() == 0)
6440 return 0;
6441 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6442 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006443 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006444
6445 // Check that the token is inside the definition and not its argument list.
6446 SourceManager &SM = Unit->getSourceManager();
6447 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6448 return 0;
6449 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6450 return 0;
6451
6452 Preprocessor &PP = Unit->getPreprocessor();
6453 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6454 if (!PPRec)
6455 return 0;
6456
6457 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6458 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6459 if (!II.hadMacroDefinition())
6460 return 0;
6461
6462 // Check that the identifier is not one of the macro arguments.
6463 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6464 return 0;
6465
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006466 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6467 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006468 return 0;
6469
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006470 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006471}
6472
6473MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6474 SourceLocation Loc,
6475 CXTranslationUnit TU) {
6476 if (Loc.isInvalid() || !MI || !TU)
6477 return 0;
6478
6479 if (MI->getNumTokens() == 0)
6480 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006481 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006482 Preprocessor &PP = Unit->getPreprocessor();
6483 if (!PP.getPreprocessingRecord())
6484 return 0;
6485 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6486 Token Tok;
6487 if (PP.getRawToken(Loc, Tok))
6488 return 0;
6489
6490 return checkForMacroInMacroDefinition(MI, Tok, TU);
6491}
6492
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006493extern "C" {
6494
6495CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006496 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006497}
6498
6499} // end: extern "C"
6500
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006501Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6502 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006503 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006504 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006505 if (Unit->isMainFileAST())
6506 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006507 return *this;
6508 }
6509 }
6510
6511 LogOS << "<NULL TU>";
6512 return *this;
6513}
6514
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006515Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6516 *this << FE->getName();
6517 return *this;
6518}
6519
6520Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6521 CXString cursorName = clang_getCursorDisplayName(cursor);
6522 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6523 clang_disposeString(cursorName);
6524 return *this;
6525}
6526
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006527Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6528 CXFile File;
6529 unsigned Line, Column;
6530 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6531 CXString FileName = clang_getFileName(File);
6532 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6533 clang_disposeString(FileName);
6534 return *this;
6535}
6536
6537Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6538 CXSourceLocation BLoc = clang_getRangeStart(range);
6539 CXSourceLocation ELoc = clang_getRangeEnd(range);
6540
6541 CXFile BFile;
6542 unsigned BLine, BColumn;
6543 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6544
6545 CXFile EFile;
6546 unsigned ELine, EColumn;
6547 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6548
6549 CXString BFileName = clang_getFileName(BFile);
6550 if (BFile == EFile) {
6551 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6552 BLine, BColumn, ELine, EColumn);
6553 } else {
6554 CXString EFileName = clang_getFileName(EFile);
6555 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6556 BLine, BColumn)
6557 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6558 ELine, EColumn);
6559 clang_disposeString(EFileName);
6560 }
6561 clang_disposeString(BFileName);
6562 return *this;
6563}
6564
6565Logger &cxindex::Logger::operator<<(CXString Str) {
6566 *this << clang_getCString(Str);
6567 return *this;
6568}
6569
6570Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6571 LogOS << Fmt;
6572 return *this;
6573}
6574
6575cxindex::Logger::~Logger() {
6576 LogOS.flush();
6577
6578 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6579
6580 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6581
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006582 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006583 OS << "[libclang:" << Name << ':';
6584
6585 // FIXME: Portability.
6586#if HAVE_PTHREAD_H && __APPLE__
6587 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6588 OS << tid << ':';
6589#endif
6590
6591 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6592 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6593 OS << Msg.str() << '\n';
6594
6595 if (Trace) {
6596 llvm::sys::PrintStackTrace(stderr);
6597 OS << "--------------------------------------------------\n";
6598 }
6599}