blob: bd20800993b8d770eadf262806f5a8ea311f5018 [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) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002369 // FIXME: Lambda init-captures.
2370 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002371 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002372
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002373 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2374 C->getLocation(),
2375 TU)))
2376 return true;
2377 }
2378
2379 // Visit parameters and return type, if present.
2380 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2381 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2382 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2383 // Visit the whole type.
2384 if (Visit(TL))
2385 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002386 } else if (FunctionProtoTypeLoc Proto =
2387 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002388 if (E->hasExplicitParameters()) {
2389 // Visit parameters.
2390 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2391 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2392 return true;
2393 } else {
2394 // Visit result type.
2395 if (Visit(Proto.getResultLoc()))
2396 return true;
2397 }
2398 }
2399 }
2400 break;
2401 }
2402
2403 case VisitorJob::PostChildrenVisitKind:
2404 if (PostChildrenVisitor(Parent, ClientData))
2405 return true;
2406 break;
2407 }
2408 }
2409 return false;
2410}
2411
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002412bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002413 VisitorWorkList *WL = 0;
2414 if (!WorkListFreeList.empty()) {
2415 WL = WorkListFreeList.back();
2416 WL->clear();
2417 WorkListFreeList.pop_back();
2418 }
2419 else {
2420 WL = new VisitorWorkList();
2421 WorkListCache.push_back(WL);
2422 }
2423 EnqueueWorkList(*WL, S);
2424 bool result = RunVisitorWorkList(*WL);
2425 WorkListFreeList.push_back(WL);
2426 return result;
2427}
2428
2429namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002430typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002431RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2432 const DeclarationNameInfo &NI,
2433 const SourceRange &QLoc,
2434 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2435 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2436 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2437 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2438
2439 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2440
2441 RefNamePieces Pieces;
2442
2443 if (WantQualifier && QLoc.isValid())
2444 Pieces.push_back(QLoc);
2445
2446 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2447 Pieces.push_back(NI.getLoc());
2448
2449 if (WantTemplateArgs && TemplateArgs)
2450 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2451 TemplateArgs->RAngleLoc));
2452
2453 if (Kind == DeclarationName::CXXOperatorName) {
2454 Pieces.push_back(SourceLocation::getFromRawEncoding(
2455 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2456 Pieces.push_back(SourceLocation::getFromRawEncoding(
2457 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2458 }
2459
2460 if (WantSinglePiece) {
2461 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2462 Pieces.clear();
2463 Pieces.push_back(R);
2464 }
2465
2466 return Pieces;
2467}
2468}
2469
2470//===----------------------------------------------------------------------===//
2471// Misc. API hooks.
2472//===----------------------------------------------------------------------===//
2473
2474static llvm::sys::Mutex EnableMultithreadingMutex;
2475static bool EnabledMultithreading;
2476
Chad Rosier90836282013-03-27 18:28:23 +00002477static void fatal_error_handler(void *user_data, const std::string& reason,
2478 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002479 // Write the result out to stderr avoiding errs() because raw_ostreams can
2480 // call report_fatal_error.
2481 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2482 ::abort();
2483}
2484
2485extern "C" {
2486CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2487 int displayDiagnostics) {
2488 // Disable pretty stack trace functionality, which will otherwise be a very
2489 // poor citizen of the world and set up all sorts of signal handlers.
2490 llvm::DisablePrettyStackTrace = true;
2491
2492 // We use crash recovery to make some of our APIs more reliable, implicitly
2493 // enable it.
2494 llvm::CrashRecoveryContext::Enable();
2495
2496 // Enable support for multithreading in LLVM.
2497 {
2498 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2499 if (!EnabledMultithreading) {
2500 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2501 llvm::llvm_start_multithreaded();
2502 EnabledMultithreading = true;
2503 }
2504 }
2505
2506 CIndexer *CIdxr = new CIndexer();
2507 if (excludeDeclarationsFromPCH)
2508 CIdxr->setOnlyLocalDecls();
2509 if (displayDiagnostics)
2510 CIdxr->setDisplayDiagnostics();
2511
2512 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2513 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2514 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2515 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2516 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2517 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2518
2519 return CIdxr;
2520}
2521
2522void clang_disposeIndex(CXIndex CIdx) {
2523 if (CIdx)
2524 delete static_cast<CIndexer *>(CIdx);
2525}
2526
2527void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2528 if (CIdx)
2529 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2530}
2531
2532unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2533 if (CIdx)
2534 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2535 return 0;
2536}
2537
2538void clang_toggleCrashRecovery(unsigned isEnabled) {
2539 if (isEnabled)
2540 llvm::CrashRecoveryContext::Enable();
2541 else
2542 llvm::CrashRecoveryContext::Disable();
2543}
2544
2545CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2546 const char *ast_filename) {
2547 if (!CIdx)
2548 return 0;
2549
2550 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2551 FileSystemOptions FileSystemOpts;
2552
2553 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2554 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2555 CXXIdx->getOnlyLocalDecls(),
2556 0, 0,
2557 /*CaptureDiagnostics=*/true,
2558 /*AllowPCHWithCompilerErrors=*/true,
2559 /*UserFilesAreVolatile=*/true);
2560 return MakeCXTranslationUnit(CXXIdx, TU);
2561}
2562
2563unsigned clang_defaultEditingTranslationUnitOptions() {
2564 return CXTranslationUnit_PrecompiledPreamble |
2565 CXTranslationUnit_CacheCompletionResults;
2566}
2567
2568CXTranslationUnit
2569clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2570 const char *source_filename,
2571 int num_command_line_args,
2572 const char * const *command_line_args,
2573 unsigned num_unsaved_files,
2574 struct CXUnsavedFile *unsaved_files) {
2575 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2576 return clang_parseTranslationUnit(CIdx, source_filename,
2577 command_line_args, num_command_line_args,
2578 unsaved_files, num_unsaved_files,
2579 Options);
2580}
2581
2582struct ParseTranslationUnitInfo {
2583 CXIndex CIdx;
2584 const char *source_filename;
2585 const char *const *command_line_args;
2586 int num_command_line_args;
2587 struct CXUnsavedFile *unsaved_files;
2588 unsigned num_unsaved_files;
2589 unsigned options;
2590 CXTranslationUnit result;
2591};
2592static void clang_parseTranslationUnit_Impl(void *UserData) {
2593 ParseTranslationUnitInfo *PTUI =
2594 static_cast<ParseTranslationUnitInfo*>(UserData);
2595 CXIndex CIdx = PTUI->CIdx;
2596 const char *source_filename = PTUI->source_filename;
2597 const char * const *command_line_args = PTUI->command_line_args;
2598 int num_command_line_args = PTUI->num_command_line_args;
2599 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2600 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2601 unsigned options = PTUI->options;
2602 PTUI->result = 0;
2603
2604 if (!CIdx)
2605 return;
2606
2607 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2608
2609 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2610 setThreadBackgroundPriority();
2611
2612 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2613 // FIXME: Add a flag for modules.
2614 TranslationUnitKind TUKind
2615 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2616 bool CacheCodeCompetionResults
2617 = options & CXTranslationUnit_CacheCompletionResults;
2618 bool IncludeBriefCommentsInCodeCompletion
2619 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2620 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2621 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2622
2623 // Configure the diagnostics.
2624 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002625 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002626
2627 // Recover resources if we crash before exiting this function.
2628 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2629 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2630 DiagCleanup(Diags.getPtr());
2631
2632 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2633 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2634
2635 // Recover resources if we crash before exiting this function.
2636 llvm::CrashRecoveryContextCleanupRegistrar<
2637 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2638
2639 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2640 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2641 const llvm::MemoryBuffer *Buffer
2642 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2643 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2644 Buffer));
2645 }
2646
2647 OwningPtr<std::vector<const char *> >
2648 Args(new std::vector<const char*>());
2649
2650 // Recover resources if we crash before exiting this method.
2651 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2652 ArgsCleanup(Args.get());
2653
2654 // Since the Clang C library is primarily used by batch tools dealing with
2655 // (often very broken) source code, where spell-checking can have a
2656 // significant negative impact on performance (particularly when
2657 // precompiled headers are involved), we disable it by default.
2658 // Only do this if we haven't found a spell-checking-related argument.
2659 bool FoundSpellCheckingArgument = false;
2660 for (int I = 0; I != num_command_line_args; ++I) {
2661 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2662 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2663 FoundSpellCheckingArgument = true;
2664 break;
2665 }
2666 }
2667 if (!FoundSpellCheckingArgument)
2668 Args->push_back("-fno-spell-checking");
2669
2670 Args->insert(Args->end(), command_line_args,
2671 command_line_args + num_command_line_args);
2672
2673 // The 'source_filename' argument is optional. If the caller does not
2674 // specify it then it is assumed that the source file is specified
2675 // in the actual argument list.
2676 // Put the source file after command_line_args otherwise if '-x' flag is
2677 // present it will be unused.
2678 if (source_filename)
2679 Args->push_back(source_filename);
2680
2681 // Do we need the detailed preprocessing record?
2682 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2683 Args->push_back("-Xclang");
2684 Args->push_back("-detailed-preprocessing-record");
2685 }
2686
2687 unsigned NumErrors = Diags->getClient()->getNumErrors();
2688 OwningPtr<ASTUnit> ErrUnit;
2689 OwningPtr<ASTUnit> Unit(
2690 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2691 /* vector::data() not portable */,
2692 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2693 Diags,
2694 CXXIdx->getClangResourcesPath(),
2695 CXXIdx->getOnlyLocalDecls(),
2696 /*CaptureDiagnostics=*/true,
2697 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2698 RemappedFiles->size(),
2699 /*RemappedFilesKeepOriginalName=*/true,
2700 PrecompilePreamble,
2701 TUKind,
2702 CacheCodeCompetionResults,
2703 IncludeBriefCommentsInCodeCompletion,
2704 /*AllowPCHWithCompilerErrors=*/true,
2705 SkipFunctionBodies,
2706 /*UserFilesAreVolatile=*/true,
2707 ForSerialization,
2708 &ErrUnit));
2709
2710 if (NumErrors != Diags->getClient()->getNumErrors()) {
2711 // Make sure to check that 'Unit' is non-NULL.
2712 if (CXXIdx->getDisplayDiagnostics())
2713 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2714 }
2715
2716 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2717}
2718CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2719 const char *source_filename,
2720 const char * const *command_line_args,
2721 int num_command_line_args,
2722 struct CXUnsavedFile *unsaved_files,
2723 unsigned num_unsaved_files,
2724 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002725 LOG_FUNC_SECTION {
2726 *Log << source_filename << ": ";
2727 for (int i = 0; i != num_command_line_args; ++i)
2728 *Log << command_line_args[i] << " ";
2729 }
2730
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002731 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2732 num_command_line_args, unsaved_files,
2733 num_unsaved_files, options, 0 };
2734 llvm::CrashRecoveryContext CRC;
2735
2736 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2737 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2738 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2739 fprintf(stderr, " 'command_line_args' : [");
2740 for (int i = 0; i != num_command_line_args; ++i) {
2741 if (i)
2742 fprintf(stderr, ", ");
2743 fprintf(stderr, "'%s'", command_line_args[i]);
2744 }
2745 fprintf(stderr, "],\n");
2746 fprintf(stderr, " 'unsaved_files' : [");
2747 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2748 if (i)
2749 fprintf(stderr, ", ");
2750 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2751 unsaved_files[i].Length);
2752 }
2753 fprintf(stderr, "],\n");
2754 fprintf(stderr, " 'options' : %d,\n", options);
2755 fprintf(stderr, "}\n");
2756
2757 return 0;
2758 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2759 PrintLibclangResourceUsage(PTUI.result);
2760 }
2761
2762 return PTUI.result;
2763}
2764
2765unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2766 return CXSaveTranslationUnit_None;
2767}
2768
2769namespace {
2770
2771struct SaveTranslationUnitInfo {
2772 CXTranslationUnit TU;
2773 const char *FileName;
2774 unsigned options;
2775 CXSaveError result;
2776};
2777
2778}
2779
2780static void clang_saveTranslationUnit_Impl(void *UserData) {
2781 SaveTranslationUnitInfo *STUI =
2782 static_cast<SaveTranslationUnitInfo*>(UserData);
2783
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002784 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002785 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2786 setThreadBackgroundPriority();
2787
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002788 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002789 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2790}
2791
2792int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2793 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002794 LOG_FUNC_SECTION {
2795 *Log << TU << ' ' << FileName;
2796 }
2797
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002798 if (!TU)
2799 return CXSaveError_InvalidTU;
2800
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002801 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002802 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2803 if (!CXXUnit->hasSema())
2804 return CXSaveError_InvalidTU;
2805
2806 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2807
2808 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2809 getenv("LIBCLANG_NOTHREADS")) {
2810 clang_saveTranslationUnit_Impl(&STUI);
2811
2812 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2813 PrintLibclangResourceUsage(TU);
2814
2815 return STUI.result;
2816 }
2817
2818 // We have an AST that has invalid nodes due to compiler errors.
2819 // Use a crash recovery thread for protection.
2820
2821 llvm::CrashRecoveryContext CRC;
2822
2823 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2824 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2825 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2826 fprintf(stderr, " 'options' : %d,\n", options);
2827 fprintf(stderr, "}\n");
2828
2829 return CXSaveError_Unknown;
2830
2831 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2832 PrintLibclangResourceUsage(TU);
2833 }
2834
2835 return STUI.result;
2836}
2837
2838void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2839 if (CTUnit) {
2840 // If the translation unit has been marked as unsafe to free, just discard
2841 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002842 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002843 return;
2844
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002845 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002846 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002847 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2848 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002849 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002850 delete CTUnit;
2851 }
2852}
2853
2854unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2855 return CXReparse_None;
2856}
2857
2858struct ReparseTranslationUnitInfo {
2859 CXTranslationUnit TU;
2860 unsigned num_unsaved_files;
2861 struct CXUnsavedFile *unsaved_files;
2862 unsigned options;
2863 int result;
2864};
2865
2866static void clang_reparseTranslationUnit_Impl(void *UserData) {
2867 ReparseTranslationUnitInfo *RTUI =
2868 static_cast<ReparseTranslationUnitInfo*>(UserData);
2869 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002870 if (!TU)
2871 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002872
2873 // Reset the associated diagnostics.
2874 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2875 TU->Diagnostics = 0;
2876
2877 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2878 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2879 unsigned options = RTUI->options;
2880 (void) options;
2881 RTUI->result = 1;
2882
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002883 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002884 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2885 setThreadBackgroundPriority();
2886
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002887 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002888 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2889
2890 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2891 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2892
2893 // Recover resources if we crash before exiting this function.
2894 llvm::CrashRecoveryContextCleanupRegistrar<
2895 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2896
2897 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2898 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2899 const llvm::MemoryBuffer *Buffer
2900 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2901 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2902 Buffer));
2903 }
2904
2905 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2906 RemappedFiles->size()))
2907 RTUI->result = 0;
2908}
2909
2910int clang_reparseTranslationUnit(CXTranslationUnit TU,
2911 unsigned num_unsaved_files,
2912 struct CXUnsavedFile *unsaved_files,
2913 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002914 LOG_FUNC_SECTION {
2915 *Log << TU;
2916 }
2917
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002918 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2919 options, 0 };
2920
2921 if (getenv("LIBCLANG_NOTHREADS")) {
2922 clang_reparseTranslationUnit_Impl(&RTUI);
2923 return RTUI.result;
2924 }
2925
2926 llvm::CrashRecoveryContext CRC;
2927
2928 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2929 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002930 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002931 return 1;
2932 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2933 PrintLibclangResourceUsage(TU);
2934
2935 return RTUI.result;
2936}
2937
2938
2939CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2940 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002941 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002942
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002943 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002944 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002945}
2946
2947CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00002948 if (!TU)
2949 return clang_getNullCursor();
2950
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002951 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002952 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2953}
2954
2955} // end: extern "C"
2956
2957//===----------------------------------------------------------------------===//
2958// CXFile Operations.
2959//===----------------------------------------------------------------------===//
2960
2961extern "C" {
2962CXString clang_getFileName(CXFile SFile) {
2963 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002964 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002965
2966 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002967 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002968}
2969
2970time_t clang_getFileTime(CXFile SFile) {
2971 if (!SFile)
2972 return 0;
2973
2974 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2975 return FEnt->getModificationTime();
2976}
2977
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002978CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2979 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002980 return 0;
2981
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002982 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002983
2984 FileManager &FMgr = CXXUnit->getFileManager();
2985 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2986}
2987
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002988unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2989 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002990 return 0;
2991
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002992 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002993 FileEntry *FEnt = static_cast<FileEntry *>(file);
2994 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2995 .isFileMultipleIncludeGuarded(FEnt);
2996}
2997
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002998int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2999 if (!file || !outID)
3000 return 1;
3001
3002#ifdef LLVM_ON_WIN32
3003 return 1; // inodes not supported on windows.
3004#else
3005 FileEntry *FEnt = static_cast<FileEntry *>(file);
3006 outID->data[0] = FEnt->getDevice();
3007 outID->data[1] = FEnt->getInode();
3008 outID->data[2] = FEnt->getModificationTime();
3009 return 0;
3010#endif
3011}
3012
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003013} // end: extern "C"
3014
3015//===----------------------------------------------------------------------===//
3016// CXCursor Operations.
3017//===----------------------------------------------------------------------===//
3018
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003019static const Decl *getDeclFromExpr(const Stmt *E) {
3020 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003021 return getDeclFromExpr(CE->getSubExpr());
3022
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003023 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003024 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003025 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003026 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003027 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003028 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003029 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003030 if (PRE->isExplicitProperty())
3031 return PRE->getExplicitProperty();
3032 // It could be messaging both getter and setter as in:
3033 // ++myobj.myprop;
3034 // in which case prefer to associate the setter since it is less obvious
3035 // from inspecting the source that the setter is going to get called.
3036 if (PRE->isMessagingSetter())
3037 return PRE->getImplicitPropertySetter();
3038 return PRE->getImplicitPropertyGetter();
3039 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003040 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003041 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003042 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003043 if (Expr *Src = OVE->getSourceExpr())
3044 return getDeclFromExpr(Src);
3045
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003046 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003047 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003048 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003049 if (!CE->isElidable())
3050 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003051 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003052 return OME->getMethodDecl();
3053
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003054 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003055 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003056 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003057 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3058 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003059 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003060 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3061 isa<ParmVarDecl>(SizeOfPack->getPack()))
3062 return SizeOfPack->getPack();
3063
3064 return 0;
3065}
3066
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003067static SourceLocation getLocationFromExpr(const Expr *E) {
3068 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003069 return getLocationFromExpr(CE->getSubExpr());
3070
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003071 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003072 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003073 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003074 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003075 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003076 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003077 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003078 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003079 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003080 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003081 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003082 return PropRef->getLocation();
3083
3084 return E->getLocStart();
3085}
3086
3087extern "C" {
3088
3089unsigned clang_visitChildren(CXCursor parent,
3090 CXCursorVisitor visitor,
3091 CXClientData client_data) {
3092 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3093 /*VisitPreprocessorLast=*/false);
3094 return CursorVis.VisitChildren(parent);
3095}
3096
3097#ifndef __has_feature
3098#define __has_feature(x) 0
3099#endif
3100#if __has_feature(blocks)
3101typedef enum CXChildVisitResult
3102 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3103
3104static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3105 CXClientData client_data) {
3106 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3107 return block(cursor, parent);
3108}
3109#else
3110// If we are compiled with a compiler that doesn't have native blocks support,
3111// define and call the block manually, so the
3112typedef struct _CXChildVisitResult
3113{
3114 void *isa;
3115 int flags;
3116 int reserved;
3117 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3118 CXCursor);
3119} *CXCursorVisitorBlock;
3120
3121static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3122 CXClientData client_data) {
3123 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3124 return block->invoke(block, cursor, parent);
3125}
3126#endif
3127
3128
3129unsigned clang_visitChildrenWithBlock(CXCursor parent,
3130 CXCursorVisitorBlock block) {
3131 return clang_visitChildren(parent, visitWithBlock, block);
3132}
3133
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003134static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003136 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003137
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003138 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003139 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003140 if (const ObjCPropertyImplDecl *PropImpl =
3141 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003142 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003143 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003144
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003145 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003146 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003147 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003148
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003149 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003150 }
3151
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003152 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003153 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003154
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003155 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003156 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3157 // and returns different names. NamedDecl returns the class name and
3158 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003159 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003160
3161 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003162 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003163
3164 SmallString<1024> S;
3165 llvm::raw_svector_ostream os(S);
3166 ND->printName(os);
3167
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003168 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003169}
3170
3171CXString clang_getCursorSpelling(CXCursor C) {
3172 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003173 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003174
3175 if (clang_isReference(C.kind)) {
3176 switch (C.kind) {
3177 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003178 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003179 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003180 }
3181 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003182 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003183 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003184 }
3185 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003186 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003187 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003188 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003189 }
3190 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003191 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003192 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003193 }
3194 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003195 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003196 assert(Type && "Missing type decl");
3197
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003198 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 getAsString());
3200 }
3201 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003202 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203 assert(Template && "Missing template decl");
3204
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003205 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003206 }
3207
3208 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003209 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003210 assert(NS && "Missing namespace decl");
3211
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003212 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003213 }
3214
3215 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003216 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003217 assert(Field && "Missing member decl");
3218
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003219 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003220 }
3221
3222 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003223 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003224 assert(Label && "Missing label");
3225
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003226 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003227 }
3228
3229 case CXCursor_OverloadedDeclRef: {
3230 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003231 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3232 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003233 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003234 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003235 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003236 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003237 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003238 OverloadedTemplateStorage *Ovl
3239 = Storage.get<OverloadedTemplateStorage*>();
3240 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003241 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003242 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003243 }
3244
3245 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003246 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003247 assert(Var && "Missing variable decl");
3248
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003249 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003250 }
3251
3252 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003253 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003254 }
3255 }
3256
3257 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003258 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003259 if (D)
3260 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003261 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003262 }
3263
3264 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003265 const Stmt *S = getCursorStmt(C);
3266 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003267 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003268
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003269 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003270 }
3271
3272 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003273 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003274 ->getNameStart());
3275
3276 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003277 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003278 ->getNameStart());
3279
3280 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003281 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282
3283 if (clang_isDeclaration(C.kind))
3284 return getDeclSpelling(getCursorDecl(C));
3285
3286 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003287 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003288 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003289 }
3290
3291 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003292 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003293 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003294 }
3295
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003297}
3298
3299CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3300 unsigned pieceIndex,
3301 unsigned options) {
3302 if (clang_Cursor_isNull(C))
3303 return clang_getNullRange();
3304
3305 ASTContext &Ctx = getCursorContext(C);
3306
3307 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003308 const Stmt *S = getCursorStmt(C);
3309 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003310 if (pieceIndex > 0)
3311 return clang_getNullRange();
3312 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3313 }
3314
3315 return clang_getNullRange();
3316 }
3317
3318 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003319 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003320 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3321 if (pieceIndex >= ME->getNumSelectorLocs())
3322 return clang_getNullRange();
3323 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3324 }
3325 }
3326
3327 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3328 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003329 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003330 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3331 if (pieceIndex >= MD->getNumSelectorLocs())
3332 return clang_getNullRange();
3333 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3334 }
3335 }
3336
3337 if (C.kind == CXCursor_ObjCCategoryDecl ||
3338 C.kind == CXCursor_ObjCCategoryImplDecl) {
3339 if (pieceIndex > 0)
3340 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003341 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003342 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3343 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003344 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003345 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3346 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3347 }
3348
3349 if (C.kind == CXCursor_ModuleImportDecl) {
3350 if (pieceIndex > 0)
3351 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003352 if (const ImportDecl *ImportD =
3353 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003354 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3355 if (!Locs.empty())
3356 return cxloc::translateSourceRange(Ctx,
3357 SourceRange(Locs.front(), Locs.back()));
3358 }
3359 return clang_getNullRange();
3360 }
3361
3362 // FIXME: A CXCursor_InclusionDirective should give the location of the
3363 // filename, but we don't keep track of this.
3364
3365 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3366 // but we don't keep track of this.
3367
3368 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3369 // but we don't keep track of this.
3370
3371 // Default handling, give the location of the cursor.
3372
3373 if (pieceIndex > 0)
3374 return clang_getNullRange();
3375
3376 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3377 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3378 return cxloc::translateSourceRange(Ctx, Loc);
3379}
3380
3381CXString clang_getCursorDisplayName(CXCursor C) {
3382 if (!clang_isDeclaration(C.kind))
3383 return clang_getCursorSpelling(C);
3384
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003385 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003386 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003387 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003388
3389 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003390 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003391 D = FunTmpl->getTemplatedDecl();
3392
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003393 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003394 SmallString<64> Str;
3395 llvm::raw_svector_ostream OS(Str);
3396 OS << *Function;
3397 if (Function->getPrimaryTemplate())
3398 OS << "<>";
3399 OS << "(";
3400 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3401 if (I)
3402 OS << ", ";
3403 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3404 }
3405
3406 if (Function->isVariadic()) {
3407 if (Function->getNumParams())
3408 OS << ", ";
3409 OS << "...";
3410 }
3411 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003412 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003413 }
3414
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003415 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003416 SmallString<64> Str;
3417 llvm::raw_svector_ostream OS(Str);
3418 OS << *ClassTemplate;
3419 OS << "<";
3420 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3421 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3422 if (I)
3423 OS << ", ";
3424
3425 NamedDecl *Param = Params->getParam(I);
3426 if (Param->getIdentifier()) {
3427 OS << Param->getIdentifier()->getName();
3428 continue;
3429 }
3430
3431 // There is no parameter name, which makes this tricky. Try to come up
3432 // with something useful that isn't too long.
3433 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3434 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3435 else if (NonTypeTemplateParmDecl *NTTP
3436 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3437 OS << NTTP->getType().getAsString(Policy);
3438 else
3439 OS << "template<...> class";
3440 }
3441
3442 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003443 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003444 }
3445
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003446 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003447 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3448 // If the type was explicitly written, use that.
3449 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003450 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451
Benjamin Kramer5eada842013-02-22 15:46:01 +00003452 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003453 llvm::raw_svector_ostream OS(Str);
3454 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003455 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003456 ClassSpec->getTemplateArgs().data(),
3457 ClassSpec->getTemplateArgs().size(),
3458 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003459 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003460 }
3461
3462 return clang_getCursorSpelling(C);
3463}
3464
3465CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3466 switch (Kind) {
3467 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003468 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003469 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003470 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003472 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003474 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003595 case CXCursor_ObjCSelfExpr:
3596 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003742 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003743 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003744 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003745 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003746 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003747 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003748 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003749 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003750 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003751 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003752 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003753 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003754 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003755 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003756 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003757 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003758 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003759 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003760 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003761 }
3762
3763 llvm_unreachable("Unhandled CXCursorKind");
3764}
3765
3766struct GetCursorData {
3767 SourceLocation TokenBeginLoc;
3768 bool PointsAtMacroArgExpansion;
3769 bool VisitedObjCPropertyImplDecl;
3770 SourceLocation VisitedDeclaratorDeclStartLoc;
3771 CXCursor &BestCursor;
3772
3773 GetCursorData(SourceManager &SM,
3774 SourceLocation tokenBegin, CXCursor &outputCursor)
3775 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3776 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3777 VisitedObjCPropertyImplDecl = false;
3778 }
3779};
3780
3781static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3782 CXCursor parent,
3783 CXClientData client_data) {
3784 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3785 CXCursor *BestCursor = &Data->BestCursor;
3786
3787 // If we point inside a macro argument we should provide info of what the
3788 // token is so use the actual cursor, don't replace it with a macro expansion
3789 // cursor.
3790 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3791 return CXChildVisit_Recurse;
3792
3793 if (clang_isDeclaration(cursor.kind)) {
3794 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003795 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3797 if (MD->isImplicit())
3798 return CXChildVisit_Break;
3799
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003800 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003801 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3802 // Check that when we have multiple @class references in the same line,
3803 // that later ones do not override the previous ones.
3804 // If we have:
3805 // @class Foo, Bar;
3806 // source ranges for both start at '@', so 'Bar' will end up overriding
3807 // 'Foo' even though the cursor location was at 'Foo'.
3808 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3809 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003810 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003811 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3812 if (PrevID != ID &&
3813 !PrevID->isThisDeclarationADefinition() &&
3814 !ID->isThisDeclarationADefinition())
3815 return CXChildVisit_Break;
3816 }
3817
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003818 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003819 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3820 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3821 // Check that when we have multiple declarators in the same line,
3822 // that later ones do not override the previous ones.
3823 // If we have:
3824 // int Foo, Bar;
3825 // source ranges for both start at 'int', so 'Bar' will end up overriding
3826 // 'Foo' even though the cursor location was at 'Foo'.
3827 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3828 return CXChildVisit_Break;
3829 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3830
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003831 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003832 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3833 (void)PropImp;
3834 // Check that when we have multiple @synthesize in the same line,
3835 // that later ones do not override the previous ones.
3836 // If we have:
3837 // @synthesize Foo, Bar;
3838 // source ranges for both start at '@', so 'Bar' will end up overriding
3839 // 'Foo' even though the cursor location was at 'Foo'.
3840 if (Data->VisitedObjCPropertyImplDecl)
3841 return CXChildVisit_Break;
3842 Data->VisitedObjCPropertyImplDecl = true;
3843 }
3844 }
3845
3846 if (clang_isExpression(cursor.kind) &&
3847 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003848 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003849 // Avoid having the cursor of an expression replace the declaration cursor
3850 // when the expression source range overlaps the declaration range.
3851 // This can happen for C++ constructor expressions whose range generally
3852 // include the variable declaration, e.g.:
3853 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3854 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3855 D->getLocation() == Data->TokenBeginLoc)
3856 return CXChildVisit_Break;
3857 }
3858 }
3859
3860 // If our current best cursor is the construction of a temporary object,
3861 // don't replace that cursor with a type reference, because we want
3862 // clang_getCursor() to point at the constructor.
3863 if (clang_isExpression(BestCursor->kind) &&
3864 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3865 cursor.kind == CXCursor_TypeRef) {
3866 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3867 // as having the actual point on the type reference.
3868 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3869 return CXChildVisit_Recurse;
3870 }
3871
3872 *BestCursor = cursor;
3873 return CXChildVisit_Recurse;
3874}
3875
3876CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3877 if (!TU)
3878 return clang_getNullCursor();
3879
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003880 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003881 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3882
3883 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3884 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3885
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003886 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003887 CXFile SearchFile;
3888 unsigned SearchLine, SearchColumn;
3889 CXFile ResultFile;
3890 unsigned ResultLine, ResultColumn;
3891 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3892 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3893 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3894
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003895 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3896 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003897 &ResultColumn, 0);
3898 SearchFileName = clang_getFileName(SearchFile);
3899 ResultFileName = clang_getFileName(ResultFile);
3900 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3901 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003902 *Log << llvm::format("(%s:%d:%d) = %s",
3903 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3904 clang_getCString(KindSpelling))
3905 << llvm::format("(%s:%d:%d):%s%s",
3906 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3907 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003908 clang_disposeString(SearchFileName);
3909 clang_disposeString(ResultFileName);
3910 clang_disposeString(KindSpelling);
3911 clang_disposeString(USR);
3912
3913 CXCursor Definition = clang_getCursorDefinition(Result);
3914 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3915 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3916 CXString DefinitionKindSpelling
3917 = clang_getCursorKindSpelling(Definition.kind);
3918 CXFile DefinitionFile;
3919 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003920 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003921 &DefinitionLine, &DefinitionColumn, 0);
3922 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003923 *Log << llvm::format(" -> %s(%s:%d:%d)",
3924 clang_getCString(DefinitionKindSpelling),
3925 clang_getCString(DefinitionFileName),
3926 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003927 clang_disposeString(DefinitionFileName);
3928 clang_disposeString(DefinitionKindSpelling);
3929 }
3930 }
3931
3932 return Result;
3933}
3934
3935CXCursor clang_getNullCursor(void) {
3936 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3937}
3938
3939unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003940 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3941 // can't set consistently. For example, when visiting a DeclStmt we will set
3942 // it but we don't set it on the result of clang_getCursorDefinition for
3943 // a reference of the same declaration.
3944 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3945 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3946 // to provide that kind of info.
3947 if (clang_isDeclaration(X.kind))
3948 X.data[1] = 0;
3949 if (clang_isDeclaration(Y.kind))
3950 Y.data[1] = 0;
3951
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003952 return X == Y;
3953}
3954
3955unsigned clang_hashCursor(CXCursor C) {
3956 unsigned Index = 0;
3957 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3958 Index = 1;
3959
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003960 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003961 std::make_pair(C.kind, C.data[Index]));
3962}
3963
3964unsigned clang_isInvalid(enum CXCursorKind K) {
3965 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3966}
3967
3968unsigned clang_isDeclaration(enum CXCursorKind K) {
3969 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3970 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3971}
3972
3973unsigned clang_isReference(enum CXCursorKind K) {
3974 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3975}
3976
3977unsigned clang_isExpression(enum CXCursorKind K) {
3978 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3979}
3980
3981unsigned clang_isStatement(enum CXCursorKind K) {
3982 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3983}
3984
3985unsigned clang_isAttribute(enum CXCursorKind K) {
3986 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3987}
3988
3989unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3990 return K == CXCursor_TranslationUnit;
3991}
3992
3993unsigned clang_isPreprocessing(enum CXCursorKind K) {
3994 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3995}
3996
3997unsigned clang_isUnexposed(enum CXCursorKind K) {
3998 switch (K) {
3999 case CXCursor_UnexposedDecl:
4000 case CXCursor_UnexposedExpr:
4001 case CXCursor_UnexposedStmt:
4002 case CXCursor_UnexposedAttr:
4003 return true;
4004 default:
4005 return false;
4006 }
4007}
4008
4009CXCursorKind clang_getCursorKind(CXCursor C) {
4010 return C.kind;
4011}
4012
4013CXSourceLocation clang_getCursorLocation(CXCursor C) {
4014 if (clang_isReference(C.kind)) {
4015 switch (C.kind) {
4016 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004017 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004018 = getCursorObjCSuperClassRef(C);
4019 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4020 }
4021
4022 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004023 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004024 = getCursorObjCProtocolRef(C);
4025 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4026 }
4027
4028 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004029 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004030 = getCursorObjCClassRef(C);
4031 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4032 }
4033
4034 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004035 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004036 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4037 }
4038
4039 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004040 std::pair<const TemplateDecl *, SourceLocation> P =
4041 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004042 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4043 }
4044
4045 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004046 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004047 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4048 }
4049
4050 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004051 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004052 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4053 }
4054
4055 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004056 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004057 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4058 }
4059
4060 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004061 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004062 if (!BaseSpec)
4063 return clang_getNullLocation();
4064
4065 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4066 return cxloc::translateSourceLocation(getCursorContext(C),
4067 TSInfo->getTypeLoc().getBeginLoc());
4068
4069 return cxloc::translateSourceLocation(getCursorContext(C),
4070 BaseSpec->getLocStart());
4071 }
4072
4073 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004074 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004075 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4076 }
4077
4078 case CXCursor_OverloadedDeclRef:
4079 return cxloc::translateSourceLocation(getCursorContext(C),
4080 getCursorOverloadedDeclRef(C).second);
4081
4082 default:
4083 // FIXME: Need a way to enumerate all non-reference cases.
4084 llvm_unreachable("Missed a reference kind");
4085 }
4086 }
4087
4088 if (clang_isExpression(C.kind))
4089 return cxloc::translateSourceLocation(getCursorContext(C),
4090 getLocationFromExpr(getCursorExpr(C)));
4091
4092 if (clang_isStatement(C.kind))
4093 return cxloc::translateSourceLocation(getCursorContext(C),
4094 getCursorStmt(C)->getLocStart());
4095
4096 if (C.kind == CXCursor_PreprocessingDirective) {
4097 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4098 return cxloc::translateSourceLocation(getCursorContext(C), L);
4099 }
4100
4101 if (C.kind == CXCursor_MacroExpansion) {
4102 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004103 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004104 return cxloc::translateSourceLocation(getCursorContext(C), L);
4105 }
4106
4107 if (C.kind == CXCursor_MacroDefinition) {
4108 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4109 return cxloc::translateSourceLocation(getCursorContext(C), L);
4110 }
4111
4112 if (C.kind == CXCursor_InclusionDirective) {
4113 SourceLocation L
4114 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4115 return cxloc::translateSourceLocation(getCursorContext(C), L);
4116 }
4117
4118 if (!clang_isDeclaration(C.kind))
4119 return clang_getNullLocation();
4120
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004121 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004122 if (!D)
4123 return clang_getNullLocation();
4124
4125 SourceLocation Loc = D->getLocation();
4126 // FIXME: Multiple variables declared in a single declaration
4127 // currently lack the information needed to correctly determine their
4128 // ranges when accounting for the type-specifier. We use context
4129 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4130 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004131 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004132 if (!cxcursor::isFirstInDeclGroup(C))
4133 Loc = VD->getLocation();
4134 }
4135
4136 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004137 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004138 Loc = MD->getSelectorStartLoc();
4139
4140 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4141}
4142
4143} // end extern "C"
4144
4145CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4146 assert(TU);
4147
4148 // Guard against an invalid SourceLocation, or we may assert in one
4149 // of the following calls.
4150 if (SLoc.isInvalid())
4151 return clang_getNullCursor();
4152
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004153 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004154
4155 // Translate the given source location to make it point at the beginning of
4156 // the token under the cursor.
4157 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4158 CXXUnit->getASTContext().getLangOpts());
4159
4160 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4161 if (SLoc.isValid()) {
4162 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4163 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4164 /*VisitPreprocessorLast=*/true,
4165 /*VisitIncludedEntities=*/false,
4166 SourceLocation(SLoc));
4167 CursorVis.visitFileRegion();
4168 }
4169
4170 return Result;
4171}
4172
4173static SourceRange getRawCursorExtent(CXCursor C) {
4174 if (clang_isReference(C.kind)) {
4175 switch (C.kind) {
4176 case CXCursor_ObjCSuperClassRef:
4177 return getCursorObjCSuperClassRef(C).second;
4178
4179 case CXCursor_ObjCProtocolRef:
4180 return getCursorObjCProtocolRef(C).second;
4181
4182 case CXCursor_ObjCClassRef:
4183 return getCursorObjCClassRef(C).second;
4184
4185 case CXCursor_TypeRef:
4186 return getCursorTypeRef(C).second;
4187
4188 case CXCursor_TemplateRef:
4189 return getCursorTemplateRef(C).second;
4190
4191 case CXCursor_NamespaceRef:
4192 return getCursorNamespaceRef(C).second;
4193
4194 case CXCursor_MemberRef:
4195 return getCursorMemberRef(C).second;
4196
4197 case CXCursor_CXXBaseSpecifier:
4198 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4199
4200 case CXCursor_LabelRef:
4201 return getCursorLabelRef(C).second;
4202
4203 case CXCursor_OverloadedDeclRef:
4204 return getCursorOverloadedDeclRef(C).second;
4205
4206 case CXCursor_VariableRef:
4207 return getCursorVariableRef(C).second;
4208
4209 default:
4210 // FIXME: Need a way to enumerate all non-reference cases.
4211 llvm_unreachable("Missed a reference kind");
4212 }
4213 }
4214
4215 if (clang_isExpression(C.kind))
4216 return getCursorExpr(C)->getSourceRange();
4217
4218 if (clang_isStatement(C.kind))
4219 return getCursorStmt(C)->getSourceRange();
4220
4221 if (clang_isAttribute(C.kind))
4222 return getCursorAttr(C)->getRange();
4223
4224 if (C.kind == CXCursor_PreprocessingDirective)
4225 return cxcursor::getCursorPreprocessingDirective(C);
4226
4227 if (C.kind == CXCursor_MacroExpansion) {
4228 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004229 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004230 return TU->mapRangeFromPreamble(Range);
4231 }
4232
4233 if (C.kind == CXCursor_MacroDefinition) {
4234 ASTUnit *TU = getCursorASTUnit(C);
4235 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4236 return TU->mapRangeFromPreamble(Range);
4237 }
4238
4239 if (C.kind == CXCursor_InclusionDirective) {
4240 ASTUnit *TU = getCursorASTUnit(C);
4241 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4242 return TU->mapRangeFromPreamble(Range);
4243 }
4244
4245 if (C.kind == CXCursor_TranslationUnit) {
4246 ASTUnit *TU = getCursorASTUnit(C);
4247 FileID MainID = TU->getSourceManager().getMainFileID();
4248 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4249 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4250 return SourceRange(Start, End);
4251 }
4252
4253 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004254 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004255 if (!D)
4256 return SourceRange();
4257
4258 SourceRange R = D->getSourceRange();
4259 // FIXME: Multiple variables declared in a single declaration
4260 // currently lack the information needed to correctly determine their
4261 // ranges when accounting for the type-specifier. We use context
4262 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4263 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004264 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004265 if (!cxcursor::isFirstInDeclGroup(C))
4266 R.setBegin(VD->getLocation());
4267 }
4268 return R;
4269 }
4270 return SourceRange();
4271}
4272
4273/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4274/// the decl-specifier-seq for declarations.
4275static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4276 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004277 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004278 if (!D)
4279 return SourceRange();
4280
4281 SourceRange R = D->getSourceRange();
4282
4283 // Adjust the start of the location for declarations preceded by
4284 // declaration specifiers.
4285 SourceLocation StartLoc;
4286 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4287 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4288 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004289 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004290 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4291 StartLoc = TI->getTypeLoc().getLocStart();
4292 }
4293
4294 if (StartLoc.isValid() && R.getBegin().isValid() &&
4295 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4296 R.setBegin(StartLoc);
4297
4298 // FIXME: Multiple variables declared in a single declaration
4299 // currently lack the information needed to correctly determine their
4300 // ranges when accounting for the type-specifier. We use context
4301 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4302 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004303 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004304 if (!cxcursor::isFirstInDeclGroup(C))
4305 R.setBegin(VD->getLocation());
4306 }
4307
4308 return R;
4309 }
4310
4311 return getRawCursorExtent(C);
4312}
4313
4314extern "C" {
4315
4316CXSourceRange clang_getCursorExtent(CXCursor C) {
4317 SourceRange R = getRawCursorExtent(C);
4318 if (R.isInvalid())
4319 return clang_getNullRange();
4320
4321 return cxloc::translateSourceRange(getCursorContext(C), R);
4322}
4323
4324CXCursor clang_getCursorReferenced(CXCursor C) {
4325 if (clang_isInvalid(C.kind))
4326 return clang_getNullCursor();
4327
4328 CXTranslationUnit tu = getCursorTU(C);
4329 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004330 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004331 if (!D)
4332 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004333 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004334 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004335 if (const ObjCPropertyImplDecl *PropImpl =
4336 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004337 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4338 return MakeCXCursor(Property, tu);
4339
4340 return C;
4341 }
4342
4343 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004344 const Expr *E = getCursorExpr(C);
4345 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004346 if (D) {
4347 CXCursor declCursor = MakeCXCursor(D, tu);
4348 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4349 declCursor);
4350 return declCursor;
4351 }
4352
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004353 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004354 return MakeCursorOverloadedDeclRef(Ovl, tu);
4355
4356 return clang_getNullCursor();
4357 }
4358
4359 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004360 const Stmt *S = getCursorStmt(C);
4361 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004362 if (LabelDecl *label = Goto->getLabel())
4363 if (LabelStmt *labelS = label->getStmt())
4364 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4365
4366 return clang_getNullCursor();
4367 }
4368
4369 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004370 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004371 return MakeMacroDefinitionCursor(Def, tu);
4372 }
4373
4374 if (!clang_isReference(C.kind))
4375 return clang_getNullCursor();
4376
4377 switch (C.kind) {
4378 case CXCursor_ObjCSuperClassRef:
4379 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4380
4381 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004382 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4383 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004384 return MakeCXCursor(Def, tu);
4385
4386 return MakeCXCursor(Prot, tu);
4387 }
4388
4389 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004390 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4391 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004392 return MakeCXCursor(Def, tu);
4393
4394 return MakeCXCursor(Class, tu);
4395 }
4396
4397 case CXCursor_TypeRef:
4398 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4399
4400 case CXCursor_TemplateRef:
4401 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4402
4403 case CXCursor_NamespaceRef:
4404 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4405
4406 case CXCursor_MemberRef:
4407 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4408
4409 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004410 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004411 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4412 tu ));
4413 }
4414
4415 case CXCursor_LabelRef:
4416 // FIXME: We end up faking the "parent" declaration here because we
4417 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004418 return MakeCXCursor(getCursorLabelRef(C).first,
4419 cxtu::getASTUnit(tu)->getASTContext()
4420 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004421 tu);
4422
4423 case CXCursor_OverloadedDeclRef:
4424 return C;
4425
4426 case CXCursor_VariableRef:
4427 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4428
4429 default:
4430 // We would prefer to enumerate all non-reference cursor kinds here.
4431 llvm_unreachable("Unhandled reference cursor kind");
4432 }
4433}
4434
4435CXCursor clang_getCursorDefinition(CXCursor C) {
4436 if (clang_isInvalid(C.kind))
4437 return clang_getNullCursor();
4438
4439 CXTranslationUnit TU = getCursorTU(C);
4440
4441 bool WasReference = false;
4442 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4443 C = clang_getCursorReferenced(C);
4444 WasReference = true;
4445 }
4446
4447 if (C.kind == CXCursor_MacroExpansion)
4448 return clang_getCursorReferenced(C);
4449
4450 if (!clang_isDeclaration(C.kind))
4451 return clang_getNullCursor();
4452
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004453 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004454 if (!D)
4455 return clang_getNullCursor();
4456
4457 switch (D->getKind()) {
4458 // Declaration kinds that don't really separate the notions of
4459 // declaration and definition.
4460 case Decl::Namespace:
4461 case Decl::Typedef:
4462 case Decl::TypeAlias:
4463 case Decl::TypeAliasTemplate:
4464 case Decl::TemplateTypeParm:
4465 case Decl::EnumConstant:
4466 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004467 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004468 case Decl::IndirectField:
4469 case Decl::ObjCIvar:
4470 case Decl::ObjCAtDefsField:
4471 case Decl::ImplicitParam:
4472 case Decl::ParmVar:
4473 case Decl::NonTypeTemplateParm:
4474 case Decl::TemplateTemplateParm:
4475 case Decl::ObjCCategoryImpl:
4476 case Decl::ObjCImplementation:
4477 case Decl::AccessSpec:
4478 case Decl::LinkageSpec:
4479 case Decl::ObjCPropertyImpl:
4480 case Decl::FileScopeAsm:
4481 case Decl::StaticAssert:
4482 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004483 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004484 case Decl::Label: // FIXME: Is this right??
4485 case Decl::ClassScopeFunctionSpecialization:
4486 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004487 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004488 return C;
4489
4490 // Declaration kinds that don't make any sense here, but are
4491 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004492 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004493 case Decl::TranslationUnit:
4494 break;
4495
4496 // Declaration kinds for which the definition is not resolvable.
4497 case Decl::UnresolvedUsingTypename:
4498 case Decl::UnresolvedUsingValue:
4499 break;
4500
4501 case Decl::UsingDirective:
4502 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4503 TU);
4504
4505 case Decl::NamespaceAlias:
4506 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4507
4508 case Decl::Enum:
4509 case Decl::Record:
4510 case Decl::CXXRecord:
4511 case Decl::ClassTemplateSpecialization:
4512 case Decl::ClassTemplatePartialSpecialization:
4513 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4514 return MakeCXCursor(Def, TU);
4515 return clang_getNullCursor();
4516
4517 case Decl::Function:
4518 case Decl::CXXMethod:
4519 case Decl::CXXConstructor:
4520 case Decl::CXXDestructor:
4521 case Decl::CXXConversion: {
4522 const FunctionDecl *Def = 0;
4523 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004524 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004525 return clang_getNullCursor();
4526 }
4527
4528 case Decl::Var: {
4529 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004530 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004531 return MakeCXCursor(Def, TU);
4532 return clang_getNullCursor();
4533 }
4534
4535 case Decl::FunctionTemplate: {
4536 const FunctionDecl *Def = 0;
4537 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4538 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4539 return clang_getNullCursor();
4540 }
4541
4542 case Decl::ClassTemplate: {
4543 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4544 ->getDefinition())
4545 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4546 TU);
4547 return clang_getNullCursor();
4548 }
4549
4550 case Decl::Using:
4551 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4552 D->getLocation(), TU);
4553
4554 case Decl::UsingShadow:
4555 return clang_getCursorDefinition(
4556 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4557 TU));
4558
4559 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004560 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004561 if (Method->isThisDeclarationADefinition())
4562 return C;
4563
4564 // Dig out the method definition in the associated
4565 // @implementation, if we have it.
4566 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004567 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004568 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4569 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4570 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4571 Method->isInstanceMethod()))
4572 if (Def->isThisDeclarationADefinition())
4573 return MakeCXCursor(Def, TU);
4574
4575 return clang_getNullCursor();
4576 }
4577
4578 case Decl::ObjCCategory:
4579 if (ObjCCategoryImplDecl *Impl
4580 = cast<ObjCCategoryDecl>(D)->getImplementation())
4581 return MakeCXCursor(Impl, TU);
4582 return clang_getNullCursor();
4583
4584 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004585 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004586 return MakeCXCursor(Def, TU);
4587 return clang_getNullCursor();
4588
4589 case Decl::ObjCInterface: {
4590 // There are two notions of a "definition" for an Objective-C
4591 // class: the interface and its implementation. When we resolved a
4592 // reference to an Objective-C class, produce the @interface as
4593 // the definition; when we were provided with the interface,
4594 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004595 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004596 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004597 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004598 return MakeCXCursor(Def, TU);
4599 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4600 return MakeCXCursor(Impl, TU);
4601 return clang_getNullCursor();
4602 }
4603
4604 case Decl::ObjCProperty:
4605 // FIXME: We don't really know where to find the
4606 // ObjCPropertyImplDecls that implement this property.
4607 return clang_getNullCursor();
4608
4609 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004610 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004611 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004612 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004613 return MakeCXCursor(Def, TU);
4614
4615 return clang_getNullCursor();
4616
4617 case Decl::Friend:
4618 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4619 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4620 return clang_getNullCursor();
4621
4622 case Decl::FriendTemplate:
4623 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4624 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4625 return clang_getNullCursor();
4626 }
4627
4628 return clang_getNullCursor();
4629}
4630
4631unsigned clang_isCursorDefinition(CXCursor C) {
4632 if (!clang_isDeclaration(C.kind))
4633 return 0;
4634
4635 return clang_getCursorDefinition(C) == C;
4636}
4637
4638CXCursor clang_getCanonicalCursor(CXCursor C) {
4639 if (!clang_isDeclaration(C.kind))
4640 return C;
4641
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004642 if (const Decl *D = getCursorDecl(C)) {
4643 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004644 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4645 return MakeCXCursor(CatD, getCursorTU(C));
4646
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004647 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4648 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004649 return MakeCXCursor(IFD, getCursorTU(C));
4650
4651 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4652 }
4653
4654 return C;
4655}
4656
4657int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4658 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4659}
4660
4661unsigned clang_getNumOverloadedDecls(CXCursor C) {
4662 if (C.kind != CXCursor_OverloadedDeclRef)
4663 return 0;
4664
4665 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004666 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004667 return E->getNumDecls();
4668
4669 if (OverloadedTemplateStorage *S
4670 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4671 return S->size();
4672
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004673 const Decl *D = Storage.get<const Decl *>();
4674 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004675 return Using->shadow_size();
4676
4677 return 0;
4678}
4679
4680CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4681 if (cursor.kind != CXCursor_OverloadedDeclRef)
4682 return clang_getNullCursor();
4683
4684 if (index >= clang_getNumOverloadedDecls(cursor))
4685 return clang_getNullCursor();
4686
4687 CXTranslationUnit TU = getCursorTU(cursor);
4688 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004689 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004690 return MakeCXCursor(E->decls_begin()[index], TU);
4691
4692 if (OverloadedTemplateStorage *S
4693 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4694 return MakeCXCursor(S->begin()[index], TU);
4695
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004696 const Decl *D = Storage.get<const Decl *>();
4697 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004698 // FIXME: This is, unfortunately, linear time.
4699 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4700 std::advance(Pos, index);
4701 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4702 }
4703
4704 return clang_getNullCursor();
4705}
4706
4707void clang_getDefinitionSpellingAndExtent(CXCursor C,
4708 const char **startBuf,
4709 const char **endBuf,
4710 unsigned *startLine,
4711 unsigned *startColumn,
4712 unsigned *endLine,
4713 unsigned *endColumn) {
4714 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004715 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004716 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4717
4718 SourceManager &SM = FD->getASTContext().getSourceManager();
4719 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4720 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4721 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4722 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4723 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4724 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4725}
4726
4727
4728CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4729 unsigned PieceIndex) {
4730 RefNamePieces Pieces;
4731
4732 switch (C.kind) {
4733 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004734 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004735 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4736 E->getQualifierLoc().getSourceRange());
4737 break;
4738
4739 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004740 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004741 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4742 E->getQualifierLoc().getSourceRange(),
4743 E->getOptionalExplicitTemplateArgs());
4744 break;
4745
4746 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004747 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004748 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004749 const Expr *Callee = OCE->getCallee();
4750 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004751 Callee = ICE->getSubExpr();
4752
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004753 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004754 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4755 DRE->getQualifierLoc().getSourceRange());
4756 }
4757 break;
4758
4759 default:
4760 break;
4761 }
4762
4763 if (Pieces.empty()) {
4764 if (PieceIndex == 0)
4765 return clang_getCursorExtent(C);
4766 } else if (PieceIndex < Pieces.size()) {
4767 SourceRange R = Pieces[PieceIndex];
4768 if (R.isValid())
4769 return cxloc::translateSourceRange(getCursorContext(C), R);
4770 }
4771
4772 return clang_getNullRange();
4773}
4774
4775void clang_enableStackTraces(void) {
4776 llvm::sys::PrintStackTraceOnErrorSignal();
4777}
4778
4779void clang_executeOnThread(void (*fn)(void*), void *user_data,
4780 unsigned stack_size) {
4781 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4782}
4783
4784} // end: extern "C"
4785
4786//===----------------------------------------------------------------------===//
4787// Token-based Operations.
4788//===----------------------------------------------------------------------===//
4789
4790/* CXToken layout:
4791 * int_data[0]: a CXTokenKind
4792 * int_data[1]: starting token location
4793 * int_data[2]: token length
4794 * int_data[3]: reserved
4795 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4796 * otherwise unused.
4797 */
4798extern "C" {
4799
4800CXTokenKind clang_getTokenKind(CXToken CXTok) {
4801 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4802}
4803
4804CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4805 switch (clang_getTokenKind(CXTok)) {
4806 case CXToken_Identifier:
4807 case CXToken_Keyword:
4808 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004809 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004810 ->getNameStart());
4811
4812 case CXToken_Literal: {
4813 // We have stashed the starting pointer in the ptr_data field. Use it.
4814 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004815 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004816 }
4817
4818 case CXToken_Punctuation:
4819 case CXToken_Comment:
4820 break;
4821 }
4822
4823 // We have to find the starting buffer pointer the hard way, by
4824 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004825 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004826 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004827 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004828
4829 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4830 std::pair<FileID, unsigned> LocInfo
4831 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4832 bool Invalid = false;
4833 StringRef Buffer
4834 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4835 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004836 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004837
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004838 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004839}
4840
4841CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004842 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004843 if (!CXXUnit)
4844 return clang_getNullLocation();
4845
4846 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4847 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4848}
4849
4850CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004851 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004852 if (!CXXUnit)
4853 return clang_getNullRange();
4854
4855 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4856 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4857}
4858
4859static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4860 SmallVectorImpl<CXToken> &CXTokens) {
4861 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4862 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004863 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004864 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004865 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004866
4867 // Cannot tokenize across files.
4868 if (BeginLocInfo.first != EndLocInfo.first)
4869 return;
4870
4871 // Create a lexer
4872 bool Invalid = false;
4873 StringRef Buffer
4874 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4875 if (Invalid)
4876 return;
4877
4878 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4879 CXXUnit->getASTContext().getLangOpts(),
4880 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4881 Lex.SetCommentRetentionState(true);
4882
4883 // Lex tokens until we hit the end of the range.
4884 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4885 Token Tok;
4886 bool previousWasAt = false;
4887 do {
4888 // Lex the next token
4889 Lex.LexFromRawLexer(Tok);
4890 if (Tok.is(tok::eof))
4891 break;
4892
4893 // Initialize the CXToken.
4894 CXToken CXTok;
4895
4896 // - Common fields
4897 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4898 CXTok.int_data[2] = Tok.getLength();
4899 CXTok.int_data[3] = 0;
4900
4901 // - Kind-specific fields
4902 if (Tok.isLiteral()) {
4903 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004904 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004905 } else if (Tok.is(tok::raw_identifier)) {
4906 // Lookup the identifier to determine whether we have a keyword.
4907 IdentifierInfo *II
4908 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4909
4910 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4911 CXTok.int_data[0] = CXToken_Keyword;
4912 }
4913 else {
4914 CXTok.int_data[0] = Tok.is(tok::identifier)
4915 ? CXToken_Identifier
4916 : CXToken_Keyword;
4917 }
4918 CXTok.ptr_data = II;
4919 } else if (Tok.is(tok::comment)) {
4920 CXTok.int_data[0] = CXToken_Comment;
4921 CXTok.ptr_data = 0;
4922 } else {
4923 CXTok.int_data[0] = CXToken_Punctuation;
4924 CXTok.ptr_data = 0;
4925 }
4926 CXTokens.push_back(CXTok);
4927 previousWasAt = Tok.is(tok::at);
4928 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4929}
4930
4931void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4932 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004933 LOG_FUNC_SECTION {
4934 *Log << TU << ' ' << Range;
4935 }
4936
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004937 if (Tokens)
4938 *Tokens = 0;
4939 if (NumTokens)
4940 *NumTokens = 0;
4941
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004942 if (!TU)
4943 return;
4944
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004946 if (!CXXUnit || !Tokens || !NumTokens)
4947 return;
4948
4949 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4950
4951 SourceRange R = cxloc::translateCXSourceRange(Range);
4952 if (R.isInvalid())
4953 return;
4954
4955 SmallVector<CXToken, 32> CXTokens;
4956 getTokens(CXXUnit, R, CXTokens);
4957
4958 if (CXTokens.empty())
4959 return;
4960
4961 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4962 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4963 *NumTokens = CXTokens.size();
4964}
4965
4966void clang_disposeTokens(CXTranslationUnit TU,
4967 CXToken *Tokens, unsigned NumTokens) {
4968 free(Tokens);
4969}
4970
4971} // end: extern "C"
4972
4973//===----------------------------------------------------------------------===//
4974// Token annotation APIs.
4975//===----------------------------------------------------------------------===//
4976
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004977static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4978 CXCursor parent,
4979 CXClientData client_data);
4980static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4981 CXClientData client_data);
4982
4983namespace {
4984class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004985 CXToken *Tokens;
4986 CXCursor *Cursors;
4987 unsigned NumTokens;
4988 unsigned TokIdx;
4989 unsigned PreprocessingTokIdx;
4990 CursorVisitor AnnotateVis;
4991 SourceManager &SrcMgr;
4992 bool HasContextSensitiveKeywords;
4993
4994 struct PostChildrenInfo {
4995 CXCursor Cursor;
4996 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004997 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004998 unsigned BeforeChildrenTokenIdx;
4999 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005000 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005001
5002 bool MoreTokens() const { return TokIdx < NumTokens; }
5003 unsigned NextToken() const { return TokIdx; }
5004 void AdvanceToken() { ++TokIdx; }
5005 SourceLocation GetTokenLoc(unsigned tokI) {
5006 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5007 }
5008 bool isFunctionMacroToken(unsigned tokI) const {
5009 return Tokens[tokI].int_data[3] != 0;
5010 }
5011 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5012 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5013 }
5014
5015 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005016 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005017 SourceRange);
5018
5019public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005020 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005021 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005022 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005023 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005024 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005025 AnnotateTokensVisitor, this,
5026 /*VisitPreprocessorLast=*/true,
5027 /*VisitIncludedEntities=*/false,
5028 RegionOfInterest,
5029 /*VisitDeclsOnly=*/false,
5030 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005031 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005032 HasContextSensitiveKeywords(false) { }
5033
5034 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5035 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5036 bool postVisitChildren(CXCursor cursor);
5037 void AnnotateTokens();
5038
5039 /// \brief Determine whether the annotator saw any cursors that have
5040 /// context-sensitive keywords.
5041 bool hasContextSensitiveKeywords() const {
5042 return HasContextSensitiveKeywords;
5043 }
5044
5045 ~AnnotateTokensWorker() {
5046 assert(PostChildrenInfos.empty());
5047 }
5048};
5049}
5050
5051void AnnotateTokensWorker::AnnotateTokens() {
5052 // Walk the AST within the region of interest, annotating tokens
5053 // along the way.
5054 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005055}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005056
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005057static inline void updateCursorAnnotation(CXCursor &Cursor,
5058 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005059 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005060 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005061 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005062}
5063
5064/// \brief It annotates and advances tokens with a cursor until the comparison
5065//// between the cursor location and the source range is the same as
5066/// \arg compResult.
5067///
5068/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5069/// Pass RangeOverlap to annotate tokens inside a range.
5070void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5071 RangeComparisonResult compResult,
5072 SourceRange range) {
5073 while (MoreTokens()) {
5074 const unsigned I = NextToken();
5075 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005076 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5077 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005078
5079 SourceLocation TokLoc = GetTokenLoc(I);
5080 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005081 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005082 AdvanceToken();
5083 continue;
5084 }
5085 break;
5086 }
5087}
5088
5089/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005090/// \returns true if it advanced beyond all macro tokens, false otherwise.
5091bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005092 CXCursor updateC,
5093 RangeComparisonResult compResult,
5094 SourceRange range) {
5095 assert(MoreTokens());
5096 assert(isFunctionMacroToken(NextToken()) &&
5097 "Should be called only for macro arg tokens");
5098
5099 // This works differently than annotateAndAdvanceTokens; because expanded
5100 // macro arguments can have arbitrary translation-unit source order, we do not
5101 // advance the token index one by one until a token fails the range test.
5102 // We only advance once past all of the macro arg tokens if all of them
5103 // pass the range test. If one of them fails we keep the token index pointing
5104 // at the start of the macro arg tokens so that the failing token will be
5105 // annotated by a subsequent annotation try.
5106
5107 bool atLeastOneCompFail = false;
5108
5109 unsigned I = NextToken();
5110 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5111 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5112 if (TokLoc.isFileID())
5113 continue; // not macro arg token, it's parens or comma.
5114 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5115 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5116 Cursors[I] = updateC;
5117 } else
5118 atLeastOneCompFail = true;
5119 }
5120
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005121 if (atLeastOneCompFail)
5122 return false;
5123
5124 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5125 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005126}
5127
5128enum CXChildVisitResult
5129AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005130 SourceRange cursorRange = getRawCursorExtent(cursor);
5131 if (cursorRange.isInvalid())
5132 return CXChildVisit_Recurse;
5133
5134 if (!HasContextSensitiveKeywords) {
5135 // Objective-C properties can have context-sensitive keywords.
5136 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005137 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005138 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5139 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5140 }
5141 // Objective-C methods can have context-sensitive keywords.
5142 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5143 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005144 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005145 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5146 if (Method->getObjCDeclQualifier())
5147 HasContextSensitiveKeywords = true;
5148 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005149 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5150 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005151 P != PEnd; ++P) {
5152 if ((*P)->getObjCDeclQualifier()) {
5153 HasContextSensitiveKeywords = true;
5154 break;
5155 }
5156 }
5157 }
5158 }
5159 }
5160 // C++ methods can have context-sensitive keywords.
5161 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005162 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005163 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5164 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5165 HasContextSensitiveKeywords = true;
5166 }
5167 }
5168 // C++ classes can have context-sensitive keywords.
5169 else if (cursor.kind == CXCursor_StructDecl ||
5170 cursor.kind == CXCursor_ClassDecl ||
5171 cursor.kind == CXCursor_ClassTemplate ||
5172 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005173 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005174 if (D->hasAttr<FinalAttr>())
5175 HasContextSensitiveKeywords = true;
5176 }
5177 }
5178
5179 if (clang_isPreprocessing(cursor.kind)) {
5180 // Items in the preprocessing record are kept separate from items in
5181 // declarations, so we keep a separate token index.
5182 unsigned SavedTokIdx = TokIdx;
5183 TokIdx = PreprocessingTokIdx;
5184
5185 // Skip tokens up until we catch up to the beginning of the preprocessing
5186 // entry.
5187 while (MoreTokens()) {
5188 const unsigned I = NextToken();
5189 SourceLocation TokLoc = GetTokenLoc(I);
5190 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5191 case RangeBefore:
5192 AdvanceToken();
5193 continue;
5194 case RangeAfter:
5195 case RangeOverlap:
5196 break;
5197 }
5198 break;
5199 }
5200
5201 // Look at all of the tokens within this range.
5202 while (MoreTokens()) {
5203 const unsigned I = NextToken();
5204 SourceLocation TokLoc = GetTokenLoc(I);
5205 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5206 case RangeBefore:
5207 llvm_unreachable("Infeasible");
5208 case RangeAfter:
5209 break;
5210 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005211 // For macro expansions, just note where the beginning of the macro
5212 // expansion occurs.
5213 if (cursor.kind == CXCursor_MacroExpansion) {
5214 if (TokLoc == cursorRange.getBegin())
5215 Cursors[I] = cursor;
5216 AdvanceToken();
5217 break;
5218 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005219 // We may have already annotated macro names inside macro definitions.
5220 if (Cursors[I].kind != CXCursor_MacroExpansion)
5221 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005222 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005223 continue;
5224 }
5225 break;
5226 }
5227
5228 // Save the preprocessing token index; restore the non-preprocessing
5229 // token index.
5230 PreprocessingTokIdx = TokIdx;
5231 TokIdx = SavedTokIdx;
5232 return CXChildVisit_Recurse;
5233 }
5234
5235 if (cursorRange.isInvalid())
5236 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005237
5238 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005239 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005240 const enum CXCursorKind K = clang_getCursorKind(parent);
5241 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005242 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5243 // Attributes are annotated out-of-order, skip tokens until we reach it.
5244 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005245 ? clang_getNullCursor() : parent;
5246
5247 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5248
5249 // Avoid having the cursor of an expression "overwrite" the annotation of the
5250 // variable declaration that it belongs to.
5251 // This can happen for C++ constructor expressions whose range generally
5252 // include the variable declaration, e.g.:
5253 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5254 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005255 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005256 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005257 const unsigned I = NextToken();
5258 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5259 E->getLocStart() == D->getLocation() &&
5260 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005261 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005262 AdvanceToken();
5263 }
5264 }
5265 }
5266
5267 // Before recursing into the children keep some state that we are going
5268 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5269 // extra work after the child nodes are visited.
5270 // Note that we don't call VisitChildren here to avoid traversing statements
5271 // code-recursively which can blow the stack.
5272
5273 PostChildrenInfo Info;
5274 Info.Cursor = cursor;
5275 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005276 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005277 Info.BeforeChildrenTokenIdx = NextToken();
5278 PostChildrenInfos.push_back(Info);
5279
5280 return CXChildVisit_Recurse;
5281}
5282
5283bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5284 if (PostChildrenInfos.empty())
5285 return false;
5286 const PostChildrenInfo &Info = PostChildrenInfos.back();
5287 if (!clang_equalCursors(Info.Cursor, cursor))
5288 return false;
5289
5290 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5291 const unsigned AfterChildren = NextToken();
5292 SourceRange cursorRange = Info.CursorRange;
5293
5294 // Scan the tokens that are at the end of the cursor, but are not captured
5295 // but the child cursors.
5296 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5297
5298 // Scan the tokens that are at the beginning of the cursor, but are not
5299 // capture by the child cursors.
5300 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5301 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5302 break;
5303
5304 Cursors[I] = cursor;
5305 }
5306
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005307 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5308 // encountered the attribute cursor.
5309 if (clang_isAttribute(cursor.kind))
5310 TokIdx = Info.BeforeReachingCursorIdx;
5311
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005312 PostChildrenInfos.pop_back();
5313 return false;
5314}
5315
5316static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5317 CXCursor parent,
5318 CXClientData client_data) {
5319 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5320}
5321
5322static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5323 CXClientData client_data) {
5324 return static_cast<AnnotateTokensWorker*>(client_data)->
5325 postVisitChildren(cursor);
5326}
5327
5328namespace {
5329
5330/// \brief Uses the macro expansions in the preprocessing record to find
5331/// and mark tokens that are macro arguments. This info is used by the
5332/// AnnotateTokensWorker.
5333class MarkMacroArgTokensVisitor {
5334 SourceManager &SM;
5335 CXToken *Tokens;
5336 unsigned NumTokens;
5337 unsigned CurIdx;
5338
5339public:
5340 MarkMacroArgTokensVisitor(SourceManager &SM,
5341 CXToken *tokens, unsigned numTokens)
5342 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5343
5344 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5345 if (cursor.kind != CXCursor_MacroExpansion)
5346 return CXChildVisit_Continue;
5347
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005348 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005349 if (macroRange.getBegin() == macroRange.getEnd())
5350 return CXChildVisit_Continue; // it's not a function macro.
5351
5352 for (; CurIdx < NumTokens; ++CurIdx) {
5353 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5354 macroRange.getBegin()))
5355 break;
5356 }
5357
5358 if (CurIdx == NumTokens)
5359 return CXChildVisit_Break;
5360
5361 for (; CurIdx < NumTokens; ++CurIdx) {
5362 SourceLocation tokLoc = getTokenLoc(CurIdx);
5363 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5364 break;
5365
5366 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5367 }
5368
5369 if (CurIdx == NumTokens)
5370 return CXChildVisit_Break;
5371
5372 return CXChildVisit_Continue;
5373 }
5374
5375private:
5376 SourceLocation getTokenLoc(unsigned tokI) {
5377 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5378 }
5379
5380 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5381 // The third field is reserved and currently not used. Use it here
5382 // to mark macro arg expanded tokens with their expanded locations.
5383 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5384 }
5385};
5386
5387} // end anonymous namespace
5388
5389static CXChildVisitResult
5390MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5391 CXClientData client_data) {
5392 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5393 parent);
5394}
5395
5396namespace {
5397 struct clang_annotateTokens_Data {
5398 CXTranslationUnit TU;
5399 ASTUnit *CXXUnit;
5400 CXToken *Tokens;
5401 unsigned NumTokens;
5402 CXCursor *Cursors;
5403 };
5404}
5405
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005406/// \brief Used by \c annotatePreprocessorTokens.
5407/// \returns true if lexing was finished, false otherwise.
5408static bool lexNext(Lexer &Lex, Token &Tok,
5409 unsigned &NextIdx, unsigned NumTokens) {
5410 if (NextIdx >= NumTokens)
5411 return true;
5412
5413 ++NextIdx;
5414 Lex.LexFromRawLexer(Tok);
5415 if (Tok.is(tok::eof))
5416 return true;
5417
5418 return false;
5419}
5420
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005421static void annotatePreprocessorTokens(CXTranslationUnit TU,
5422 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005423 CXCursor *Cursors,
5424 CXToken *Tokens,
5425 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005426 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005427
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005428 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005429 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5430 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005431 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005432 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005433 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005434
5435 if (BeginLocInfo.first != EndLocInfo.first)
5436 return;
5437
5438 StringRef Buffer;
5439 bool Invalid = false;
5440 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5441 if (Buffer.empty() || Invalid)
5442 return;
5443
5444 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5445 CXXUnit->getASTContext().getLangOpts(),
5446 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5447 Buffer.end());
5448 Lex.SetCommentRetentionState(true);
5449
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005450 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005451 // Lex tokens in raw mode until we hit the end of the range, to avoid
5452 // entering #includes or expanding macros.
5453 while (true) {
5454 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005455 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5456 break;
5457 unsigned TokIdx = NextIdx-1;
5458 assert(Tok.getLocation() ==
5459 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005460
5461 reprocess:
5462 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005463 // We have found a preprocessing directive. Annotate the tokens
5464 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005465 //
5466 // FIXME: Some simple tests here could identify macro definitions and
5467 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005468
5469 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005470 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5471 break;
5472
5473 MacroInfo *MI = 0;
5474 if (Tok.is(tok::raw_identifier) &&
5475 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5476 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5477 break;
5478
5479 if (Tok.is(tok::raw_identifier)) {
5480 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5481 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5482 SourceLocation MappedTokLoc =
5483 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5484 MI = getMacroInfo(II, MappedTokLoc, TU);
5485 }
5486 }
5487
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005488 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005489 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005490 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5491 finished = true;
5492 break;
5493 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005494 // If we are in a macro definition, check if the token was ever a
5495 // macro name and annotate it if that's the case.
5496 if (MI) {
5497 SourceLocation SaveLoc = Tok.getLocation();
5498 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5499 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5500 Tok.setLocation(SaveLoc);
5501 if (MacroDef)
5502 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5503 Tok.getLocation(), TU);
5504 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005505 } while (!Tok.isAtStartOfLine());
5506
5507 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5508 assert(TokIdx <= LastIdx);
5509 SourceLocation EndLoc =
5510 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5511 CXCursor Cursor =
5512 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5513
5514 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005515 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005516
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005517 if (finished)
5518 break;
5519 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005520 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005521 }
5522}
5523
5524// This gets run a separate thread to avoid stack blowout.
5525static void clang_annotateTokensImpl(void *UserData) {
5526 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5527 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5528 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5529 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5530 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5531
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005532 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005533 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5534 setThreadBackgroundPriority();
5535
5536 // Determine the region of interest, which contains all of the tokens.
5537 SourceRange RegionOfInterest;
5538 RegionOfInterest.setBegin(
5539 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5540 RegionOfInterest.setEnd(
5541 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5542 Tokens[NumTokens-1])));
5543
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005544 // Relex the tokens within the source range to look for preprocessing
5545 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005546 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005547
5548 // If begin location points inside a macro argument, set it to the expansion
5549 // location so we can have the full context when annotating semantically.
5550 {
5551 SourceManager &SM = CXXUnit->getSourceManager();
5552 SourceLocation Loc =
5553 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5554 if (Loc.isMacroID())
5555 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5556 }
5557
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005558 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5559 // Search and mark tokens that are macro argument expansions.
5560 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5561 Tokens, NumTokens);
5562 CursorVisitor MacroArgMarker(TU,
5563 MarkMacroArgTokensVisitorDelegate, &Visitor,
5564 /*VisitPreprocessorLast=*/true,
5565 /*VisitIncludedEntities=*/false,
5566 RegionOfInterest);
5567 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5568 }
5569
5570 // Annotate all of the source locations in the region of interest that map to
5571 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005572 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005573
5574 // FIXME: We use a ridiculous stack size here because the data-recursion
5575 // algorithm uses a large stack frame than the non-data recursive version,
5576 // and AnnotationTokensWorker currently transforms the data-recursion
5577 // algorithm back into a traditional recursion by explicitly calling
5578 // VisitChildren(). We will need to remove this explicit recursive call.
5579 W.AnnotateTokens();
5580
5581 // If we ran into any entities that involve context-sensitive keywords,
5582 // take another pass through the tokens to mark them as such.
5583 if (W.hasContextSensitiveKeywords()) {
5584 for (unsigned I = 0; I != NumTokens; ++I) {
5585 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5586 continue;
5587
5588 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5589 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005590 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005591 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5592 if (Property->getPropertyAttributesAsWritten() != 0 &&
5593 llvm::StringSwitch<bool>(II->getName())
5594 .Case("readonly", true)
5595 .Case("assign", true)
5596 .Case("unsafe_unretained", true)
5597 .Case("readwrite", true)
5598 .Case("retain", true)
5599 .Case("copy", true)
5600 .Case("nonatomic", true)
5601 .Case("atomic", true)
5602 .Case("getter", true)
5603 .Case("setter", true)
5604 .Case("strong", true)
5605 .Case("weak", true)
5606 .Default(false))
5607 Tokens[I].int_data[0] = CXToken_Keyword;
5608 }
5609 continue;
5610 }
5611
5612 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5613 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5614 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5615 if (llvm::StringSwitch<bool>(II->getName())
5616 .Case("in", true)
5617 .Case("out", true)
5618 .Case("inout", true)
5619 .Case("oneway", true)
5620 .Case("bycopy", true)
5621 .Case("byref", true)
5622 .Default(false))
5623 Tokens[I].int_data[0] = CXToken_Keyword;
5624 continue;
5625 }
5626
5627 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5628 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5629 Tokens[I].int_data[0] = CXToken_Keyword;
5630 continue;
5631 }
5632 }
5633 }
5634}
5635
5636extern "C" {
5637
5638void clang_annotateTokens(CXTranslationUnit TU,
5639 CXToken *Tokens, unsigned NumTokens,
5640 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005641 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005642 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005643 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005644 }
5645
5646 LOG_FUNC_SECTION {
5647 *Log << TU << ' ';
5648 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5649 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5650 *Log << clang_getRange(bloc, eloc);
5651 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005652
5653 // Any token we don't specifically annotate will have a NULL cursor.
5654 CXCursor C = clang_getNullCursor();
5655 for (unsigned I = 0; I != NumTokens; ++I)
5656 Cursors[I] = C;
5657
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005658 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005659 if (!CXXUnit)
5660 return;
5661
5662 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5663
5664 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5665 llvm::CrashRecoveryContext CRC;
5666 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5667 GetSafetyThreadStackSize() * 2)) {
5668 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5669 }
5670}
5671
5672} // end: extern "C"
5673
5674//===----------------------------------------------------------------------===//
5675// Operations for querying linkage of a cursor.
5676//===----------------------------------------------------------------------===//
5677
5678extern "C" {
5679CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5680 if (!clang_isDeclaration(cursor.kind))
5681 return CXLinkage_Invalid;
5682
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005683 const Decl *D = cxcursor::getCursorDecl(cursor);
5684 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005685 switch (ND->getLinkageInternal()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005686 case NoLinkage: return CXLinkage_NoLinkage;
5687 case InternalLinkage: return CXLinkage_Internal;
5688 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5689 case ExternalLinkage: return CXLinkage_External;
5690 };
5691
5692 return CXLinkage_Invalid;
5693}
5694} // end: extern "C"
5695
5696//===----------------------------------------------------------------------===//
5697// Operations for querying language of a cursor.
5698//===----------------------------------------------------------------------===//
5699
5700static CXLanguageKind getDeclLanguage(const Decl *D) {
5701 if (!D)
5702 return CXLanguage_C;
5703
5704 switch (D->getKind()) {
5705 default:
5706 break;
5707 case Decl::ImplicitParam:
5708 case Decl::ObjCAtDefsField:
5709 case Decl::ObjCCategory:
5710 case Decl::ObjCCategoryImpl:
5711 case Decl::ObjCCompatibleAlias:
5712 case Decl::ObjCImplementation:
5713 case Decl::ObjCInterface:
5714 case Decl::ObjCIvar:
5715 case Decl::ObjCMethod:
5716 case Decl::ObjCProperty:
5717 case Decl::ObjCPropertyImpl:
5718 case Decl::ObjCProtocol:
5719 return CXLanguage_ObjC;
5720 case Decl::CXXConstructor:
5721 case Decl::CXXConversion:
5722 case Decl::CXXDestructor:
5723 case Decl::CXXMethod:
5724 case Decl::CXXRecord:
5725 case Decl::ClassTemplate:
5726 case Decl::ClassTemplatePartialSpecialization:
5727 case Decl::ClassTemplateSpecialization:
5728 case Decl::Friend:
5729 case Decl::FriendTemplate:
5730 case Decl::FunctionTemplate:
5731 case Decl::LinkageSpec:
5732 case Decl::Namespace:
5733 case Decl::NamespaceAlias:
5734 case Decl::NonTypeTemplateParm:
5735 case Decl::StaticAssert:
5736 case Decl::TemplateTemplateParm:
5737 case Decl::TemplateTypeParm:
5738 case Decl::UnresolvedUsingTypename:
5739 case Decl::UnresolvedUsingValue:
5740 case Decl::Using:
5741 case Decl::UsingDirective:
5742 case Decl::UsingShadow:
5743 return CXLanguage_CPlusPlus;
5744 }
5745
5746 return CXLanguage_C;
5747}
5748
5749extern "C" {
5750
5751enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5752 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005753 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005754 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5755 return CXAvailability_Available;
5756
5757 switch (D->getAvailability()) {
5758 case AR_Available:
5759 case AR_NotYetIntroduced:
5760 return CXAvailability_Available;
5761
5762 case AR_Deprecated:
5763 return CXAvailability_Deprecated;
5764
5765 case AR_Unavailable:
5766 return CXAvailability_NotAvailable;
5767 }
5768 }
5769
5770 return CXAvailability_Available;
5771}
5772
5773static CXVersion convertVersion(VersionTuple In) {
5774 CXVersion Out = { -1, -1, -1 };
5775 if (In.empty())
5776 return Out;
5777
5778 Out.Major = In.getMajor();
5779
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005780 Optional<unsigned> Minor = In.getMinor();
5781 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005782 Out.Minor = *Minor;
5783 else
5784 return Out;
5785
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005786 Optional<unsigned> Subminor = In.getSubminor();
5787 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005788 Out.Subminor = *Subminor;
5789
5790 return Out;
5791}
5792
5793int clang_getCursorPlatformAvailability(CXCursor cursor,
5794 int *always_deprecated,
5795 CXString *deprecated_message,
5796 int *always_unavailable,
5797 CXString *unavailable_message,
5798 CXPlatformAvailability *availability,
5799 int availability_size) {
5800 if (always_deprecated)
5801 *always_deprecated = 0;
5802 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005803 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005804 if (always_unavailable)
5805 *always_unavailable = 0;
5806 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005807 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005808
5809 if (!clang_isDeclaration(cursor.kind))
5810 return 0;
5811
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005812 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005813 if (!D)
5814 return 0;
5815
5816 int N = 0;
5817 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5818 ++A) {
5819 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5820 if (always_deprecated)
5821 *always_deprecated = 1;
5822 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005823 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005824 continue;
5825 }
5826
5827 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5828 if (always_unavailable)
5829 *always_unavailable = 1;
5830 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005831 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005832 }
5833 continue;
5834 }
5835
5836 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5837 if (N < availability_size) {
5838 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005839 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005840 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5841 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5842 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5843 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005844 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005845 }
5846 ++N;
5847 }
5848 }
5849
5850 return N;
5851}
5852
5853void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5854 clang_disposeString(availability->Platform);
5855 clang_disposeString(availability->Message);
5856}
5857
5858CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5859 if (clang_isDeclaration(cursor.kind))
5860 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5861
5862 return CXLanguage_Invalid;
5863}
5864
5865 /// \brief If the given cursor is the "templated" declaration
5866 /// descibing a class or function template, return the class or
5867 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005868static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005869 if (!D)
5870 return 0;
5871
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005872 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005873 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5874 return FunTmpl;
5875
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005876 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005877 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5878 return ClassTmpl;
5879
5880 return D;
5881}
5882
5883CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5884 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005885 if (const Decl *D = getCursorDecl(cursor)) {
5886 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005887 if (!DC)
5888 return clang_getNullCursor();
5889
5890 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5891 getCursorTU(cursor));
5892 }
5893 }
5894
5895 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005896 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005897 return MakeCXCursor(D, getCursorTU(cursor));
5898 }
5899
5900 return clang_getNullCursor();
5901}
5902
5903CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5904 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005905 if (const Decl *D = getCursorDecl(cursor)) {
5906 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005907 if (!DC)
5908 return clang_getNullCursor();
5909
5910 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5911 getCursorTU(cursor));
5912 }
5913 }
5914
5915 // FIXME: Note that we can't easily compute the lexical context of a
5916 // statement or expression, so we return nothing.
5917 return clang_getNullCursor();
5918}
5919
5920CXFile clang_getIncludedFile(CXCursor cursor) {
5921 if (cursor.kind != CXCursor_InclusionDirective)
5922 return 0;
5923
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005924 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005925 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005926}
5927
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005928unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5929 if (C.kind != CXCursor_ObjCPropertyDecl)
5930 return CXObjCPropertyAttr_noattr;
5931
5932 unsigned Result = CXObjCPropertyAttr_noattr;
5933 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
5934 ObjCPropertyDecl::PropertyAttributeKind Attr =
5935 PD->getPropertyAttributesAsWritten();
5936
5937#define SET_CXOBJCPROP_ATTR(A) \
5938 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
5939 Result |= CXObjCPropertyAttr_##A
5940 SET_CXOBJCPROP_ATTR(readonly);
5941 SET_CXOBJCPROP_ATTR(getter);
5942 SET_CXOBJCPROP_ATTR(assign);
5943 SET_CXOBJCPROP_ATTR(readwrite);
5944 SET_CXOBJCPROP_ATTR(retain);
5945 SET_CXOBJCPROP_ATTR(copy);
5946 SET_CXOBJCPROP_ATTR(nonatomic);
5947 SET_CXOBJCPROP_ATTR(setter);
5948 SET_CXOBJCPROP_ATTR(atomic);
5949 SET_CXOBJCPROP_ATTR(weak);
5950 SET_CXOBJCPROP_ATTR(strong);
5951 SET_CXOBJCPROP_ATTR(unsafe_unretained);
5952#undef SET_CXOBJCPROP_ATTR
5953
5954 return Result;
5955}
5956
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00005957unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
5958 if (!clang_isDeclaration(C.kind))
5959 return CXObjCDeclQualifier_None;
5960
5961 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
5962 const Decl *D = getCursorDecl(C);
5963 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5964 QT = MD->getObjCDeclQualifier();
5965 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
5966 QT = PD->getObjCDeclQualifier();
5967 if (QT == Decl::OBJC_TQ_None)
5968 return CXObjCDeclQualifier_None;
5969
5970 unsigned Result = CXObjCDeclQualifier_None;
5971 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
5972 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
5973 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
5974 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
5975 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
5976 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
5977
5978 return Result;
5979}
5980
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00005981unsigned clang_Cursor_isVariadic(CXCursor C) {
5982 if (!clang_isDeclaration(C.kind))
5983 return 0;
5984
5985 const Decl *D = getCursorDecl(C);
5986 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5987 return FD->isVariadic();
5988 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5989 return MD->isVariadic();
5990
5991 return 0;
5992}
5993
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005994CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5995 if (!clang_isDeclaration(C.kind))
5996 return clang_getNullRange();
5997
5998 const Decl *D = getCursorDecl(C);
5999 ASTContext &Context = getCursorContext(C);
6000 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6001 if (!RC)
6002 return clang_getNullRange();
6003
6004 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6005}
6006
6007CXString clang_Cursor_getRawCommentText(CXCursor C) {
6008 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006009 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006010
6011 const Decl *D = getCursorDecl(C);
6012 ASTContext &Context = getCursorContext(C);
6013 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6014 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6015 StringRef();
6016
6017 // Don't duplicate the string because RawText points directly into source
6018 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006019 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006020}
6021
6022CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6023 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006024 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006025
6026 const Decl *D = getCursorDecl(C);
6027 const ASTContext &Context = getCursorContext(C);
6028 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6029
6030 if (RC) {
6031 StringRef BriefText = RC->getBriefText(Context);
6032
6033 // Don't duplicate the string because RawComment ensures that this memory
6034 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006035 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006036 }
6037
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006038 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006039}
6040
6041CXComment clang_Cursor_getParsedComment(CXCursor C) {
6042 if (!clang_isDeclaration(C.kind))
6043 return cxcomment::createCXComment(NULL, NULL);
6044
6045 const Decl *D = getCursorDecl(C);
6046 const ASTContext &Context = getCursorContext(C);
6047 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6048
6049 return cxcomment::createCXComment(FC, getCursorTU(C));
6050}
6051
6052CXModule clang_Cursor_getModule(CXCursor C) {
6053 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006054 if (const ImportDecl *ImportD =
6055 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006056 return ImportD->getImportedModule();
6057 }
6058
6059 return 0;
6060}
6061
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006062CXFile clang_Module_getASTFile(CXModule CXMod) {
6063 if (!CXMod)
6064 return 0;
6065 Module *Mod = static_cast<Module*>(CXMod);
6066 return const_cast<FileEntry *>(Mod->getASTFile());
6067}
6068
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006069CXModule clang_Module_getParent(CXModule CXMod) {
6070 if (!CXMod)
6071 return 0;
6072 Module *Mod = static_cast<Module*>(CXMod);
6073 return Mod->Parent;
6074}
6075
6076CXString clang_Module_getName(CXModule CXMod) {
6077 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006078 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006079 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006080 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006081}
6082
6083CXString clang_Module_getFullName(CXModule CXMod) {
6084 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006085 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006086 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006087 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006088}
6089
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006090unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6091 CXModule CXMod) {
6092 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006093 return 0;
6094 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006095 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6096 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6097 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006098}
6099
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006100CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6101 CXModule CXMod, unsigned Index) {
6102 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006103 return 0;
6104 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006105 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006106
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006107 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6108 if (Index < TopHeaders.size())
6109 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006110
6111 return 0;
6112}
6113
6114} // end: extern "C"
6115
6116//===----------------------------------------------------------------------===//
6117// C++ AST instrospection.
6118//===----------------------------------------------------------------------===//
6119
6120extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006121unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6122 if (!clang_isDeclaration(C.kind))
6123 return 0;
6124
6125 const CXXMethodDecl *Method = 0;
6126 const Decl *D = cxcursor::getCursorDecl(C);
6127 if (const FunctionTemplateDecl *FunTmpl =
6128 dyn_cast_or_null<FunctionTemplateDecl>(D))
6129 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6130 else
6131 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6132 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6133}
6134
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006135unsigned clang_CXXMethod_isStatic(CXCursor C) {
6136 if (!clang_isDeclaration(C.kind))
6137 return 0;
6138
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006139 const CXXMethodDecl *Method = 0;
6140 const Decl *D = cxcursor::getCursorDecl(C);
6141 if (const FunctionTemplateDecl *FunTmpl =
6142 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006143 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6144 else
6145 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6146 return (Method && Method->isStatic()) ? 1 : 0;
6147}
6148
6149unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6150 if (!clang_isDeclaration(C.kind))
6151 return 0;
6152
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006153 const CXXMethodDecl *Method = 0;
6154 const Decl *D = cxcursor::getCursorDecl(C);
6155 if (const FunctionTemplateDecl *FunTmpl =
6156 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006157 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6158 else
6159 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6160 return (Method && Method->isVirtual()) ? 1 : 0;
6161}
6162} // end: extern "C"
6163
6164//===----------------------------------------------------------------------===//
6165// Attribute introspection.
6166//===----------------------------------------------------------------------===//
6167
6168extern "C" {
6169CXType clang_getIBOutletCollectionType(CXCursor C) {
6170 if (C.kind != CXCursor_IBOutletCollectionAttr)
6171 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6172
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006173 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006174 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6175
6176 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6177}
6178} // end: extern "C"
6179
6180//===----------------------------------------------------------------------===//
6181// Inspecting memory usage.
6182//===----------------------------------------------------------------------===//
6183
6184typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6185
6186static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6187 enum CXTUResourceUsageKind k,
6188 unsigned long amount) {
6189 CXTUResourceUsageEntry entry = { k, amount };
6190 entries.push_back(entry);
6191}
6192
6193extern "C" {
6194
6195const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6196 const char *str = "";
6197 switch (kind) {
6198 case CXTUResourceUsage_AST:
6199 str = "ASTContext: expressions, declarations, and types";
6200 break;
6201 case CXTUResourceUsage_Identifiers:
6202 str = "ASTContext: identifiers";
6203 break;
6204 case CXTUResourceUsage_Selectors:
6205 str = "ASTContext: selectors";
6206 break;
6207 case CXTUResourceUsage_GlobalCompletionResults:
6208 str = "Code completion: cached global results";
6209 break;
6210 case CXTUResourceUsage_SourceManagerContentCache:
6211 str = "SourceManager: content cache allocator";
6212 break;
6213 case CXTUResourceUsage_AST_SideTables:
6214 str = "ASTContext: side tables";
6215 break;
6216 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6217 str = "SourceManager: malloc'ed memory buffers";
6218 break;
6219 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6220 str = "SourceManager: mmap'ed memory buffers";
6221 break;
6222 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6223 str = "ExternalASTSource: malloc'ed memory buffers";
6224 break;
6225 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6226 str = "ExternalASTSource: mmap'ed memory buffers";
6227 break;
6228 case CXTUResourceUsage_Preprocessor:
6229 str = "Preprocessor: malloc'ed memory";
6230 break;
6231 case CXTUResourceUsage_PreprocessingRecord:
6232 str = "Preprocessor: PreprocessingRecord";
6233 break;
6234 case CXTUResourceUsage_SourceManager_DataStructures:
6235 str = "SourceManager: data structures and tables";
6236 break;
6237 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6238 str = "Preprocessor: header search tables";
6239 break;
6240 }
6241 return str;
6242}
6243
6244CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6245 if (!TU) {
6246 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6247 return usage;
6248 }
6249
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006250 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006251 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6252 ASTContext &astContext = astUnit->getASTContext();
6253
6254 // How much memory is used by AST nodes and types?
6255 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6256 (unsigned long) astContext.getASTAllocatedMemory());
6257
6258 // How much memory is used by identifiers?
6259 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6260 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6261
6262 // How much memory is used for selectors?
6263 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6264 (unsigned long) astContext.Selectors.getTotalMemory());
6265
6266 // How much memory is used by ASTContext's side tables?
6267 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6268 (unsigned long) astContext.getSideTableAllocatedMemory());
6269
6270 // How much memory is used for caching global code completion results?
6271 unsigned long completionBytes = 0;
6272 if (GlobalCodeCompletionAllocator *completionAllocator =
6273 astUnit->getCachedCompletionAllocator().getPtr()) {
6274 completionBytes = completionAllocator->getTotalMemory();
6275 }
6276 createCXTUResourceUsageEntry(*entries,
6277 CXTUResourceUsage_GlobalCompletionResults,
6278 completionBytes);
6279
6280 // How much memory is being used by SourceManager's content cache?
6281 createCXTUResourceUsageEntry(*entries,
6282 CXTUResourceUsage_SourceManagerContentCache,
6283 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6284
6285 // How much memory is being used by the MemoryBuffer's in SourceManager?
6286 const SourceManager::MemoryBufferSizes &srcBufs =
6287 astUnit->getSourceManager().getMemoryBufferSizes();
6288
6289 createCXTUResourceUsageEntry(*entries,
6290 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6291 (unsigned long) srcBufs.malloc_bytes);
6292 createCXTUResourceUsageEntry(*entries,
6293 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6294 (unsigned long) srcBufs.mmap_bytes);
6295 createCXTUResourceUsageEntry(*entries,
6296 CXTUResourceUsage_SourceManager_DataStructures,
6297 (unsigned long) astContext.getSourceManager()
6298 .getDataStructureSizes());
6299
6300 // How much memory is being used by the ExternalASTSource?
6301 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6302 const ExternalASTSource::MemoryBufferSizes &sizes =
6303 esrc->getMemoryBufferSizes();
6304
6305 createCXTUResourceUsageEntry(*entries,
6306 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6307 (unsigned long) sizes.malloc_bytes);
6308 createCXTUResourceUsageEntry(*entries,
6309 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6310 (unsigned long) sizes.mmap_bytes);
6311 }
6312
6313 // How much memory is being used by the Preprocessor?
6314 Preprocessor &pp = astUnit->getPreprocessor();
6315 createCXTUResourceUsageEntry(*entries,
6316 CXTUResourceUsage_Preprocessor,
6317 pp.getTotalMemory());
6318
6319 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6320 createCXTUResourceUsageEntry(*entries,
6321 CXTUResourceUsage_PreprocessingRecord,
6322 pRec->getTotalMemory());
6323 }
6324
6325 createCXTUResourceUsageEntry(*entries,
6326 CXTUResourceUsage_Preprocessor_HeaderSearch,
6327 pp.getHeaderSearchInfo().getTotalMemory());
6328
6329 CXTUResourceUsage usage = { (void*) entries.get(),
6330 (unsigned) entries->size(),
6331 entries->size() ? &(*entries)[0] : 0 };
6332 entries.take();
6333 return usage;
6334}
6335
6336void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6337 if (usage.data)
6338 delete (MemUsageEntries*) usage.data;
6339}
6340
6341} // end extern "C"
6342
6343void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6344 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6345 for (unsigned I = 0; I != Usage.numEntries; ++I)
6346 fprintf(stderr, " %s: %lu\n",
6347 clang_getTUResourceUsageName(Usage.entries[I].kind),
6348 Usage.entries[I].amount);
6349
6350 clang_disposeCXTUResourceUsage(Usage);
6351}
6352
6353//===----------------------------------------------------------------------===//
6354// Misc. utility functions.
6355//===----------------------------------------------------------------------===//
6356
6357/// Default to using an 8 MB stack size on "safety" threads.
6358static unsigned SafetyStackThreadSize = 8 << 20;
6359
6360namespace clang {
6361
6362bool RunSafely(llvm::CrashRecoveryContext &CRC,
6363 void (*Fn)(void*), void *UserData,
6364 unsigned Size) {
6365 if (!Size)
6366 Size = GetSafetyThreadStackSize();
6367 if (Size)
6368 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6369 return CRC.RunSafely(Fn, UserData);
6370}
6371
6372unsigned GetSafetyThreadStackSize() {
6373 return SafetyStackThreadSize;
6374}
6375
6376void SetSafetyThreadStackSize(unsigned Value) {
6377 SafetyStackThreadSize = Value;
6378}
6379
6380}
6381
6382void clang::setThreadBackgroundPriority() {
6383 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6384 return;
6385
6386 // FIXME: Move to llvm/Support and make it cross-platform.
6387#ifdef __APPLE__
6388 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6389#endif
6390}
6391
6392void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6393 if (!Unit)
6394 return;
6395
6396 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6397 DEnd = Unit->stored_diag_end();
6398 D != DEnd; ++D) {
6399 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6400 CXString Msg = clang_formatDiagnostic(&Diag,
6401 clang_defaultDiagnosticDisplayOptions());
6402 fprintf(stderr, "%s\n", clang_getCString(Msg));
6403 clang_disposeString(Msg);
6404 }
6405#ifdef LLVM_ON_WIN32
6406 // On Windows, force a flush, since there may be multiple copies of
6407 // stderr and stdout in the file system, all with different buffers
6408 // but writing to the same device.
6409 fflush(stderr);
6410#endif
6411}
6412
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006413MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6414 SourceLocation MacroDefLoc,
6415 CXTranslationUnit TU){
6416 if (MacroDefLoc.isInvalid() || !TU)
6417 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006418 if (!II.hadMacroDefinition())
6419 return 0;
6420
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006421 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006422 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006423 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006424 if (MD) {
6425 for (MacroDirective::DefInfo
6426 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6427 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6428 return Def.getMacroInfo();
6429 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006430 }
6431
6432 return 0;
6433}
6434
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006435const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6436 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006437 if (!MacroDef || !TU)
6438 return 0;
6439 const IdentifierInfo *II = MacroDef->getName();
6440 if (!II)
6441 return 0;
6442
6443 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6444}
6445
6446MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6447 const Token &Tok,
6448 CXTranslationUnit TU) {
6449 if (!MI || !TU)
6450 return 0;
6451 if (Tok.isNot(tok::raw_identifier))
6452 return 0;
6453
6454 if (MI->getNumTokens() == 0)
6455 return 0;
6456 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6457 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006458 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006459
6460 // Check that the token is inside the definition and not its argument list.
6461 SourceManager &SM = Unit->getSourceManager();
6462 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6463 return 0;
6464 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6465 return 0;
6466
6467 Preprocessor &PP = Unit->getPreprocessor();
6468 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6469 if (!PPRec)
6470 return 0;
6471
6472 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6473 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6474 if (!II.hadMacroDefinition())
6475 return 0;
6476
6477 // Check that the identifier is not one of the macro arguments.
6478 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6479 return 0;
6480
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006481 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6482 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006483 return 0;
6484
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006485 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006486}
6487
6488MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6489 SourceLocation Loc,
6490 CXTranslationUnit TU) {
6491 if (Loc.isInvalid() || !MI || !TU)
6492 return 0;
6493
6494 if (MI->getNumTokens() == 0)
6495 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006496 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006497 Preprocessor &PP = Unit->getPreprocessor();
6498 if (!PP.getPreprocessingRecord())
6499 return 0;
6500 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6501 Token Tok;
6502 if (PP.getRawToken(Loc, Tok))
6503 return 0;
6504
6505 return checkForMacroInMacroDefinition(MI, Tok, TU);
6506}
6507
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006508extern "C" {
6509
6510CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006511 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006512}
6513
6514} // end: extern "C"
6515
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006516Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6517 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006518 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006519 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006520 if (Unit->isMainFileAST())
6521 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006522 return *this;
6523 }
6524 }
6525
6526 LogOS << "<NULL TU>";
6527 return *this;
6528}
6529
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006530Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6531 *this << FE->getName();
6532 return *this;
6533}
6534
6535Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6536 CXString cursorName = clang_getCursorDisplayName(cursor);
6537 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6538 clang_disposeString(cursorName);
6539 return *this;
6540}
6541
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006542Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6543 CXFile File;
6544 unsigned Line, Column;
6545 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6546 CXString FileName = clang_getFileName(File);
6547 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6548 clang_disposeString(FileName);
6549 return *this;
6550}
6551
6552Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6553 CXSourceLocation BLoc = clang_getRangeStart(range);
6554 CXSourceLocation ELoc = clang_getRangeEnd(range);
6555
6556 CXFile BFile;
6557 unsigned BLine, BColumn;
6558 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6559
6560 CXFile EFile;
6561 unsigned ELine, EColumn;
6562 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6563
6564 CXString BFileName = clang_getFileName(BFile);
6565 if (BFile == EFile) {
6566 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6567 BLine, BColumn, ELine, EColumn);
6568 } else {
6569 CXString EFileName = clang_getFileName(EFile);
6570 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6571 BLine, BColumn)
6572 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6573 ELine, EColumn);
6574 clang_disposeString(EFileName);
6575 }
6576 clang_disposeString(BFileName);
6577 return *this;
6578}
6579
6580Logger &cxindex::Logger::operator<<(CXString Str) {
6581 *this << clang_getCString(Str);
6582 return *this;
6583}
6584
6585Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6586 LogOS << Fmt;
6587 return *this;
6588}
6589
6590cxindex::Logger::~Logger() {
6591 LogOS.flush();
6592
6593 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6594
6595 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6596
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006597 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006598 OS << "[libclang:" << Name << ':';
6599
6600 // FIXME: Portability.
6601#if HAVE_PTHREAD_H && __APPLE__
6602 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6603 OS << tid << ':';
6604#endif
6605
6606 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6607 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6608 OS << Msg.str() << '\n';
6609
6610 if (Trace) {
6611 llvm::sys::PrintStackTrace(stderr);
6612 OS << "--------------------------------------------------\n";
6613 }
6614}