blob: 36224a8cffdad4db9008f539158d965cc556dd7c [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
226void CursorVisitor::visitFileRegion() {
227 if (RegionOfInterest.isInvalid())
228 return;
229
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)
246 return;
247
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())
254 return; // visitation break.
255
256 visitDeclsFromFileRegion(File, Offset, Length);
257
258 if (!VisitDeclsOnly && VisitPreprocessorLast)
259 visitPreprocessedEntitiesInRegion();
260}
261
262static bool isInLexicalContext(Decl *D, DeclContext *DC) {
263 if (!DC)
264 return false;
265
266 for (DeclContext *DeclDC = D->getLexicalDeclContext();
267 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
268 if (DeclDC == DC)
269 return true;
270 }
271 return false;
272}
273
274void CursorVisitor::visitDeclsFromFileRegion(FileID File,
275 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000276 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000277 SourceManager &SM = Unit->getSourceManager();
278 SourceRange Range = RegionOfInterest;
279
280 SmallVector<Decl *, 16> Decls;
281 Unit->findFileRegionDecls(File, Offset, Length, Decls);
282
283 // If we didn't find any file level decls for the file, try looking at the
284 // file that it was included from.
285 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
286 bool Invalid = false;
287 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
288 if (Invalid)
289 return;
290
291 SourceLocation Outer;
292 if (SLEntry.isFile())
293 Outer = SLEntry.getFile().getIncludeLoc();
294 else
295 Outer = SLEntry.getExpansion().getExpansionLocStart();
296 if (Outer.isInvalid())
297 return;
298
299 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
300 Length = 0;
301 Unit->findFileRegionDecls(File, Offset, Length, Decls);
302 }
303
304 assert(!Decls.empty());
305
306 bool VisitedAtLeastOnce = false;
307 DeclContext *CurDC = 0;
308 SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
309 for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
310 Decl *D = *DIt;
311 if (D->getSourceRange().isInvalid())
312 continue;
313
314 if (isInLexicalContext(D, CurDC))
315 continue;
316
317 CurDC = dyn_cast<DeclContext>(D);
318
319 if (TagDecl *TD = dyn_cast<TagDecl>(D))
320 if (!TD->isFreeStanding())
321 continue;
322
323 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
324 if (CompRes == RangeBefore)
325 continue;
326 if (CompRes == RangeAfter)
327 break;
328
329 assert(CompRes == RangeOverlap);
330 VisitedAtLeastOnce = true;
331
332 if (isa<ObjCContainerDecl>(D)) {
333 FileDI_current = &DIt;
334 FileDE_current = DE;
335 } else {
336 FileDI_current = 0;
337 }
338
339 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
340 break;
341 }
342
343 if (VisitedAtLeastOnce)
344 return;
345
346 // No Decls overlapped with the range. Move up the lexical context until there
347 // is a context that contains the range or we reach the translation unit
348 // level.
349 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
350 : (*(DIt-1))->getLexicalDeclContext();
351
352 while (DC && !DC->isTranslationUnit()) {
353 Decl *D = cast<Decl>(DC);
354 SourceRange CurDeclRange = D->getSourceRange();
355 if (CurDeclRange.isInvalid())
356 break;
357
358 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
359 Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true);
360 break;
361 }
362
363 DC = D->getLexicalDeclContext();
364 }
365}
366
367bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
368 if (!AU->getPreprocessor().getPreprocessingRecord())
369 return false;
370
371 PreprocessingRecord &PPRec
372 = *AU->getPreprocessor().getPreprocessingRecord();
373 SourceManager &SM = AU->getSourceManager();
374
375 if (RegionOfInterest.isValid()) {
376 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
377 SourceLocation B = MappedRange.getBegin();
378 SourceLocation E = MappedRange.getEnd();
379
380 if (AU->isInPreambleFileID(B)) {
381 if (SM.isLoadedSourceLocation(E))
382 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
383 PPRec, *this);
384
385 // Beginning of range lies in the preamble but it also extends beyond
386 // it into the main file. Split the range into 2 parts, one covering
387 // the preamble and another covering the main file. This allows subsequent
388 // calls to visitPreprocessedEntitiesInRange to accept a source range that
389 // lies in the same FileID, allowing it to skip preprocessed entities that
390 // do not come from the same FileID.
391 bool breaked =
392 visitPreprocessedEntitiesInRange(
393 SourceRange(B, AU->getEndOfPreambleFileID()),
394 PPRec, *this);
395 if (breaked) return true;
396 return visitPreprocessedEntitiesInRange(
397 SourceRange(AU->getStartOfMainFileID(), E),
398 PPRec, *this);
399 }
400
401 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
402 }
403
404 bool OnlyLocalDecls
405 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
406
407 if (OnlyLocalDecls)
408 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
409 PPRec);
410
411 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
412}
413
414template<typename InputIterator>
415bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
416 InputIterator Last,
417 PreprocessingRecord &PPRec,
418 FileID FID) {
419 for (; First != Last; ++First) {
420 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
421 continue;
422
423 PreprocessedEntity *PPE = *First;
424 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
425 if (Visit(MakeMacroExpansionCursor(ME, TU)))
426 return true;
427
428 continue;
429 }
430
431 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
432 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
433 return true;
434
435 continue;
436 }
437
438 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
439 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
440 return true;
441
442 continue;
443 }
444 }
445
446 return false;
447}
448
449/// \brief Visit the children of the given cursor.
450///
451/// \returns true if the visitation should be aborted, false if it
452/// should continue.
453bool CursorVisitor::VisitChildren(CXCursor Cursor) {
454 if (clang_isReference(Cursor.kind) &&
455 Cursor.kind != CXCursor_CXXBaseSpecifier) {
456 // By definition, references have no children.
457 return false;
458 }
459
460 // Set the Parent field to Cursor, then back to its old value once we're
461 // done.
462 SetParentRAII SetParent(Parent, StmtParent, Cursor);
463
464 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000465 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000466 if (!D)
467 return false;
468
469 return VisitAttributes(D) || Visit(D);
470 }
471
472 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000473 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000474 return Visit(S);
475
476 return false;
477 }
478
479 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000480 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000481 return Visit(E);
482
483 return false;
484 }
485
486 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000487 CXTranslationUnit TU = getCursorTU(Cursor);
488 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000489
490 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
491 for (unsigned I = 0; I != 2; ++I) {
492 if (VisitOrder[I]) {
493 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
494 RegionOfInterest.isInvalid()) {
495 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
496 TLEnd = CXXUnit->top_level_end();
497 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000498 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000499 return true;
500 }
501 } else if (VisitDeclContext(
502 CXXUnit->getASTContext().getTranslationUnitDecl()))
503 return true;
504 continue;
505 }
506
507 // Walk the preprocessing record.
508 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
509 visitPreprocessedEntitiesInRegion();
510 }
511
512 return false;
513 }
514
515 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000516 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000517 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
518 return Visit(BaseTSInfo->getTypeLoc());
519 }
520 }
521 }
522
523 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000524 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000525 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
526 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
527 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
528 A->getInterfaceLoc(), TU));
529 }
530
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000531 // If pointing inside a macro definition, check if the token is an identifier
532 // that was ever defined as a macro. In such a case, create a "pseudo" macro
533 // expansion cursor for that token.
534 SourceLocation BeginLoc = RegionOfInterest.getBegin();
535 if (Cursor.kind == CXCursor_MacroDefinition &&
536 BeginLoc == RegionOfInterest.getEnd()) {
537 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000538 const MacroInfo *MI =
539 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000540 if (MacroDefinition *MacroDef =
541 checkForMacroInMacroDefinition(MI, Loc, TU))
542 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
543 }
544
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000545 // Nothing to visit at the moment.
546 return false;
547}
548
549bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
550 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
551 if (Visit(TSInfo->getTypeLoc()))
552 return true;
553
554 if (Stmt *Body = B->getBody())
555 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
556
557 return false;
558}
559
Ted Kremenek943f9092013-02-21 01:29:01 +0000560Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000561 if (RegionOfInterest.isValid()) {
562 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
563 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000564 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000565
566 switch (CompareRegionOfInterest(Range)) {
567 case RangeBefore:
568 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000569 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000570
571 case RangeAfter:
572 // This declaration comes after the region of interest; we're done.
573 return false;
574
575 case RangeOverlap:
576 // This declaration overlaps the region of interest; visit it.
577 break;
578 }
579 }
580 return true;
581}
582
583bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
584 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
585
586 // FIXME: Eventually remove. This part of a hack to support proper
587 // iteration over all Decls contained lexically within an ObjC container.
588 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
589 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
590
591 for ( ; I != E; ++I) {
592 Decl *D = *I;
593 if (D->getLexicalDeclContext() != DC)
594 continue;
595 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
596
597 // Ignore synthesized ivars here, otherwise if we have something like:
598 // @synthesize prop = _prop;
599 // and '_prop' is not declared, we will encounter a '_prop' ivar before
600 // encountering the 'prop' synthesize declaration and we will think that
601 // we passed the region-of-interest.
602 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
603 if (ivarD->getSynthesize())
604 continue;
605 }
606
607 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
608 // declarations is a mismatch with the compiler semantics.
609 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
610 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
611 if (!ID->isThisDeclarationADefinition())
612 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
613
614 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
615 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
616 if (!PD->isThisDeclarationADefinition())
617 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
618 }
619
Ted Kremenek943f9092013-02-21 01:29:01 +0000620 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000621 if (!V.hasValue())
622 continue;
623 if (!V.getValue())
624 return false;
625 if (Visit(Cursor, true))
626 return true;
627 }
628 return false;
629}
630
631bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
632 llvm_unreachable("Translation units are visited directly by Visit()");
633}
634
635bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
636 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
637 return Visit(TSInfo->getTypeLoc());
638
639 return false;
640}
641
642bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
643 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
644 return Visit(TSInfo->getTypeLoc());
645
646 return false;
647}
648
649bool CursorVisitor::VisitTagDecl(TagDecl *D) {
650 return VisitDeclContext(D);
651}
652
653bool CursorVisitor::VisitClassTemplateSpecializationDecl(
654 ClassTemplateSpecializationDecl *D) {
655 bool ShouldVisitBody = false;
656 switch (D->getSpecializationKind()) {
657 case TSK_Undeclared:
658 case TSK_ImplicitInstantiation:
659 // Nothing to visit
660 return false;
661
662 case TSK_ExplicitInstantiationDeclaration:
663 case TSK_ExplicitInstantiationDefinition:
664 break;
665
666 case TSK_ExplicitSpecialization:
667 ShouldVisitBody = true;
668 break;
669 }
670
671 // Visit the template arguments used in the specialization.
672 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
673 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000674 if (TemplateSpecializationTypeLoc TSTLoc =
675 TL.getAs<TemplateSpecializationTypeLoc>()) {
676 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
677 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000678 return true;
679 }
680 }
681
682 if (ShouldVisitBody && VisitCXXRecordDecl(D))
683 return true;
684
685 return false;
686}
687
688bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
689 ClassTemplatePartialSpecializationDecl *D) {
690 // FIXME: Visit the "outer" template parameter lists on the TagDecl
691 // before visiting these template parameters.
692 if (VisitTemplateParameters(D->getTemplateParameters()))
693 return true;
694
695 // Visit the partial specialization arguments.
696 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
697 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
698 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
699 return true;
700
701 return VisitCXXRecordDecl(D);
702}
703
704bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
705 // Visit the default argument.
706 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
707 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
708 if (Visit(DefArg->getTypeLoc()))
709 return true;
710
711 return false;
712}
713
714bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
715 if (Expr *Init = D->getInitExpr())
716 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
717 return false;
718}
719
720bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
721 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
722 if (Visit(TSInfo->getTypeLoc()))
723 return true;
724
725 // Visit the nested-name-specifier, if present.
726 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
727 if (VisitNestedNameSpecifierLoc(QualifierLoc))
728 return true;
729
730 return false;
731}
732
733/// \brief Compare two base or member initializers based on their source order.
734static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
735 CXXCtorInitializer const * const *X
736 = static_cast<CXXCtorInitializer const * const *>(Xp);
737 CXXCtorInitializer const * const *Y
738 = static_cast<CXXCtorInitializer const * const *>(Yp);
739
740 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
741 return -1;
742 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
743 return 1;
744 else
745 return 0;
746}
747
748bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
749 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
750 // Visit the function declaration's syntactic components in the order
751 // written. This requires a bit of work.
752 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000753 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000754
755 // If we have a function declared directly (without the use of a typedef),
756 // visit just the return type. Otherwise, just visit the function's type
757 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000758 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000759 (!FTL && Visit(TL)))
760 return true;
761
762 // Visit the nested-name-specifier, if present.
763 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
764 if (VisitNestedNameSpecifierLoc(QualifierLoc))
765 return true;
766
767 // Visit the declaration name.
768 if (VisitDeclarationNameInfo(ND->getNameInfo()))
769 return true;
770
771 // FIXME: Visit explicitly-specified template arguments!
772
773 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000774 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000775 return true;
776
Bill Wendlingad017fa2012-12-20 19:22:21 +0000777 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000778 }
779
780 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
781 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
782 // Find the initializers that were written in the source.
783 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
784 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
785 IEnd = Constructor->init_end();
786 I != IEnd; ++I) {
787 if (!(*I)->isWritten())
788 continue;
789
790 WrittenInits.push_back(*I);
791 }
792
793 // Sort the initializers in source order
794 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
795 &CompareCXXCtorInitializers);
796
797 // Visit the initializers in source order
798 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
799 CXXCtorInitializer *Init = WrittenInits[I];
800 if (Init->isAnyMemberInitializer()) {
801 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
802 Init->getMemberLocation(), TU)))
803 return true;
804 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
805 if (Visit(TInfo->getTypeLoc()))
806 return true;
807 }
808
809 // Visit the initializer value.
810 if (Expr *Initializer = Init->getInit())
811 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
812 return true;
813 }
814 }
815
816 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
817 return true;
818 }
819
820 return false;
821}
822
823bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
824 if (VisitDeclaratorDecl(D))
825 return true;
826
827 if (Expr *BitWidth = D->getBitWidth())
828 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
829
830 return false;
831}
832
833bool CursorVisitor::VisitVarDecl(VarDecl *D) {
834 if (VisitDeclaratorDecl(D))
835 return true;
836
837 if (Expr *Init = D->getInit())
838 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
839
840 return false;
841}
842
843bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
844 if (VisitDeclaratorDecl(D))
845 return true;
846
847 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
848 if (Expr *DefArg = D->getDefaultArgument())
849 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
850
851 return false;
852}
853
854bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
855 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
856 // before visiting these template parameters.
857 if (VisitTemplateParameters(D->getTemplateParameters()))
858 return true;
859
860 return VisitFunctionDecl(D->getTemplatedDecl());
861}
862
863bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
864 // FIXME: Visit the "outer" template parameter lists on the TagDecl
865 // before visiting these template parameters.
866 if (VisitTemplateParameters(D->getTemplateParameters()))
867 return true;
868
869 return VisitCXXRecordDecl(D->getTemplatedDecl());
870}
871
872bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
873 if (VisitTemplateParameters(D->getTemplateParameters()))
874 return true;
875
876 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
877 VisitTemplateArgumentLoc(D->getDefaultArgument()))
878 return true;
879
880 return false;
881}
882
883bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
884 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
885 if (Visit(TSInfo->getTypeLoc()))
886 return true;
887
888 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
889 PEnd = ND->param_end();
890 P != PEnd; ++P) {
891 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
892 return true;
893 }
894
895 if (ND->isThisDeclarationADefinition() &&
896 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
897 return true;
898
899 return false;
900}
901
902template <typename DeclIt>
903static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
904 SourceManager &SM, SourceLocation EndLoc,
905 SmallVectorImpl<Decl *> &Decls) {
906 DeclIt next = *DI_current;
907 while (++next != DE_current) {
908 Decl *D_next = *next;
909 if (!D_next)
910 break;
911 SourceLocation L = D_next->getLocStart();
912 if (!L.isValid())
913 break;
914 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
915 *DI_current = next;
916 Decls.push_back(D_next);
917 continue;
918 }
919 break;
920 }
921}
922
923namespace {
924 struct ContainerDeclsSort {
925 SourceManager &SM;
926 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
927 bool operator()(Decl *A, Decl *B) {
928 SourceLocation L_A = A->getLocStart();
929 SourceLocation L_B = B->getLocStart();
930 assert(L_A.isValid() && L_B.isValid());
931 return SM.isBeforeInTranslationUnit(L_A, L_B);
932 }
933 };
934}
935
936bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
937 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
938 // an @implementation can lexically contain Decls that are not properly
939 // nested in the AST. When we identify such cases, we need to retrofit
940 // this nesting here.
941 if (!DI_current && !FileDI_current)
942 return VisitDeclContext(D);
943
944 // Scan the Decls that immediately come after the container
945 // in the current DeclContext. If any fall within the
946 // container's lexical region, stash them into a vector
947 // for later processing.
948 SmallVector<Decl *, 24> DeclsInContainer;
949 SourceLocation EndLoc = D->getSourceRange().getEnd();
950 SourceManager &SM = AU->getSourceManager();
951 if (EndLoc.isValid()) {
952 if (DI_current) {
953 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
954 DeclsInContainer);
955 } else {
956 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
957 DeclsInContainer);
958 }
959 }
960
961 // The common case.
962 if (DeclsInContainer.empty())
963 return VisitDeclContext(D);
964
965 // Get all the Decls in the DeclContext, and sort them with the
966 // additional ones we've collected. Then visit them.
967 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
968 I!=E; ++I) {
969 Decl *subDecl = *I;
970 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
971 subDecl->getLocStart().isInvalid())
972 continue;
973 DeclsInContainer.push_back(subDecl);
974 }
975
976 // Now sort the Decls so that they appear in lexical order.
977 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
978 ContainerDeclsSort(SM));
979
980 // Now visit the decls.
981 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
982 E = DeclsInContainer.end(); I != E; ++I) {
983 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +0000984 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000985 if (!V.hasValue())
986 continue;
987 if (!V.getValue())
988 return false;
989 if (Visit(Cursor, true))
990 return true;
991 }
992 return false;
993}
994
995bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
996 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
997 TU)))
998 return true;
999
1000 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1001 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1002 E = ND->protocol_end(); I != E; ++I, ++PL)
1003 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1004 return true;
1005
1006 return VisitObjCContainerDecl(ND);
1007}
1008
1009bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1010 if (!PID->isThisDeclarationADefinition())
1011 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1012
1013 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1014 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1015 E = PID->protocol_end(); I != E; ++I, ++PL)
1016 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1017 return true;
1018
1019 return VisitObjCContainerDecl(PID);
1020}
1021
1022bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1023 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1024 return true;
1025
1026 // FIXME: This implements a workaround with @property declarations also being
1027 // installed in the DeclContext for the @interface. Eventually this code
1028 // should be removed.
1029 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1030 if (!CDecl || !CDecl->IsClassExtension())
1031 return false;
1032
1033 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1034 if (!ID)
1035 return false;
1036
1037 IdentifierInfo *PropertyId = PD->getIdentifier();
1038 ObjCPropertyDecl *prevDecl =
1039 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1040
1041 if (!prevDecl)
1042 return false;
1043
1044 // Visit synthesized methods since they will be skipped when visiting
1045 // the @interface.
1046 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1047 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1048 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1049 return true;
1050
1051 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1052 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1053 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1054 return true;
1055
1056 return false;
1057}
1058
1059bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1060 if (!D->isThisDeclarationADefinition()) {
1061 // Forward declaration is treated like a reference.
1062 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1063 }
1064
1065 // Issue callbacks for super class.
1066 if (D->getSuperClass() &&
1067 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1068 D->getSuperClassLoc(),
1069 TU)))
1070 return true;
1071
1072 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1073 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1074 E = D->protocol_end(); I != E; ++I, ++PL)
1075 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1076 return true;
1077
1078 return VisitObjCContainerDecl(D);
1079}
1080
1081bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1082 return VisitObjCContainerDecl(D);
1083}
1084
1085bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1086 // 'ID' could be null when dealing with invalid code.
1087 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1088 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1089 return true;
1090
1091 return VisitObjCImplDecl(D);
1092}
1093
1094bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1095#if 0
1096 // Issue callbacks for super class.
1097 // FIXME: No source location information!
1098 if (D->getSuperClass() &&
1099 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1100 D->getSuperClassLoc(),
1101 TU)))
1102 return true;
1103#endif
1104
1105 return VisitObjCImplDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1109 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1110 if (PD->isIvarNameSpecified())
1111 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1112
1113 return false;
1114}
1115
1116bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1117 return VisitDeclContext(D);
1118}
1119
1120bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1121 // Visit nested-name-specifier.
1122 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1123 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1124 return true;
1125
1126 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1127 D->getTargetNameLoc(), TU));
1128}
1129
1130bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1131 // Visit nested-name-specifier.
1132 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1133 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1134 return true;
1135 }
1136
1137 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1138 return true;
1139
1140 return VisitDeclarationNameInfo(D->getNameInfo());
1141}
1142
1143bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1144 // Visit nested-name-specifier.
1145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1147 return true;
1148
1149 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1150 D->getIdentLocation(), TU));
1151}
1152
1153bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1154 // Visit nested-name-specifier.
1155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1157 return true;
1158 }
1159
1160 return VisitDeclarationNameInfo(D->getNameInfo());
1161}
1162
1163bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1164 UnresolvedUsingTypenameDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return false;
1171}
1172
1173bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1174 switch (Name.getName().getNameKind()) {
1175 case clang::DeclarationName::Identifier:
1176 case clang::DeclarationName::CXXLiteralOperatorName:
1177 case clang::DeclarationName::CXXOperatorName:
1178 case clang::DeclarationName::CXXUsingDirective:
1179 return false;
1180
1181 case clang::DeclarationName::CXXConstructorName:
1182 case clang::DeclarationName::CXXDestructorName:
1183 case clang::DeclarationName::CXXConversionFunctionName:
1184 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1185 return Visit(TSInfo->getTypeLoc());
1186 return false;
1187
1188 case clang::DeclarationName::ObjCZeroArgSelector:
1189 case clang::DeclarationName::ObjCOneArgSelector:
1190 case clang::DeclarationName::ObjCMultiArgSelector:
1191 // FIXME: Per-identifier location info?
1192 return false;
1193 }
1194
1195 llvm_unreachable("Invalid DeclarationName::Kind!");
1196}
1197
1198bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1199 SourceRange Range) {
1200 // FIXME: This whole routine is a hack to work around the lack of proper
1201 // source information in nested-name-specifiers (PR5791). Since we do have
1202 // a beginning source location, we can visit the first component of the
1203 // nested-name-specifier, if it's a single-token component.
1204 if (!NNS)
1205 return false;
1206
1207 // Get the first component in the nested-name-specifier.
1208 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1209 NNS = Prefix;
1210
1211 switch (NNS->getKind()) {
1212 case NestedNameSpecifier::Namespace:
1213 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1214 TU));
1215
1216 case NestedNameSpecifier::NamespaceAlias:
1217 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1218 Range.getBegin(), TU));
1219
1220 case NestedNameSpecifier::TypeSpec: {
1221 // If the type has a form where we know that the beginning of the source
1222 // range matches up with a reference cursor. Visit the appropriate reference
1223 // cursor.
1224 const Type *T = NNS->getAsType();
1225 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1226 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1227 if (const TagType *Tag = dyn_cast<TagType>(T))
1228 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1229 if (const TemplateSpecializationType *TST
1230 = dyn_cast<TemplateSpecializationType>(T))
1231 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1232 break;
1233 }
1234
1235 case NestedNameSpecifier::TypeSpecWithTemplate:
1236 case NestedNameSpecifier::Global:
1237 case NestedNameSpecifier::Identifier:
1238 break;
1239 }
1240
1241 return false;
1242}
1243
1244bool
1245CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1246 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1247 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1248 Qualifiers.push_back(Qualifier);
1249
1250 while (!Qualifiers.empty()) {
1251 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1252 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1253 switch (NNS->getKind()) {
1254 case NestedNameSpecifier::Namespace:
1255 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1256 Q.getLocalBeginLoc(),
1257 TU)))
1258 return true;
1259
1260 break;
1261
1262 case NestedNameSpecifier::NamespaceAlias:
1263 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1264 Q.getLocalBeginLoc(),
1265 TU)))
1266 return true;
1267
1268 break;
1269
1270 case NestedNameSpecifier::TypeSpec:
1271 case NestedNameSpecifier::TypeSpecWithTemplate:
1272 if (Visit(Q.getTypeLoc()))
1273 return true;
1274
1275 break;
1276
1277 case NestedNameSpecifier::Global:
1278 case NestedNameSpecifier::Identifier:
1279 break;
1280 }
1281 }
1282
1283 return false;
1284}
1285
1286bool CursorVisitor::VisitTemplateParameters(
1287 const TemplateParameterList *Params) {
1288 if (!Params)
1289 return false;
1290
1291 for (TemplateParameterList::const_iterator P = Params->begin(),
1292 PEnd = Params->end();
1293 P != PEnd; ++P) {
1294 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1295 return true;
1296 }
1297
1298 return false;
1299}
1300
1301bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1302 switch (Name.getKind()) {
1303 case TemplateName::Template:
1304 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1305
1306 case TemplateName::OverloadedTemplate:
1307 // Visit the overloaded template set.
1308 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1309 return true;
1310
1311 return false;
1312
1313 case TemplateName::DependentTemplate:
1314 // FIXME: Visit nested-name-specifier.
1315 return false;
1316
1317 case TemplateName::QualifiedTemplate:
1318 // FIXME: Visit nested-name-specifier.
1319 return Visit(MakeCursorTemplateRef(
1320 Name.getAsQualifiedTemplateName()->getDecl(),
1321 Loc, TU));
1322
1323 case TemplateName::SubstTemplateTemplateParm:
1324 return Visit(MakeCursorTemplateRef(
1325 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1326 Loc, TU));
1327
1328 case TemplateName::SubstTemplateTemplateParmPack:
1329 return Visit(MakeCursorTemplateRef(
1330 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1331 Loc, TU));
1332 }
1333
1334 llvm_unreachable("Invalid TemplateName::Kind!");
1335}
1336
1337bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1338 switch (TAL.getArgument().getKind()) {
1339 case TemplateArgument::Null:
1340 case TemplateArgument::Integral:
1341 case TemplateArgument::Pack:
1342 return false;
1343
1344 case TemplateArgument::Type:
1345 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1346 return Visit(TSInfo->getTypeLoc());
1347 return false;
1348
1349 case TemplateArgument::Declaration:
1350 if (Expr *E = TAL.getSourceDeclExpression())
1351 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1352 return false;
1353
1354 case TemplateArgument::NullPtr:
1355 if (Expr *E = TAL.getSourceNullPtrExpression())
1356 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1357 return false;
1358
1359 case TemplateArgument::Expression:
1360 if (Expr *E = TAL.getSourceExpression())
1361 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1362 return false;
1363
1364 case TemplateArgument::Template:
1365 case TemplateArgument::TemplateExpansion:
1366 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1367 return true;
1368
1369 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1370 TAL.getTemplateNameLoc());
1371 }
1372
1373 llvm_unreachable("Invalid TemplateArgument::Kind!");
1374}
1375
1376bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1377 return VisitDeclContext(D);
1378}
1379
1380bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1381 return Visit(TL.getUnqualifiedLoc());
1382}
1383
1384bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1385 ASTContext &Context = AU->getASTContext();
1386
1387 // Some builtin types (such as Objective-C's "id", "sel", and
1388 // "Class") have associated declarations. Create cursors for those.
1389 QualType VisitType;
1390 switch (TL.getTypePtr()->getKind()) {
1391
1392 case BuiltinType::Void:
1393 case BuiltinType::NullPtr:
1394 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001395 case BuiltinType::OCLImage1d:
1396 case BuiltinType::OCLImage1dArray:
1397 case BuiltinType::OCLImage1dBuffer:
1398 case BuiltinType::OCLImage2d:
1399 case BuiltinType::OCLImage2dArray:
1400 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001401 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001402 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001403#define BUILTIN_TYPE(Id, SingletonId)
1404#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1405#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1406#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1407#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1408#include "clang/AST/BuiltinTypes.def"
1409 break;
1410
1411 case BuiltinType::ObjCId:
1412 VisitType = Context.getObjCIdType();
1413 break;
1414
1415 case BuiltinType::ObjCClass:
1416 VisitType = Context.getObjCClassType();
1417 break;
1418
1419 case BuiltinType::ObjCSel:
1420 VisitType = Context.getObjCSelType();
1421 break;
1422 }
1423
1424 if (!VisitType.isNull()) {
1425 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1426 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1427 TU));
1428 }
1429
1430 return false;
1431}
1432
1433bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1434 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1435}
1436
1437bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1438 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1439}
1440
1441bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1442 if (TL.isDefinition())
1443 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1444
1445 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1446}
1447
1448bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1450}
1451
1452bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1453 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1454 return true;
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1460 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1461 return true;
1462
1463 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1464 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1465 TU)))
1466 return true;
1467 }
1468
1469 return false;
1470}
1471
1472bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1473 return Visit(TL.getPointeeLoc());
1474}
1475
1476bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1477 return Visit(TL.getInnerLoc());
1478}
1479
1480bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1481 return Visit(TL.getPointeeLoc());
1482}
1483
1484bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1485 return Visit(TL.getPointeeLoc());
1486}
1487
1488bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1493 return Visit(TL.getPointeeLoc());
1494}
1495
1496bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1501 return Visit(TL.getModifiedLoc());
1502}
1503
1504bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1505 bool SkipResultType) {
1506 if (!SkipResultType && Visit(TL.getResultLoc()))
1507 return true;
1508
1509 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1510 if (Decl *D = TL.getArg(I))
1511 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1512 return true;
1513
1514 return false;
1515}
1516
1517bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1518 if (Visit(TL.getElementLoc()))
1519 return true;
1520
1521 if (Expr *Size = TL.getSizeExpr())
1522 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1523
1524 return false;
1525}
1526
1527bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1528 TemplateSpecializationTypeLoc TL) {
1529 // Visit the template name.
1530 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1531 TL.getTemplateNameLoc()))
1532 return true;
1533
1534 // Visit the template arguments.
1535 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1536 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1537 return true;
1538
1539 return false;
1540}
1541
1542bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1543 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1544}
1545
1546bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1547 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1548 return Visit(TSInfo->getTypeLoc());
1549
1550 return false;
1551}
1552
1553bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1554 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1555 return Visit(TSInfo->getTypeLoc());
1556
1557 return false;
1558}
1559
1560bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1561 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1562 return true;
1563
1564 return false;
1565}
1566
1567bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1568 DependentTemplateSpecializationTypeLoc TL) {
1569 // Visit the nested-name-specifier, if there is one.
1570 if (TL.getQualifierLoc() &&
1571 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1572 return true;
1573
1574 // Visit the template arguments.
1575 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1576 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1577 return true;
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1583 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1584 return true;
1585
1586 return Visit(TL.getNamedTypeLoc());
1587}
1588
1589bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1590 return Visit(TL.getPatternLoc());
1591}
1592
1593bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1594 if (Expr *E = TL.getUnderlyingExpr())
1595 return Visit(MakeCXCursor(E, StmtParent, TU));
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1601 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1602}
1603
1604bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1605 return Visit(TL.getValueLoc());
1606}
1607
1608#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1609bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1610 return Visit##PARENT##Loc(TL); \
1611}
1612
1613DEFAULT_TYPELOC_IMPL(Complex, Type)
1614DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1615DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1616DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1617DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1618DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1619DEFAULT_TYPELOC_IMPL(Vector, Type)
1620DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1621DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1622DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1623DEFAULT_TYPELOC_IMPL(Record, TagType)
1624DEFAULT_TYPELOC_IMPL(Enum, TagType)
1625DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1626DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1627DEFAULT_TYPELOC_IMPL(Auto, Type)
1628
1629bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1630 // Visit the nested-name-specifier, if present.
1631 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1632 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1633 return true;
1634
1635 if (D->isCompleteDefinition()) {
1636 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1637 E = D->bases_end(); I != E; ++I) {
1638 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1639 return true;
1640 }
1641 }
1642
1643 return VisitTagDecl(D);
1644}
1645
1646bool CursorVisitor::VisitAttributes(Decl *D) {
1647 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1648 i != e; ++i)
1649 if (Visit(MakeCXCursor(*i, D, TU)))
1650 return true;
1651
1652 return false;
1653}
1654
1655//===----------------------------------------------------------------------===//
1656// Data-recursive visitor methods.
1657//===----------------------------------------------------------------------===//
1658
1659namespace {
1660#define DEF_JOB(NAME, DATA, KIND)\
1661class NAME : public VisitorJob {\
1662public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001663 NAME(const DATA *d, CXCursor parent) : \
1664 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001665 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001666 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001667};
1668
1669DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1670DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1671DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1672DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1673DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1674 ExplicitTemplateArgsVisitKind)
1675DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1676DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1677DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1678#undef DEF_JOB
1679
1680class DeclVisit : public VisitorJob {
1681public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001682 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001683 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001684 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001685 static bool classof(const VisitorJob *VJ) {
1686 return VJ->getKind() == DeclVisitKind;
1687 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001688 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001689 bool isFirst() const { return data[1] ? true : false; }
1690};
1691class TypeLocVisit : public VisitorJob {
1692public:
1693 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1694 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1695 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1696
1697 static bool classof(const VisitorJob *VJ) {
1698 return VJ->getKind() == TypeLocVisitKind;
1699 }
1700
1701 TypeLoc get() const {
1702 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001703 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001704 }
1705};
1706
1707class LabelRefVisit : public VisitorJob {
1708public:
1709 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1710 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1711 labelLoc.getPtrEncoding()) {}
1712
1713 static bool classof(const VisitorJob *VJ) {
1714 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1715 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001716 const LabelDecl *get() const {
1717 return static_cast<const LabelDecl *>(data[0]);
1718 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001719 SourceLocation getLoc() const {
1720 return SourceLocation::getFromPtrEncoding(data[1]); }
1721};
1722
1723class NestedNameSpecifierLocVisit : public VisitorJob {
1724public:
1725 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1726 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1727 Qualifier.getNestedNameSpecifier(),
1728 Qualifier.getOpaqueData()) { }
1729
1730 static bool classof(const VisitorJob *VJ) {
1731 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1732 }
1733
1734 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001735 return NestedNameSpecifierLoc(
1736 const_cast<NestedNameSpecifier *>(
1737 static_cast<const NestedNameSpecifier *>(data[0])),
1738 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001739 }
1740};
1741
1742class DeclarationNameInfoVisit : public VisitorJob {
1743public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001744 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001745 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001746 static bool classof(const VisitorJob *VJ) {
1747 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1748 }
1749 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001750 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001751 switch (S->getStmtClass()) {
1752 default:
1753 llvm_unreachable("Unhandled Stmt");
1754 case clang::Stmt::MSDependentExistsStmtClass:
1755 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1756 case Stmt::CXXDependentScopeMemberExprClass:
1757 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1758 case Stmt::DependentScopeDeclRefExprClass:
1759 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1760 }
1761 }
1762};
1763class MemberRefVisit : public VisitorJob {
1764public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001765 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001766 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1767 L.getPtrEncoding()) {}
1768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1770 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001771 const FieldDecl *get() const {
1772 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001773 }
1774 SourceLocation getLoc() const {
1775 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1776 }
1777};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001778class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001779 VisitorWorkList &WL;
1780 CXCursor Parent;
1781public:
1782 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1783 : WL(wl), Parent(parent) {}
1784
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001785 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1786 void VisitBlockExpr(const BlockExpr *B);
1787 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1788 void VisitCompoundStmt(const CompoundStmt *S);
1789 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1790 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1791 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1792 void VisitCXXNewExpr(const CXXNewExpr *E);
1793 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1794 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1795 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1796 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1797 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1798 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1799 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1800 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1801 void VisitDeclRefExpr(const DeclRefExpr *D);
1802 void VisitDeclStmt(const DeclStmt *S);
1803 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1804 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1805 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1806 void VisitForStmt(const ForStmt *FS);
1807 void VisitGotoStmt(const GotoStmt *GS);
1808 void VisitIfStmt(const IfStmt *If);
1809 void VisitInitListExpr(const InitListExpr *IE);
1810 void VisitMemberExpr(const MemberExpr *M);
1811 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1812 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1813 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1814 void VisitOverloadExpr(const OverloadExpr *E);
1815 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1816 void VisitStmt(const Stmt *S);
1817 void VisitSwitchStmt(const SwitchStmt *S);
1818 void VisitWhileStmt(const WhileStmt *W);
1819 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1820 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1821 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1822 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1823 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1824 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1825 void VisitVAArgExpr(const VAArgExpr *E);
1826 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1827 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1828 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1829 void VisitLambdaExpr(const LambdaExpr *E);
1830
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001831private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001832 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001833 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1834 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001835 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1836 void AddStmt(const Stmt *S);
1837 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001838 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001839 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001840};
1841} // end anonyous namespace
1842
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001843void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001844 // 'S' should always be non-null, since it comes from the
1845 // statement we are visiting.
1846 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1847}
1848
1849void
1850EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1851 if (Qualifier)
1852 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1853}
1854
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001855void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001856 if (S)
1857 WL.push_back(StmtVisit(S, Parent));
1858}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001859void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001860 if (D)
1861 WL.push_back(DeclVisit(D, Parent, isFirst));
1862}
1863void EnqueueVisitor::
1864 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1865 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001866 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001867}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001868void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001869 if (D)
1870 WL.push_back(MemberRefVisit(D, L, Parent));
1871}
1872void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1873 if (TI)
1874 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1875 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001876void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001877 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001878 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001879 AddStmt(*Child);
1880 }
1881 if (size == WL.size())
1882 return;
1883 // Now reverse the entries we just added. This will match the DFS
1884 // ordering performed by the worklist.
1885 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1886 std::reverse(I, E);
1887}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001888void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001889 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1890}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001891void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001892 AddDecl(B->getBlockDecl());
1893}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001894void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001895 EnqueueChildren(E);
1896 AddTypeLoc(E->getTypeSourceInfo());
1897}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001898void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1899 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 E = S->body_rend(); I != E; ++I) {
1901 AddStmt(*I);
1902 }
1903}
1904void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001905VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001906 AddStmt(S->getSubStmt());
1907 AddDeclarationNameInfo(S);
1908 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1909 AddNestedNameSpecifierLoc(QualifierLoc);
1910}
1911
1912void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001913VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001914 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1915 AddDeclarationNameInfo(E);
1916 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1917 AddNestedNameSpecifierLoc(QualifierLoc);
1918 if (!E->isImplicitAccess())
1919 AddStmt(E->getBase());
1920}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001921void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001922 // Enqueue the initializer , if any.
1923 AddStmt(E->getInitializer());
1924 // Enqueue the array size, if any.
1925 AddStmt(E->getArraySize());
1926 // Enqueue the allocated type.
1927 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1928 // Enqueue the placement arguments.
1929 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1930 AddStmt(E->getPlacementArg(I-1));
1931}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001932void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001933 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1934 AddStmt(CE->getArg(I-1));
1935 AddStmt(CE->getCallee());
1936 AddStmt(CE->getArg(0));
1937}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001938void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1939 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001940 // Visit the name of the type being destroyed.
1941 AddTypeLoc(E->getDestroyedTypeInfo());
1942 // Visit the scope type that looks disturbingly like the nested-name-specifier
1943 // but isn't.
1944 AddTypeLoc(E->getScopeTypeInfo());
1945 // Visit the nested-name-specifier.
1946 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1947 AddNestedNameSpecifierLoc(QualifierLoc);
1948 // Visit base expression.
1949 AddStmt(E->getBase());
1950}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001951void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1952 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001953 AddTypeLoc(E->getTypeSourceInfo());
1954}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001955void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1956 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001957 EnqueueChildren(E);
1958 AddTypeLoc(E->getTypeSourceInfo());
1959}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001961 EnqueueChildren(E);
1962 if (E->isTypeOperand())
1963 AddTypeLoc(E->getTypeOperandSourceInfo());
1964}
1965
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001966void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1967 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001968 EnqueueChildren(E);
1969 AddTypeLoc(E->getTypeSourceInfo());
1970}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001971void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001972 EnqueueChildren(E);
1973 if (E->isTypeOperand())
1974 AddTypeLoc(E->getTypeOperandSourceInfo());
1975}
1976
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001978 EnqueueChildren(S);
1979 AddDecl(S->getExceptionDecl());
1980}
1981
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 if (DR->hasExplicitTemplateArgs()) {
1984 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1985 }
1986 WL.push_back(DeclRefExprParts(DR, Parent));
1987}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001988void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
1989 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001990 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1991 AddDeclarationNameInfo(E);
1992 AddNestedNameSpecifierLoc(E->getQualifierLoc());
1993}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001994void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001995 unsigned size = WL.size();
1996 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001997 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001998 D != DEnd; ++D) {
1999 AddDecl(*D, isFirst);
2000 isFirst = false;
2001 }
2002 if (size == WL.size())
2003 return;
2004 // Now reverse the entries we just added. This will match the DFS
2005 // ordering performed by the worklist.
2006 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2007 std::reverse(I, E);
2008}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002010 AddStmt(E->getInit());
2011 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002012 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002013 D = E->designators_rbegin(), DEnd = E->designators_rend();
2014 D != DEnd; ++D) {
2015 if (D->isFieldDesignator()) {
2016 if (FieldDecl *Field = D->getField())
2017 AddMemberRef(Field, D->getFieldLoc());
2018 continue;
2019 }
2020 if (D->isArrayDesignator()) {
2021 AddStmt(E->getArrayIndex(*D));
2022 continue;
2023 }
2024 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2025 AddStmt(E->getArrayRangeEnd(*D));
2026 AddStmt(E->getArrayRangeStart(*D));
2027 }
2028}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002029void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002030 EnqueueChildren(E);
2031 AddTypeLoc(E->getTypeInfoAsWritten());
2032}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002033void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002034 AddStmt(FS->getBody());
2035 AddStmt(FS->getInc());
2036 AddStmt(FS->getCond());
2037 AddDecl(FS->getConditionVariable());
2038 AddStmt(FS->getInit());
2039}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002041 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2042}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002044 AddStmt(If->getElse());
2045 AddStmt(If->getThen());
2046 AddStmt(If->getCond());
2047 AddDecl(If->getConditionVariable());
2048}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002050 // We care about the syntactic form of the initializer list, only.
2051 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2052 IE = Syntactic;
2053 EnqueueChildren(IE);
2054}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002056 WL.push_back(MemberExprParts(M, Parent));
2057
2058 // If the base of the member access expression is an implicit 'this', don't
2059 // visit it.
2060 // FIXME: If we ever want to show these implicit accesses, this will be
2061 // unfortunate. However, clang_getCursor() relies on this behavior.
2062 if (!M->isImplicitAccess())
2063 AddStmt(M->getBase());
2064}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002066 AddTypeLoc(E->getEncodedTypeSourceInfo());
2067}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002069 EnqueueChildren(M);
2070 AddTypeLoc(M->getClassReceiverTypeInfo());
2071}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002073 // Visit the components of the offsetof expression.
2074 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2075 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2076 const OffsetOfNode &Node = E->getComponent(I-1);
2077 switch (Node.getKind()) {
2078 case OffsetOfNode::Array:
2079 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2080 break;
2081 case OffsetOfNode::Field:
2082 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2083 break;
2084 case OffsetOfNode::Identifier:
2085 case OffsetOfNode::Base:
2086 continue;
2087 }
2088 }
2089 // Visit the type into which we're computing the offset.
2090 AddTypeLoc(E->getTypeSourceInfo());
2091}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002093 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2094 WL.push_back(OverloadExprParts(E, Parent));
2095}
2096void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002097 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002098 EnqueueChildren(E);
2099 if (E->isArgumentType())
2100 AddTypeLoc(E->getArgumentTypeInfo());
2101}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002103 EnqueueChildren(S);
2104}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002106 AddStmt(S->getBody());
2107 AddStmt(S->getCond());
2108 AddDecl(S->getConditionVariable());
2109}
2110
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002112 AddStmt(W->getBody());
2113 AddStmt(W->getCond());
2114 AddDecl(W->getConditionVariable());
2115}
2116
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002118 AddTypeLoc(E->getQueriedTypeSourceInfo());
2119}
2120
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002122 AddTypeLoc(E->getRhsTypeSourceInfo());
2123 AddTypeLoc(E->getLhsTypeSourceInfo());
2124}
2125
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002127 for (unsigned I = E->getNumArgs(); I > 0; --I)
2128 AddTypeLoc(E->getArg(I-1));
2129}
2130
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002132 AddTypeLoc(E->getQueriedTypeSourceInfo());
2133}
2134
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137}
2138
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002140 VisitOverloadExpr(U);
2141 if (!U->isImplicitAccess())
2142 AddStmt(U->getBase());
2143}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002145 AddStmt(E->getSubExpr());
2146 AddTypeLoc(E->getWrittenTypeInfo());
2147}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002149 WL.push_back(SizeOfPackExprParts(E, Parent));
2150}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002152 // If the opaque value has a source expression, just transparently
2153 // visit that. This is useful for (e.g.) pseudo-object expressions.
2154 if (Expr *SourceExpr = E->getSourceExpr())
2155 return Visit(SourceExpr);
2156}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002158 AddStmt(E->getBody());
2159 WL.push_back(LambdaExprParts(E, Parent));
2160}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002162 // Treat the expression like its syntactic form.
2163 Visit(E->getSyntacticForm());
2164}
2165
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2168}
2169
2170bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2171 if (RegionOfInterest.isValid()) {
2172 SourceRange Range = getRawCursorExtent(C);
2173 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2174 return false;
2175 }
2176 return true;
2177}
2178
2179bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2180 while (!WL.empty()) {
2181 // Dequeue the worklist item.
2182 VisitorJob LI = WL.back();
2183 WL.pop_back();
2184
2185 // Set the Parent field, then back to its old value once we're done.
2186 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2187
2188 switch (LI.getKind()) {
2189 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002190 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002191 if (!D)
2192 continue;
2193
2194 // For now, perform default visitation for Decls.
2195 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2196 cast<DeclVisit>(&LI)->isFirst())))
2197 return true;
2198
2199 continue;
2200 }
2201 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2202 const ASTTemplateArgumentListInfo *ArgList =
2203 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2204 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2205 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2206 Arg != ArgEnd; ++Arg) {
2207 if (VisitTemplateArgumentLoc(*Arg))
2208 return true;
2209 }
2210 continue;
2211 }
2212 case VisitorJob::TypeLocVisitKind: {
2213 // Perform default visitation for TypeLocs.
2214 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2215 return true;
2216 continue;
2217 }
2218 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002219 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002220 if (LabelStmt *stmt = LS->getStmt()) {
2221 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2222 TU))) {
2223 return true;
2224 }
2225 }
2226 continue;
2227 }
2228
2229 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2230 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2231 if (VisitNestedNameSpecifierLoc(V->get()))
2232 return true;
2233 continue;
2234 }
2235
2236 case VisitorJob::DeclarationNameInfoVisitKind: {
2237 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2238 ->get()))
2239 return true;
2240 continue;
2241 }
2242 case VisitorJob::MemberRefVisitKind: {
2243 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2244 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2245 return true;
2246 continue;
2247 }
2248 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002249 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002250 if (!S)
2251 continue;
2252
2253 // Update the current cursor.
2254 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2255 if (!IsInRegionOfInterest(Cursor))
2256 continue;
2257 switch (Visitor(Cursor, Parent, ClientData)) {
2258 case CXChildVisit_Break: return true;
2259 case CXChildVisit_Continue: break;
2260 case CXChildVisit_Recurse:
2261 if (PostChildrenVisitor)
2262 WL.push_back(PostChildrenVisit(0, Cursor));
2263 EnqueueWorkList(WL, S);
2264 break;
2265 }
2266 continue;
2267 }
2268 case VisitorJob::MemberExprPartsKind: {
2269 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002270 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002271
2272 // Visit the nested-name-specifier
2273 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2274 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2275 return true;
2276
2277 // Visit the declaration name.
2278 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2279 return true;
2280
2281 // Visit the explicitly-specified template arguments, if any.
2282 if (M->hasExplicitTemplateArgs()) {
2283 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2284 *ArgEnd = Arg + M->getNumTemplateArgs();
2285 Arg != ArgEnd; ++Arg) {
2286 if (VisitTemplateArgumentLoc(*Arg))
2287 return true;
2288 }
2289 }
2290 continue;
2291 }
2292 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002293 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002294 // Visit nested-name-specifier, if present.
2295 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2296 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2297 return true;
2298 // Visit declaration name.
2299 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2300 return true;
2301 continue;
2302 }
2303 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002304 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002305 // Visit the nested-name-specifier.
2306 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2307 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2308 return true;
2309 // Visit the declaration name.
2310 if (VisitDeclarationNameInfo(O->getNameInfo()))
2311 return true;
2312 // Visit the overloaded declaration reference.
2313 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2314 return true;
2315 continue;
2316 }
2317 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002318 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002319 NamedDecl *Pack = E->getPack();
2320 if (isa<TemplateTypeParmDecl>(Pack)) {
2321 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2322 E->getPackLoc(), TU)))
2323 return true;
2324
2325 continue;
2326 }
2327
2328 if (isa<TemplateTemplateParmDecl>(Pack)) {
2329 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2330 E->getPackLoc(), TU)))
2331 return true;
2332
2333 continue;
2334 }
2335
2336 // Non-type template parameter packs and function parameter packs are
2337 // treated like DeclRefExpr cursors.
2338 continue;
2339 }
2340
2341 case VisitorJob::LambdaExprPartsKind: {
2342 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002343 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002344 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2345 CEnd = E->explicit_capture_end();
2346 C != CEnd; ++C) {
2347 if (C->capturesThis())
2348 continue;
2349
2350 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2351 C->getLocation(),
2352 TU)))
2353 return true;
2354 }
2355
2356 // Visit parameters and return type, if present.
2357 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2358 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2359 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2360 // Visit the whole type.
2361 if (Visit(TL))
2362 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002363 } else if (FunctionProtoTypeLoc Proto =
2364 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002365 if (E->hasExplicitParameters()) {
2366 // Visit parameters.
2367 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2368 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2369 return true;
2370 } else {
2371 // Visit result type.
2372 if (Visit(Proto.getResultLoc()))
2373 return true;
2374 }
2375 }
2376 }
2377 break;
2378 }
2379
2380 case VisitorJob::PostChildrenVisitKind:
2381 if (PostChildrenVisitor(Parent, ClientData))
2382 return true;
2383 break;
2384 }
2385 }
2386 return false;
2387}
2388
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002389bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002390 VisitorWorkList *WL = 0;
2391 if (!WorkListFreeList.empty()) {
2392 WL = WorkListFreeList.back();
2393 WL->clear();
2394 WorkListFreeList.pop_back();
2395 }
2396 else {
2397 WL = new VisitorWorkList();
2398 WorkListCache.push_back(WL);
2399 }
2400 EnqueueWorkList(*WL, S);
2401 bool result = RunVisitorWorkList(*WL);
2402 WorkListFreeList.push_back(WL);
2403 return result;
2404}
2405
2406namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002407typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002408RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2409 const DeclarationNameInfo &NI,
2410 const SourceRange &QLoc,
2411 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2412 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2413 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2414 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2415
2416 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2417
2418 RefNamePieces Pieces;
2419
2420 if (WantQualifier && QLoc.isValid())
2421 Pieces.push_back(QLoc);
2422
2423 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2424 Pieces.push_back(NI.getLoc());
2425
2426 if (WantTemplateArgs && TemplateArgs)
2427 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2428 TemplateArgs->RAngleLoc));
2429
2430 if (Kind == DeclarationName::CXXOperatorName) {
2431 Pieces.push_back(SourceLocation::getFromRawEncoding(
2432 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2433 Pieces.push_back(SourceLocation::getFromRawEncoding(
2434 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2435 }
2436
2437 if (WantSinglePiece) {
2438 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2439 Pieces.clear();
2440 Pieces.push_back(R);
2441 }
2442
2443 return Pieces;
2444}
2445}
2446
2447//===----------------------------------------------------------------------===//
2448// Misc. API hooks.
2449//===----------------------------------------------------------------------===//
2450
2451static llvm::sys::Mutex EnableMultithreadingMutex;
2452static bool EnabledMultithreading;
2453
2454static void fatal_error_handler(void *user_data, const std::string& reason) {
2455 // Write the result out to stderr avoiding errs() because raw_ostreams can
2456 // call report_fatal_error.
2457 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2458 ::abort();
2459}
2460
2461extern "C" {
2462CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2463 int displayDiagnostics) {
2464 // Disable pretty stack trace functionality, which will otherwise be a very
2465 // poor citizen of the world and set up all sorts of signal handlers.
2466 llvm::DisablePrettyStackTrace = true;
2467
2468 // We use crash recovery to make some of our APIs more reliable, implicitly
2469 // enable it.
2470 llvm::CrashRecoveryContext::Enable();
2471
2472 // Enable support for multithreading in LLVM.
2473 {
2474 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2475 if (!EnabledMultithreading) {
2476 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2477 llvm::llvm_start_multithreaded();
2478 EnabledMultithreading = true;
2479 }
2480 }
2481
2482 CIndexer *CIdxr = new CIndexer();
2483 if (excludeDeclarationsFromPCH)
2484 CIdxr->setOnlyLocalDecls();
2485 if (displayDiagnostics)
2486 CIdxr->setDisplayDiagnostics();
2487
2488 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2489 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2490 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2491 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2492 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2493 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2494
2495 return CIdxr;
2496}
2497
2498void clang_disposeIndex(CXIndex CIdx) {
2499 if (CIdx)
2500 delete static_cast<CIndexer *>(CIdx);
2501}
2502
2503void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2504 if (CIdx)
2505 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2506}
2507
2508unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2509 if (CIdx)
2510 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2511 return 0;
2512}
2513
2514void clang_toggleCrashRecovery(unsigned isEnabled) {
2515 if (isEnabled)
2516 llvm::CrashRecoveryContext::Enable();
2517 else
2518 llvm::CrashRecoveryContext::Disable();
2519}
2520
2521CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2522 const char *ast_filename) {
2523 if (!CIdx)
2524 return 0;
2525
2526 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2527 FileSystemOptions FileSystemOpts;
2528
2529 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2530 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2531 CXXIdx->getOnlyLocalDecls(),
2532 0, 0,
2533 /*CaptureDiagnostics=*/true,
2534 /*AllowPCHWithCompilerErrors=*/true,
2535 /*UserFilesAreVolatile=*/true);
2536 return MakeCXTranslationUnit(CXXIdx, TU);
2537}
2538
2539unsigned clang_defaultEditingTranslationUnitOptions() {
2540 return CXTranslationUnit_PrecompiledPreamble |
2541 CXTranslationUnit_CacheCompletionResults;
2542}
2543
2544CXTranslationUnit
2545clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2546 const char *source_filename,
2547 int num_command_line_args,
2548 const char * const *command_line_args,
2549 unsigned num_unsaved_files,
2550 struct CXUnsavedFile *unsaved_files) {
2551 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2552 return clang_parseTranslationUnit(CIdx, source_filename,
2553 command_line_args, num_command_line_args,
2554 unsaved_files, num_unsaved_files,
2555 Options);
2556}
2557
2558struct ParseTranslationUnitInfo {
2559 CXIndex CIdx;
2560 const char *source_filename;
2561 const char *const *command_line_args;
2562 int num_command_line_args;
2563 struct CXUnsavedFile *unsaved_files;
2564 unsigned num_unsaved_files;
2565 unsigned options;
2566 CXTranslationUnit result;
2567};
2568static void clang_parseTranslationUnit_Impl(void *UserData) {
2569 ParseTranslationUnitInfo *PTUI =
2570 static_cast<ParseTranslationUnitInfo*>(UserData);
2571 CXIndex CIdx = PTUI->CIdx;
2572 const char *source_filename = PTUI->source_filename;
2573 const char * const *command_line_args = PTUI->command_line_args;
2574 int num_command_line_args = PTUI->num_command_line_args;
2575 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2576 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2577 unsigned options = PTUI->options;
2578 PTUI->result = 0;
2579
2580 if (!CIdx)
2581 return;
2582
2583 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2584
2585 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2586 setThreadBackgroundPriority();
2587
2588 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2589 // FIXME: Add a flag for modules.
2590 TranslationUnitKind TUKind
2591 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2592 bool CacheCodeCompetionResults
2593 = options & CXTranslationUnit_CacheCompletionResults;
2594 bool IncludeBriefCommentsInCodeCompletion
2595 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2596 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2597 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2598
2599 // Configure the diagnostics.
2600 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002601 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002602
2603 // Recover resources if we crash before exiting this function.
2604 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2605 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2606 DiagCleanup(Diags.getPtr());
2607
2608 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2609 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2610
2611 // Recover resources if we crash before exiting this function.
2612 llvm::CrashRecoveryContextCleanupRegistrar<
2613 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2614
2615 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2616 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2617 const llvm::MemoryBuffer *Buffer
2618 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2619 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2620 Buffer));
2621 }
2622
2623 OwningPtr<std::vector<const char *> >
2624 Args(new std::vector<const char*>());
2625
2626 // Recover resources if we crash before exiting this method.
2627 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2628 ArgsCleanup(Args.get());
2629
2630 // Since the Clang C library is primarily used by batch tools dealing with
2631 // (often very broken) source code, where spell-checking can have a
2632 // significant negative impact on performance (particularly when
2633 // precompiled headers are involved), we disable it by default.
2634 // Only do this if we haven't found a spell-checking-related argument.
2635 bool FoundSpellCheckingArgument = false;
2636 for (int I = 0; I != num_command_line_args; ++I) {
2637 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2638 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2639 FoundSpellCheckingArgument = true;
2640 break;
2641 }
2642 }
2643 if (!FoundSpellCheckingArgument)
2644 Args->push_back("-fno-spell-checking");
2645
2646 Args->insert(Args->end(), command_line_args,
2647 command_line_args + num_command_line_args);
2648
2649 // The 'source_filename' argument is optional. If the caller does not
2650 // specify it then it is assumed that the source file is specified
2651 // in the actual argument list.
2652 // Put the source file after command_line_args otherwise if '-x' flag is
2653 // present it will be unused.
2654 if (source_filename)
2655 Args->push_back(source_filename);
2656
2657 // Do we need the detailed preprocessing record?
2658 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2659 Args->push_back("-Xclang");
2660 Args->push_back("-detailed-preprocessing-record");
2661 }
2662
2663 unsigned NumErrors = Diags->getClient()->getNumErrors();
2664 OwningPtr<ASTUnit> ErrUnit;
2665 OwningPtr<ASTUnit> Unit(
2666 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2667 /* vector::data() not portable */,
2668 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2669 Diags,
2670 CXXIdx->getClangResourcesPath(),
2671 CXXIdx->getOnlyLocalDecls(),
2672 /*CaptureDiagnostics=*/true,
2673 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2674 RemappedFiles->size(),
2675 /*RemappedFilesKeepOriginalName=*/true,
2676 PrecompilePreamble,
2677 TUKind,
2678 CacheCodeCompetionResults,
2679 IncludeBriefCommentsInCodeCompletion,
2680 /*AllowPCHWithCompilerErrors=*/true,
2681 SkipFunctionBodies,
2682 /*UserFilesAreVolatile=*/true,
2683 ForSerialization,
2684 &ErrUnit));
2685
2686 if (NumErrors != Diags->getClient()->getNumErrors()) {
2687 // Make sure to check that 'Unit' is non-NULL.
2688 if (CXXIdx->getDisplayDiagnostics())
2689 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2690 }
2691
2692 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2693}
2694CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2695 const char *source_filename,
2696 const char * const *command_line_args,
2697 int num_command_line_args,
2698 struct CXUnsavedFile *unsaved_files,
2699 unsigned num_unsaved_files,
2700 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002701 LOG_FUNC_SECTION {
2702 *Log << source_filename << ": ";
2703 for (int i = 0; i != num_command_line_args; ++i)
2704 *Log << command_line_args[i] << " ";
2705 }
2706
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002707 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2708 num_command_line_args, unsaved_files,
2709 num_unsaved_files, options, 0 };
2710 llvm::CrashRecoveryContext CRC;
2711
2712 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2713 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2714 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2715 fprintf(stderr, " 'command_line_args' : [");
2716 for (int i = 0; i != num_command_line_args; ++i) {
2717 if (i)
2718 fprintf(stderr, ", ");
2719 fprintf(stderr, "'%s'", command_line_args[i]);
2720 }
2721 fprintf(stderr, "],\n");
2722 fprintf(stderr, " 'unsaved_files' : [");
2723 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2724 if (i)
2725 fprintf(stderr, ", ");
2726 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2727 unsaved_files[i].Length);
2728 }
2729 fprintf(stderr, "],\n");
2730 fprintf(stderr, " 'options' : %d,\n", options);
2731 fprintf(stderr, "}\n");
2732
2733 return 0;
2734 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2735 PrintLibclangResourceUsage(PTUI.result);
2736 }
2737
2738 return PTUI.result;
2739}
2740
2741unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2742 return CXSaveTranslationUnit_None;
2743}
2744
2745namespace {
2746
2747struct SaveTranslationUnitInfo {
2748 CXTranslationUnit TU;
2749 const char *FileName;
2750 unsigned options;
2751 CXSaveError result;
2752};
2753
2754}
2755
2756static void clang_saveTranslationUnit_Impl(void *UserData) {
2757 SaveTranslationUnitInfo *STUI =
2758 static_cast<SaveTranslationUnitInfo*>(UserData);
2759
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002760 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002761 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2762 setThreadBackgroundPriority();
2763
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002764 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002765 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2766}
2767
2768int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2769 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002770 LOG_FUNC_SECTION {
2771 *Log << TU << ' ' << FileName;
2772 }
2773
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002774 if (!TU)
2775 return CXSaveError_InvalidTU;
2776
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002777 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002778 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2779 if (!CXXUnit->hasSema())
2780 return CXSaveError_InvalidTU;
2781
2782 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2783
2784 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2785 getenv("LIBCLANG_NOTHREADS")) {
2786 clang_saveTranslationUnit_Impl(&STUI);
2787
2788 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2789 PrintLibclangResourceUsage(TU);
2790
2791 return STUI.result;
2792 }
2793
2794 // We have an AST that has invalid nodes due to compiler errors.
2795 // Use a crash recovery thread for protection.
2796
2797 llvm::CrashRecoveryContext CRC;
2798
2799 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2800 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2801 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2802 fprintf(stderr, " 'options' : %d,\n", options);
2803 fprintf(stderr, "}\n");
2804
2805 return CXSaveError_Unknown;
2806
2807 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2808 PrintLibclangResourceUsage(TU);
2809 }
2810
2811 return STUI.result;
2812}
2813
2814void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2815 if (CTUnit) {
2816 // If the translation unit has been marked as unsafe to free, just discard
2817 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002818 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002819 return;
2820
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002821 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002822 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002823 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2824 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002825 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002826 delete CTUnit;
2827 }
2828}
2829
2830unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2831 return CXReparse_None;
2832}
2833
2834struct ReparseTranslationUnitInfo {
2835 CXTranslationUnit TU;
2836 unsigned num_unsaved_files;
2837 struct CXUnsavedFile *unsaved_files;
2838 unsigned options;
2839 int result;
2840};
2841
2842static void clang_reparseTranslationUnit_Impl(void *UserData) {
2843 ReparseTranslationUnitInfo *RTUI =
2844 static_cast<ReparseTranslationUnitInfo*>(UserData);
2845 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002846 if (!TU)
2847 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002848
2849 // Reset the associated diagnostics.
2850 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2851 TU->Diagnostics = 0;
2852
2853 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2854 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2855 unsigned options = RTUI->options;
2856 (void) options;
2857 RTUI->result = 1;
2858
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002859 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002860 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2861 setThreadBackgroundPriority();
2862
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002863 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002864 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2865
2866 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2867 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2868
2869 // Recover resources if we crash before exiting this function.
2870 llvm::CrashRecoveryContextCleanupRegistrar<
2871 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2872
2873 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2874 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2875 const llvm::MemoryBuffer *Buffer
2876 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2877 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2878 Buffer));
2879 }
2880
2881 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2882 RemappedFiles->size()))
2883 RTUI->result = 0;
2884}
2885
2886int clang_reparseTranslationUnit(CXTranslationUnit TU,
2887 unsigned num_unsaved_files,
2888 struct CXUnsavedFile *unsaved_files,
2889 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002890 LOG_FUNC_SECTION {
2891 *Log << TU;
2892 }
2893
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002894 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2895 options, 0 };
2896
2897 if (getenv("LIBCLANG_NOTHREADS")) {
2898 clang_reparseTranslationUnit_Impl(&RTUI);
2899 return RTUI.result;
2900 }
2901
2902 llvm::CrashRecoveryContext CRC;
2903
2904 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2905 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002906 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002907 return 1;
2908 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2909 PrintLibclangResourceUsage(TU);
2910
2911 return RTUI.result;
2912}
2913
2914
2915CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2916 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002917 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002918
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002919 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002920 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002921}
2922
2923CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002925 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2926}
2927
2928} // end: extern "C"
2929
2930//===----------------------------------------------------------------------===//
2931// CXFile Operations.
2932//===----------------------------------------------------------------------===//
2933
2934extern "C" {
2935CXString clang_getFileName(CXFile SFile) {
2936 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002937 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002938
2939 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002940 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002941}
2942
2943time_t clang_getFileTime(CXFile SFile) {
2944 if (!SFile)
2945 return 0;
2946
2947 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2948 return FEnt->getModificationTime();
2949}
2950
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002951CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2952 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002953 return 0;
2954
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002955 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002956
2957 FileManager &FMgr = CXXUnit->getFileManager();
2958 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2959}
2960
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002961unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2962 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002963 return 0;
2964
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002965 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002966 FileEntry *FEnt = static_cast<FileEntry *>(file);
2967 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2968 .isFileMultipleIncludeGuarded(FEnt);
2969}
2970
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002971int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2972 if (!file || !outID)
2973 return 1;
2974
2975#ifdef LLVM_ON_WIN32
2976 return 1; // inodes not supported on windows.
2977#else
2978 FileEntry *FEnt = static_cast<FileEntry *>(file);
2979 outID->data[0] = FEnt->getDevice();
2980 outID->data[1] = FEnt->getInode();
2981 outID->data[2] = FEnt->getModificationTime();
2982 return 0;
2983#endif
2984}
2985
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002986} // end: extern "C"
2987
2988//===----------------------------------------------------------------------===//
2989// CXCursor Operations.
2990//===----------------------------------------------------------------------===//
2991
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002992static const Decl *getDeclFromExpr(const Stmt *E) {
2993 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002994 return getDeclFromExpr(CE->getSubExpr());
2995
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002996 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002997 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002998 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002999 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003000 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003001 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003002 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003003 if (PRE->isExplicitProperty())
3004 return PRE->getExplicitProperty();
3005 // It could be messaging both getter and setter as in:
3006 // ++myobj.myprop;
3007 // in which case prefer to associate the setter since it is less obvious
3008 // from inspecting the source that the setter is going to get called.
3009 if (PRE->isMessagingSetter())
3010 return PRE->getImplicitPropertySetter();
3011 return PRE->getImplicitPropertyGetter();
3012 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003013 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003014 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003015 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003016 if (Expr *Src = OVE->getSourceExpr())
3017 return getDeclFromExpr(Src);
3018
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003019 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003020 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003021 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003022 if (!CE->isElidable())
3023 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003024 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003025 return OME->getMethodDecl();
3026
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003027 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003028 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003029 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003030 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3031 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003032 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003033 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3034 isa<ParmVarDecl>(SizeOfPack->getPack()))
3035 return SizeOfPack->getPack();
3036
3037 return 0;
3038}
3039
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003040static SourceLocation getLocationFromExpr(const Expr *E) {
3041 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003042 return getLocationFromExpr(CE->getSubExpr());
3043
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003044 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003045 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003046 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003047 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003048 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003049 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003050 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003052 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003053 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003054 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003055 return PropRef->getLocation();
3056
3057 return E->getLocStart();
3058}
3059
3060extern "C" {
3061
3062unsigned clang_visitChildren(CXCursor parent,
3063 CXCursorVisitor visitor,
3064 CXClientData client_data) {
3065 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3066 /*VisitPreprocessorLast=*/false);
3067 return CursorVis.VisitChildren(parent);
3068}
3069
3070#ifndef __has_feature
3071#define __has_feature(x) 0
3072#endif
3073#if __has_feature(blocks)
3074typedef enum CXChildVisitResult
3075 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3076
3077static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3078 CXClientData client_data) {
3079 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3080 return block(cursor, parent);
3081}
3082#else
3083// If we are compiled with a compiler that doesn't have native blocks support,
3084// define and call the block manually, so the
3085typedef struct _CXChildVisitResult
3086{
3087 void *isa;
3088 int flags;
3089 int reserved;
3090 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3091 CXCursor);
3092} *CXCursorVisitorBlock;
3093
3094static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3095 CXClientData client_data) {
3096 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3097 return block->invoke(block, cursor, parent);
3098}
3099#endif
3100
3101
3102unsigned clang_visitChildrenWithBlock(CXCursor parent,
3103 CXCursorVisitorBlock block) {
3104 return clang_visitChildren(parent, visitWithBlock, block);
3105}
3106
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003107static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003108 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003109 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003110
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003111 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003112 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003113 if (const ObjCPropertyImplDecl *PropImpl =
3114 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003115 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003116 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003117
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003118 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003119 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003120 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003121
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003122 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003123 }
3124
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003125 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003126 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003127
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003128 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003129 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3130 // and returns different names. NamedDecl returns the class name and
3131 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003132 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133
3134 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003135 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003136
3137 SmallString<1024> S;
3138 llvm::raw_svector_ostream os(S);
3139 ND->printName(os);
3140
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003141 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003142}
3143
3144CXString clang_getCursorSpelling(CXCursor C) {
3145 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003146 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003147
3148 if (clang_isReference(C.kind)) {
3149 switch (C.kind) {
3150 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003151 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003152 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003153 }
3154 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003155 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003156 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003157 }
3158 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003159 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003160 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003161 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003162 }
3163 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003164 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003165 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003166 }
3167 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003168 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003169 assert(Type && "Missing type decl");
3170
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003171 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003172 getAsString());
3173 }
3174 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003175 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003176 assert(Template && "Missing template decl");
3177
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003178 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003179 }
3180
3181 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003182 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003183 assert(NS && "Missing namespace decl");
3184
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003185 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003186 }
3187
3188 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003189 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003190 assert(Field && "Missing member decl");
3191
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003192 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003193 }
3194
3195 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003196 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197 assert(Label && "Missing label");
3198
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003199 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003200 }
3201
3202 case CXCursor_OverloadedDeclRef: {
3203 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003204 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3205 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003206 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003207 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003208 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003209 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003210 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003211 OverloadedTemplateStorage *Ovl
3212 = Storage.get<OverloadedTemplateStorage*>();
3213 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003214 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003215 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003216 }
3217
3218 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003219 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003220 assert(Var && "Missing variable decl");
3221
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003222 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003223 }
3224
3225 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003226 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003227 }
3228 }
3229
3230 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003231 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003232 if (D)
3233 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003234 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003235 }
3236
3237 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003238 const Stmt *S = getCursorStmt(C);
3239 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003240 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003241
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003242 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003243 }
3244
3245 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003246 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003247 ->getNameStart());
3248
3249 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003250 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003251 ->getNameStart());
3252
3253 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003254 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003255
3256 if (clang_isDeclaration(C.kind))
3257 return getDeclSpelling(getCursorDecl(C));
3258
3259 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003260 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003261 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003262 }
3263
3264 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003265 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003266 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003267 }
3268
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003269 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003270}
3271
3272CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3273 unsigned pieceIndex,
3274 unsigned options) {
3275 if (clang_Cursor_isNull(C))
3276 return clang_getNullRange();
3277
3278 ASTContext &Ctx = getCursorContext(C);
3279
3280 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003281 const Stmt *S = getCursorStmt(C);
3282 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003283 if (pieceIndex > 0)
3284 return clang_getNullRange();
3285 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3286 }
3287
3288 return clang_getNullRange();
3289 }
3290
3291 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003292 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3294 if (pieceIndex >= ME->getNumSelectorLocs())
3295 return clang_getNullRange();
3296 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3297 }
3298 }
3299
3300 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3301 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003302 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003303 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3304 if (pieceIndex >= MD->getNumSelectorLocs())
3305 return clang_getNullRange();
3306 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3307 }
3308 }
3309
3310 if (C.kind == CXCursor_ObjCCategoryDecl ||
3311 C.kind == CXCursor_ObjCCategoryImplDecl) {
3312 if (pieceIndex > 0)
3313 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003314 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003315 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3316 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003317 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003318 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3319 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3320 }
3321
3322 if (C.kind == CXCursor_ModuleImportDecl) {
3323 if (pieceIndex > 0)
3324 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003325 if (const ImportDecl *ImportD =
3326 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003327 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3328 if (!Locs.empty())
3329 return cxloc::translateSourceRange(Ctx,
3330 SourceRange(Locs.front(), Locs.back()));
3331 }
3332 return clang_getNullRange();
3333 }
3334
3335 // FIXME: A CXCursor_InclusionDirective should give the location of the
3336 // filename, but we don't keep track of this.
3337
3338 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3339 // but we don't keep track of this.
3340
3341 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3342 // but we don't keep track of this.
3343
3344 // Default handling, give the location of the cursor.
3345
3346 if (pieceIndex > 0)
3347 return clang_getNullRange();
3348
3349 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3350 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3351 return cxloc::translateSourceRange(Ctx, Loc);
3352}
3353
3354CXString clang_getCursorDisplayName(CXCursor C) {
3355 if (!clang_isDeclaration(C.kind))
3356 return clang_getCursorSpelling(C);
3357
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003358 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003359 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003360 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003361
3362 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003363 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003364 D = FunTmpl->getTemplatedDecl();
3365
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003366 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003367 SmallString<64> Str;
3368 llvm::raw_svector_ostream OS(Str);
3369 OS << *Function;
3370 if (Function->getPrimaryTemplate())
3371 OS << "<>";
3372 OS << "(";
3373 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3374 if (I)
3375 OS << ", ";
3376 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3377 }
3378
3379 if (Function->isVariadic()) {
3380 if (Function->getNumParams())
3381 OS << ", ";
3382 OS << "...";
3383 }
3384 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003385 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003386 }
3387
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003388 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003389 SmallString<64> Str;
3390 llvm::raw_svector_ostream OS(Str);
3391 OS << *ClassTemplate;
3392 OS << "<";
3393 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3394 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3395 if (I)
3396 OS << ", ";
3397
3398 NamedDecl *Param = Params->getParam(I);
3399 if (Param->getIdentifier()) {
3400 OS << Param->getIdentifier()->getName();
3401 continue;
3402 }
3403
3404 // There is no parameter name, which makes this tricky. Try to come up
3405 // with something useful that isn't too long.
3406 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3407 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3408 else if (NonTypeTemplateParmDecl *NTTP
3409 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3410 OS << NTTP->getType().getAsString(Policy);
3411 else
3412 OS << "template<...> class";
3413 }
3414
3415 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003416 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003417 }
3418
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003419 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003420 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3421 // If the type was explicitly written, use that.
3422 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003423 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003424
Benjamin Kramer5eada842013-02-22 15:46:01 +00003425 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003426 llvm::raw_svector_ostream OS(Str);
3427 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003428 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003429 ClassSpec->getTemplateArgs().data(),
3430 ClassSpec->getTemplateArgs().size(),
3431 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003432 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003433 }
3434
3435 return clang_getCursorSpelling(C);
3436}
3437
3438CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3439 switch (Kind) {
3440 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003441 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003442 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003443 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003444 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003445 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003446 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003447 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003448 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003449 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003450 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003451 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003452 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003453 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003454 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003455 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003456 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003457 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003458 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003459 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003460 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003461 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003462 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003463 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003464 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003465 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003466 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003467 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003468 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003469 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003470 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003471 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003472 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003473 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003474 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003475 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003476 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003477 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003478 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003479 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003480 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003481 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003482 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003483 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003484 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003485 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003486 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003487 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003488 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003489 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003490 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003491 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003492 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003493 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003494 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003495 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003496 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003497 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003498 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003499 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003500 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003501 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003502 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003503 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003504 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003505 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003506 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003507 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003508 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003509 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003511 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003512 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003513 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003514 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003515 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003516 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003517 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003518 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003519 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003520 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003521 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003522 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003523 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003524 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003525 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003526 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("ObjCBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 }
3733
3734 llvm_unreachable("Unhandled CXCursorKind");
3735}
3736
3737struct GetCursorData {
3738 SourceLocation TokenBeginLoc;
3739 bool PointsAtMacroArgExpansion;
3740 bool VisitedObjCPropertyImplDecl;
3741 SourceLocation VisitedDeclaratorDeclStartLoc;
3742 CXCursor &BestCursor;
3743
3744 GetCursorData(SourceManager &SM,
3745 SourceLocation tokenBegin, CXCursor &outputCursor)
3746 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3747 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3748 VisitedObjCPropertyImplDecl = false;
3749 }
3750};
3751
3752static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3753 CXCursor parent,
3754 CXClientData client_data) {
3755 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3756 CXCursor *BestCursor = &Data->BestCursor;
3757
3758 // If we point inside a macro argument we should provide info of what the
3759 // token is so use the actual cursor, don't replace it with a macro expansion
3760 // cursor.
3761 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3762 return CXChildVisit_Recurse;
3763
3764 if (clang_isDeclaration(cursor.kind)) {
3765 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003766 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003767 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3768 if (MD->isImplicit())
3769 return CXChildVisit_Break;
3770
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003771 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003772 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3773 // Check that when we have multiple @class references in the same line,
3774 // that later ones do not override the previous ones.
3775 // If we have:
3776 // @class Foo, Bar;
3777 // source ranges for both start at '@', so 'Bar' will end up overriding
3778 // 'Foo' even though the cursor location was at 'Foo'.
3779 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3780 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003781 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003782 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3783 if (PrevID != ID &&
3784 !PrevID->isThisDeclarationADefinition() &&
3785 !ID->isThisDeclarationADefinition())
3786 return CXChildVisit_Break;
3787 }
3788
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003789 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003790 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3791 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3792 // Check that when we have multiple declarators in the same line,
3793 // that later ones do not override the previous ones.
3794 // If we have:
3795 // int Foo, Bar;
3796 // source ranges for both start at 'int', so 'Bar' will end up overriding
3797 // 'Foo' even though the cursor location was at 'Foo'.
3798 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3799 return CXChildVisit_Break;
3800 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3801
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003802 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003803 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3804 (void)PropImp;
3805 // Check that when we have multiple @synthesize in the same line,
3806 // that later ones do not override the previous ones.
3807 // If we have:
3808 // @synthesize Foo, Bar;
3809 // source ranges for both start at '@', so 'Bar' will end up overriding
3810 // 'Foo' even though the cursor location was at 'Foo'.
3811 if (Data->VisitedObjCPropertyImplDecl)
3812 return CXChildVisit_Break;
3813 Data->VisitedObjCPropertyImplDecl = true;
3814 }
3815 }
3816
3817 if (clang_isExpression(cursor.kind) &&
3818 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003819 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003820 // Avoid having the cursor of an expression replace the declaration cursor
3821 // when the expression source range overlaps the declaration range.
3822 // This can happen for C++ constructor expressions whose range generally
3823 // include the variable declaration, e.g.:
3824 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3825 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3826 D->getLocation() == Data->TokenBeginLoc)
3827 return CXChildVisit_Break;
3828 }
3829 }
3830
3831 // If our current best cursor is the construction of a temporary object,
3832 // don't replace that cursor with a type reference, because we want
3833 // clang_getCursor() to point at the constructor.
3834 if (clang_isExpression(BestCursor->kind) &&
3835 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3836 cursor.kind == CXCursor_TypeRef) {
3837 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3838 // as having the actual point on the type reference.
3839 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3840 return CXChildVisit_Recurse;
3841 }
3842
3843 *BestCursor = cursor;
3844 return CXChildVisit_Recurse;
3845}
3846
3847CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3848 if (!TU)
3849 return clang_getNullCursor();
3850
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003851 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003852 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3853
3854 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3855 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3856
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003857 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003858 CXFile SearchFile;
3859 unsigned SearchLine, SearchColumn;
3860 CXFile ResultFile;
3861 unsigned ResultLine, ResultColumn;
3862 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3863 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3864 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3865
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003866 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3867 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003868 &ResultColumn, 0);
3869 SearchFileName = clang_getFileName(SearchFile);
3870 ResultFileName = clang_getFileName(ResultFile);
3871 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3872 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003873 *Log << llvm::format("(%s:%d:%d) = %s",
3874 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3875 clang_getCString(KindSpelling))
3876 << llvm::format("(%s:%d:%d):%s%s",
3877 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3878 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003879 clang_disposeString(SearchFileName);
3880 clang_disposeString(ResultFileName);
3881 clang_disposeString(KindSpelling);
3882 clang_disposeString(USR);
3883
3884 CXCursor Definition = clang_getCursorDefinition(Result);
3885 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3886 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3887 CXString DefinitionKindSpelling
3888 = clang_getCursorKindSpelling(Definition.kind);
3889 CXFile DefinitionFile;
3890 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003891 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003892 &DefinitionLine, &DefinitionColumn, 0);
3893 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003894 *Log << llvm::format(" -> %s(%s:%d:%d)",
3895 clang_getCString(DefinitionKindSpelling),
3896 clang_getCString(DefinitionFileName),
3897 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003898 clang_disposeString(DefinitionFileName);
3899 clang_disposeString(DefinitionKindSpelling);
3900 }
3901 }
3902
3903 return Result;
3904}
3905
3906CXCursor clang_getNullCursor(void) {
3907 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3908}
3909
3910unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003911 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3912 // can't set consistently. For example, when visiting a DeclStmt we will set
3913 // it but we don't set it on the result of clang_getCursorDefinition for
3914 // a reference of the same declaration.
3915 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3916 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3917 // to provide that kind of info.
3918 if (clang_isDeclaration(X.kind))
3919 X.data[1] = 0;
3920 if (clang_isDeclaration(Y.kind))
3921 Y.data[1] = 0;
3922
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003923 return X == Y;
3924}
3925
3926unsigned clang_hashCursor(CXCursor C) {
3927 unsigned Index = 0;
3928 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3929 Index = 1;
3930
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003931 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003932 std::make_pair(C.kind, C.data[Index]));
3933}
3934
3935unsigned clang_isInvalid(enum CXCursorKind K) {
3936 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3937}
3938
3939unsigned clang_isDeclaration(enum CXCursorKind K) {
3940 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3941 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3942}
3943
3944unsigned clang_isReference(enum CXCursorKind K) {
3945 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3946}
3947
3948unsigned clang_isExpression(enum CXCursorKind K) {
3949 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3950}
3951
3952unsigned clang_isStatement(enum CXCursorKind K) {
3953 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3954}
3955
3956unsigned clang_isAttribute(enum CXCursorKind K) {
3957 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3958}
3959
3960unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3961 return K == CXCursor_TranslationUnit;
3962}
3963
3964unsigned clang_isPreprocessing(enum CXCursorKind K) {
3965 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3966}
3967
3968unsigned clang_isUnexposed(enum CXCursorKind K) {
3969 switch (K) {
3970 case CXCursor_UnexposedDecl:
3971 case CXCursor_UnexposedExpr:
3972 case CXCursor_UnexposedStmt:
3973 case CXCursor_UnexposedAttr:
3974 return true;
3975 default:
3976 return false;
3977 }
3978}
3979
3980CXCursorKind clang_getCursorKind(CXCursor C) {
3981 return C.kind;
3982}
3983
3984CXSourceLocation clang_getCursorLocation(CXCursor C) {
3985 if (clang_isReference(C.kind)) {
3986 switch (C.kind) {
3987 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003988 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003989 = getCursorObjCSuperClassRef(C);
3990 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3991 }
3992
3993 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003994 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003995 = getCursorObjCProtocolRef(C);
3996 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3997 }
3998
3999 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004000 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004001 = getCursorObjCClassRef(C);
4002 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4003 }
4004
4005 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004006 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004007 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4008 }
4009
4010 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004011 std::pair<const TemplateDecl *, SourceLocation> P =
4012 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004013 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4014 }
4015
4016 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004017 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004018 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4019 }
4020
4021 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004022 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004023 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4024 }
4025
4026 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004027 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004028 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4029 }
4030
4031 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004032 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004033 if (!BaseSpec)
4034 return clang_getNullLocation();
4035
4036 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4037 return cxloc::translateSourceLocation(getCursorContext(C),
4038 TSInfo->getTypeLoc().getBeginLoc());
4039
4040 return cxloc::translateSourceLocation(getCursorContext(C),
4041 BaseSpec->getLocStart());
4042 }
4043
4044 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004045 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004046 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4047 }
4048
4049 case CXCursor_OverloadedDeclRef:
4050 return cxloc::translateSourceLocation(getCursorContext(C),
4051 getCursorOverloadedDeclRef(C).second);
4052
4053 default:
4054 // FIXME: Need a way to enumerate all non-reference cases.
4055 llvm_unreachable("Missed a reference kind");
4056 }
4057 }
4058
4059 if (clang_isExpression(C.kind))
4060 return cxloc::translateSourceLocation(getCursorContext(C),
4061 getLocationFromExpr(getCursorExpr(C)));
4062
4063 if (clang_isStatement(C.kind))
4064 return cxloc::translateSourceLocation(getCursorContext(C),
4065 getCursorStmt(C)->getLocStart());
4066
4067 if (C.kind == CXCursor_PreprocessingDirective) {
4068 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4069 return cxloc::translateSourceLocation(getCursorContext(C), L);
4070 }
4071
4072 if (C.kind == CXCursor_MacroExpansion) {
4073 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004074 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004075 return cxloc::translateSourceLocation(getCursorContext(C), L);
4076 }
4077
4078 if (C.kind == CXCursor_MacroDefinition) {
4079 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4080 return cxloc::translateSourceLocation(getCursorContext(C), L);
4081 }
4082
4083 if (C.kind == CXCursor_InclusionDirective) {
4084 SourceLocation L
4085 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4086 return cxloc::translateSourceLocation(getCursorContext(C), L);
4087 }
4088
4089 if (!clang_isDeclaration(C.kind))
4090 return clang_getNullLocation();
4091
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004092 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004093 if (!D)
4094 return clang_getNullLocation();
4095
4096 SourceLocation Loc = D->getLocation();
4097 // FIXME: Multiple variables declared in a single declaration
4098 // currently lack the information needed to correctly determine their
4099 // ranges when accounting for the type-specifier. We use context
4100 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4101 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004102 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004103 if (!cxcursor::isFirstInDeclGroup(C))
4104 Loc = VD->getLocation();
4105 }
4106
4107 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004108 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004109 Loc = MD->getSelectorStartLoc();
4110
4111 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4112}
4113
4114} // end extern "C"
4115
4116CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4117 assert(TU);
4118
4119 // Guard against an invalid SourceLocation, or we may assert in one
4120 // of the following calls.
4121 if (SLoc.isInvalid())
4122 return clang_getNullCursor();
4123
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004124 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004125
4126 // Translate the given source location to make it point at the beginning of
4127 // the token under the cursor.
4128 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4129 CXXUnit->getASTContext().getLangOpts());
4130
4131 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4132 if (SLoc.isValid()) {
4133 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4134 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4135 /*VisitPreprocessorLast=*/true,
4136 /*VisitIncludedEntities=*/false,
4137 SourceLocation(SLoc));
4138 CursorVis.visitFileRegion();
4139 }
4140
4141 return Result;
4142}
4143
4144static SourceRange getRawCursorExtent(CXCursor C) {
4145 if (clang_isReference(C.kind)) {
4146 switch (C.kind) {
4147 case CXCursor_ObjCSuperClassRef:
4148 return getCursorObjCSuperClassRef(C).second;
4149
4150 case CXCursor_ObjCProtocolRef:
4151 return getCursorObjCProtocolRef(C).second;
4152
4153 case CXCursor_ObjCClassRef:
4154 return getCursorObjCClassRef(C).second;
4155
4156 case CXCursor_TypeRef:
4157 return getCursorTypeRef(C).second;
4158
4159 case CXCursor_TemplateRef:
4160 return getCursorTemplateRef(C).second;
4161
4162 case CXCursor_NamespaceRef:
4163 return getCursorNamespaceRef(C).second;
4164
4165 case CXCursor_MemberRef:
4166 return getCursorMemberRef(C).second;
4167
4168 case CXCursor_CXXBaseSpecifier:
4169 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4170
4171 case CXCursor_LabelRef:
4172 return getCursorLabelRef(C).second;
4173
4174 case CXCursor_OverloadedDeclRef:
4175 return getCursorOverloadedDeclRef(C).second;
4176
4177 case CXCursor_VariableRef:
4178 return getCursorVariableRef(C).second;
4179
4180 default:
4181 // FIXME: Need a way to enumerate all non-reference cases.
4182 llvm_unreachable("Missed a reference kind");
4183 }
4184 }
4185
4186 if (clang_isExpression(C.kind))
4187 return getCursorExpr(C)->getSourceRange();
4188
4189 if (clang_isStatement(C.kind))
4190 return getCursorStmt(C)->getSourceRange();
4191
4192 if (clang_isAttribute(C.kind))
4193 return getCursorAttr(C)->getRange();
4194
4195 if (C.kind == CXCursor_PreprocessingDirective)
4196 return cxcursor::getCursorPreprocessingDirective(C);
4197
4198 if (C.kind == CXCursor_MacroExpansion) {
4199 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004200 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004201 return TU->mapRangeFromPreamble(Range);
4202 }
4203
4204 if (C.kind == CXCursor_MacroDefinition) {
4205 ASTUnit *TU = getCursorASTUnit(C);
4206 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4207 return TU->mapRangeFromPreamble(Range);
4208 }
4209
4210 if (C.kind == CXCursor_InclusionDirective) {
4211 ASTUnit *TU = getCursorASTUnit(C);
4212 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4213 return TU->mapRangeFromPreamble(Range);
4214 }
4215
4216 if (C.kind == CXCursor_TranslationUnit) {
4217 ASTUnit *TU = getCursorASTUnit(C);
4218 FileID MainID = TU->getSourceManager().getMainFileID();
4219 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4220 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4221 return SourceRange(Start, End);
4222 }
4223
4224 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004225 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004226 if (!D)
4227 return SourceRange();
4228
4229 SourceRange R = D->getSourceRange();
4230 // FIXME: Multiple variables declared in a single declaration
4231 // currently lack the information needed to correctly determine their
4232 // ranges when accounting for the type-specifier. We use context
4233 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4234 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004235 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004236 if (!cxcursor::isFirstInDeclGroup(C))
4237 R.setBegin(VD->getLocation());
4238 }
4239 return R;
4240 }
4241 return SourceRange();
4242}
4243
4244/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4245/// the decl-specifier-seq for declarations.
4246static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4247 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004248 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004249 if (!D)
4250 return SourceRange();
4251
4252 SourceRange R = D->getSourceRange();
4253
4254 // Adjust the start of the location for declarations preceded by
4255 // declaration specifiers.
4256 SourceLocation StartLoc;
4257 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4258 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4259 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004260 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004261 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4262 StartLoc = TI->getTypeLoc().getLocStart();
4263 }
4264
4265 if (StartLoc.isValid() && R.getBegin().isValid() &&
4266 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4267 R.setBegin(StartLoc);
4268
4269 // FIXME: Multiple variables declared in a single declaration
4270 // currently lack the information needed to correctly determine their
4271 // ranges when accounting for the type-specifier. We use context
4272 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4273 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004274 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004275 if (!cxcursor::isFirstInDeclGroup(C))
4276 R.setBegin(VD->getLocation());
4277 }
4278
4279 return R;
4280 }
4281
4282 return getRawCursorExtent(C);
4283}
4284
4285extern "C" {
4286
4287CXSourceRange clang_getCursorExtent(CXCursor C) {
4288 SourceRange R = getRawCursorExtent(C);
4289 if (R.isInvalid())
4290 return clang_getNullRange();
4291
4292 return cxloc::translateSourceRange(getCursorContext(C), R);
4293}
4294
4295CXCursor clang_getCursorReferenced(CXCursor C) {
4296 if (clang_isInvalid(C.kind))
4297 return clang_getNullCursor();
4298
4299 CXTranslationUnit tu = getCursorTU(C);
4300 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004301 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004302 if (!D)
4303 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004304 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004305 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004306 if (const ObjCPropertyImplDecl *PropImpl =
4307 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004308 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4309 return MakeCXCursor(Property, tu);
4310
4311 return C;
4312 }
4313
4314 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004315 const Expr *E = getCursorExpr(C);
4316 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004317 if (D) {
4318 CXCursor declCursor = MakeCXCursor(D, tu);
4319 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4320 declCursor);
4321 return declCursor;
4322 }
4323
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004324 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004325 return MakeCursorOverloadedDeclRef(Ovl, tu);
4326
4327 return clang_getNullCursor();
4328 }
4329
4330 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004331 const Stmt *S = getCursorStmt(C);
4332 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004333 if (LabelDecl *label = Goto->getLabel())
4334 if (LabelStmt *labelS = label->getStmt())
4335 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4336
4337 return clang_getNullCursor();
4338 }
4339
4340 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004341 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004342 return MakeMacroDefinitionCursor(Def, tu);
4343 }
4344
4345 if (!clang_isReference(C.kind))
4346 return clang_getNullCursor();
4347
4348 switch (C.kind) {
4349 case CXCursor_ObjCSuperClassRef:
4350 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4351
4352 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004353 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4354 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004355 return MakeCXCursor(Def, tu);
4356
4357 return MakeCXCursor(Prot, tu);
4358 }
4359
4360 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004361 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4362 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004363 return MakeCXCursor(Def, tu);
4364
4365 return MakeCXCursor(Class, tu);
4366 }
4367
4368 case CXCursor_TypeRef:
4369 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4370
4371 case CXCursor_TemplateRef:
4372 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4373
4374 case CXCursor_NamespaceRef:
4375 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4376
4377 case CXCursor_MemberRef:
4378 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4379
4380 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004381 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004382 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4383 tu ));
4384 }
4385
4386 case CXCursor_LabelRef:
4387 // FIXME: We end up faking the "parent" declaration here because we
4388 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004389 return MakeCXCursor(getCursorLabelRef(C).first,
4390 cxtu::getASTUnit(tu)->getASTContext()
4391 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004392 tu);
4393
4394 case CXCursor_OverloadedDeclRef:
4395 return C;
4396
4397 case CXCursor_VariableRef:
4398 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4399
4400 default:
4401 // We would prefer to enumerate all non-reference cursor kinds here.
4402 llvm_unreachable("Unhandled reference cursor kind");
4403 }
4404}
4405
4406CXCursor clang_getCursorDefinition(CXCursor C) {
4407 if (clang_isInvalid(C.kind))
4408 return clang_getNullCursor();
4409
4410 CXTranslationUnit TU = getCursorTU(C);
4411
4412 bool WasReference = false;
4413 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4414 C = clang_getCursorReferenced(C);
4415 WasReference = true;
4416 }
4417
4418 if (C.kind == CXCursor_MacroExpansion)
4419 return clang_getCursorReferenced(C);
4420
4421 if (!clang_isDeclaration(C.kind))
4422 return clang_getNullCursor();
4423
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004424 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004425 if (!D)
4426 return clang_getNullCursor();
4427
4428 switch (D->getKind()) {
4429 // Declaration kinds that don't really separate the notions of
4430 // declaration and definition.
4431 case Decl::Namespace:
4432 case Decl::Typedef:
4433 case Decl::TypeAlias:
4434 case Decl::TypeAliasTemplate:
4435 case Decl::TemplateTypeParm:
4436 case Decl::EnumConstant:
4437 case Decl::Field:
4438 case Decl::IndirectField:
4439 case Decl::ObjCIvar:
4440 case Decl::ObjCAtDefsField:
4441 case Decl::ImplicitParam:
4442 case Decl::ParmVar:
4443 case Decl::NonTypeTemplateParm:
4444 case Decl::TemplateTemplateParm:
4445 case Decl::ObjCCategoryImpl:
4446 case Decl::ObjCImplementation:
4447 case Decl::AccessSpec:
4448 case Decl::LinkageSpec:
4449 case Decl::ObjCPropertyImpl:
4450 case Decl::FileScopeAsm:
4451 case Decl::StaticAssert:
4452 case Decl::Block:
4453 case Decl::Label: // FIXME: Is this right??
4454 case Decl::ClassScopeFunctionSpecialization:
4455 case Decl::Import:
4456 return C;
4457
4458 // Declaration kinds that don't make any sense here, but are
4459 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004460 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004461 case Decl::TranslationUnit:
4462 break;
4463
4464 // Declaration kinds for which the definition is not resolvable.
4465 case Decl::UnresolvedUsingTypename:
4466 case Decl::UnresolvedUsingValue:
4467 break;
4468
4469 case Decl::UsingDirective:
4470 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4471 TU);
4472
4473 case Decl::NamespaceAlias:
4474 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4475
4476 case Decl::Enum:
4477 case Decl::Record:
4478 case Decl::CXXRecord:
4479 case Decl::ClassTemplateSpecialization:
4480 case Decl::ClassTemplatePartialSpecialization:
4481 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4482 return MakeCXCursor(Def, TU);
4483 return clang_getNullCursor();
4484
4485 case Decl::Function:
4486 case Decl::CXXMethod:
4487 case Decl::CXXConstructor:
4488 case Decl::CXXDestructor:
4489 case Decl::CXXConversion: {
4490 const FunctionDecl *Def = 0;
4491 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004492 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004493 return clang_getNullCursor();
4494 }
4495
4496 case Decl::Var: {
4497 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004498 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004499 return MakeCXCursor(Def, TU);
4500 return clang_getNullCursor();
4501 }
4502
4503 case Decl::FunctionTemplate: {
4504 const FunctionDecl *Def = 0;
4505 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4506 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4507 return clang_getNullCursor();
4508 }
4509
4510 case Decl::ClassTemplate: {
4511 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4512 ->getDefinition())
4513 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4514 TU);
4515 return clang_getNullCursor();
4516 }
4517
4518 case Decl::Using:
4519 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4520 D->getLocation(), TU);
4521
4522 case Decl::UsingShadow:
4523 return clang_getCursorDefinition(
4524 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4525 TU));
4526
4527 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004528 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004529 if (Method->isThisDeclarationADefinition())
4530 return C;
4531
4532 // Dig out the method definition in the associated
4533 // @implementation, if we have it.
4534 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004535 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004536 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4537 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4538 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4539 Method->isInstanceMethod()))
4540 if (Def->isThisDeclarationADefinition())
4541 return MakeCXCursor(Def, TU);
4542
4543 return clang_getNullCursor();
4544 }
4545
4546 case Decl::ObjCCategory:
4547 if (ObjCCategoryImplDecl *Impl
4548 = cast<ObjCCategoryDecl>(D)->getImplementation())
4549 return MakeCXCursor(Impl, TU);
4550 return clang_getNullCursor();
4551
4552 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004553 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004554 return MakeCXCursor(Def, TU);
4555 return clang_getNullCursor();
4556
4557 case Decl::ObjCInterface: {
4558 // There are two notions of a "definition" for an Objective-C
4559 // class: the interface and its implementation. When we resolved a
4560 // reference to an Objective-C class, produce the @interface as
4561 // the definition; when we were provided with the interface,
4562 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004563 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004564 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004565 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004566 return MakeCXCursor(Def, TU);
4567 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4568 return MakeCXCursor(Impl, TU);
4569 return clang_getNullCursor();
4570 }
4571
4572 case Decl::ObjCProperty:
4573 // FIXME: We don't really know where to find the
4574 // ObjCPropertyImplDecls that implement this property.
4575 return clang_getNullCursor();
4576
4577 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004578 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004579 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004580 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004581 return MakeCXCursor(Def, TU);
4582
4583 return clang_getNullCursor();
4584
4585 case Decl::Friend:
4586 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4587 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4588 return clang_getNullCursor();
4589
4590 case Decl::FriendTemplate:
4591 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4592 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4593 return clang_getNullCursor();
4594 }
4595
4596 return clang_getNullCursor();
4597}
4598
4599unsigned clang_isCursorDefinition(CXCursor C) {
4600 if (!clang_isDeclaration(C.kind))
4601 return 0;
4602
4603 return clang_getCursorDefinition(C) == C;
4604}
4605
4606CXCursor clang_getCanonicalCursor(CXCursor C) {
4607 if (!clang_isDeclaration(C.kind))
4608 return C;
4609
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004610 if (const Decl *D = getCursorDecl(C)) {
4611 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004612 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4613 return MakeCXCursor(CatD, getCursorTU(C));
4614
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004615 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4616 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004617 return MakeCXCursor(IFD, getCursorTU(C));
4618
4619 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4620 }
4621
4622 return C;
4623}
4624
4625int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4626 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4627}
4628
4629unsigned clang_getNumOverloadedDecls(CXCursor C) {
4630 if (C.kind != CXCursor_OverloadedDeclRef)
4631 return 0;
4632
4633 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004634 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004635 return E->getNumDecls();
4636
4637 if (OverloadedTemplateStorage *S
4638 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4639 return S->size();
4640
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004641 const Decl *D = Storage.get<const Decl *>();
4642 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004643 return Using->shadow_size();
4644
4645 return 0;
4646}
4647
4648CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4649 if (cursor.kind != CXCursor_OverloadedDeclRef)
4650 return clang_getNullCursor();
4651
4652 if (index >= clang_getNumOverloadedDecls(cursor))
4653 return clang_getNullCursor();
4654
4655 CXTranslationUnit TU = getCursorTU(cursor);
4656 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004657 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004658 return MakeCXCursor(E->decls_begin()[index], TU);
4659
4660 if (OverloadedTemplateStorage *S
4661 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4662 return MakeCXCursor(S->begin()[index], TU);
4663
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004664 const Decl *D = Storage.get<const Decl *>();
4665 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004666 // FIXME: This is, unfortunately, linear time.
4667 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4668 std::advance(Pos, index);
4669 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4670 }
4671
4672 return clang_getNullCursor();
4673}
4674
4675void clang_getDefinitionSpellingAndExtent(CXCursor C,
4676 const char **startBuf,
4677 const char **endBuf,
4678 unsigned *startLine,
4679 unsigned *startColumn,
4680 unsigned *endLine,
4681 unsigned *endColumn) {
4682 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004683 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004684 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4685
4686 SourceManager &SM = FD->getASTContext().getSourceManager();
4687 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4688 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4689 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4690 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4691 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4692 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4693}
4694
4695
4696CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4697 unsigned PieceIndex) {
4698 RefNamePieces Pieces;
4699
4700 switch (C.kind) {
4701 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004702 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004703 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4704 E->getQualifierLoc().getSourceRange());
4705 break;
4706
4707 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004708 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004709 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4710 E->getQualifierLoc().getSourceRange(),
4711 E->getOptionalExplicitTemplateArgs());
4712 break;
4713
4714 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004715 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004716 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004717 const Expr *Callee = OCE->getCallee();
4718 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004719 Callee = ICE->getSubExpr();
4720
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004721 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004722 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4723 DRE->getQualifierLoc().getSourceRange());
4724 }
4725 break;
4726
4727 default:
4728 break;
4729 }
4730
4731 if (Pieces.empty()) {
4732 if (PieceIndex == 0)
4733 return clang_getCursorExtent(C);
4734 } else if (PieceIndex < Pieces.size()) {
4735 SourceRange R = Pieces[PieceIndex];
4736 if (R.isValid())
4737 return cxloc::translateSourceRange(getCursorContext(C), R);
4738 }
4739
4740 return clang_getNullRange();
4741}
4742
4743void clang_enableStackTraces(void) {
4744 llvm::sys::PrintStackTraceOnErrorSignal();
4745}
4746
4747void clang_executeOnThread(void (*fn)(void*), void *user_data,
4748 unsigned stack_size) {
4749 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4750}
4751
4752} // end: extern "C"
4753
4754//===----------------------------------------------------------------------===//
4755// Token-based Operations.
4756//===----------------------------------------------------------------------===//
4757
4758/* CXToken layout:
4759 * int_data[0]: a CXTokenKind
4760 * int_data[1]: starting token location
4761 * int_data[2]: token length
4762 * int_data[3]: reserved
4763 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4764 * otherwise unused.
4765 */
4766extern "C" {
4767
4768CXTokenKind clang_getTokenKind(CXToken CXTok) {
4769 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4770}
4771
4772CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4773 switch (clang_getTokenKind(CXTok)) {
4774 case CXToken_Identifier:
4775 case CXToken_Keyword:
4776 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004777 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004778 ->getNameStart());
4779
4780 case CXToken_Literal: {
4781 // We have stashed the starting pointer in the ptr_data field. Use it.
4782 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004783 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004784 }
4785
4786 case CXToken_Punctuation:
4787 case CXToken_Comment:
4788 break;
4789 }
4790
4791 // We have to find the starting buffer pointer the hard way, by
4792 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004793 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004794 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004795 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004796
4797 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4798 std::pair<FileID, unsigned> LocInfo
4799 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4800 bool Invalid = false;
4801 StringRef Buffer
4802 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4803 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004804 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004805
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004806 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004807}
4808
4809CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004810 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004811 if (!CXXUnit)
4812 return clang_getNullLocation();
4813
4814 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4815 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4816}
4817
4818CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004819 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004820 if (!CXXUnit)
4821 return clang_getNullRange();
4822
4823 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4824 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4825}
4826
4827static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4828 SmallVectorImpl<CXToken> &CXTokens) {
4829 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4830 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004831 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004832 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004833 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004834
4835 // Cannot tokenize across files.
4836 if (BeginLocInfo.first != EndLocInfo.first)
4837 return;
4838
4839 // Create a lexer
4840 bool Invalid = false;
4841 StringRef Buffer
4842 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4843 if (Invalid)
4844 return;
4845
4846 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4847 CXXUnit->getASTContext().getLangOpts(),
4848 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4849 Lex.SetCommentRetentionState(true);
4850
4851 // Lex tokens until we hit the end of the range.
4852 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4853 Token Tok;
4854 bool previousWasAt = false;
4855 do {
4856 // Lex the next token
4857 Lex.LexFromRawLexer(Tok);
4858 if (Tok.is(tok::eof))
4859 break;
4860
4861 // Initialize the CXToken.
4862 CXToken CXTok;
4863
4864 // - Common fields
4865 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4866 CXTok.int_data[2] = Tok.getLength();
4867 CXTok.int_data[3] = 0;
4868
4869 // - Kind-specific fields
4870 if (Tok.isLiteral()) {
4871 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004872 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004873 } else if (Tok.is(tok::raw_identifier)) {
4874 // Lookup the identifier to determine whether we have a keyword.
4875 IdentifierInfo *II
4876 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4877
4878 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4879 CXTok.int_data[0] = CXToken_Keyword;
4880 }
4881 else {
4882 CXTok.int_data[0] = Tok.is(tok::identifier)
4883 ? CXToken_Identifier
4884 : CXToken_Keyword;
4885 }
4886 CXTok.ptr_data = II;
4887 } else if (Tok.is(tok::comment)) {
4888 CXTok.int_data[0] = CXToken_Comment;
4889 CXTok.ptr_data = 0;
4890 } else {
4891 CXTok.int_data[0] = CXToken_Punctuation;
4892 CXTok.ptr_data = 0;
4893 }
4894 CXTokens.push_back(CXTok);
4895 previousWasAt = Tok.is(tok::at);
4896 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4897}
4898
4899void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4900 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004901 LOG_FUNC_SECTION {
4902 *Log << TU << ' ' << Range;
4903 }
4904
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004905 if (Tokens)
4906 *Tokens = 0;
4907 if (NumTokens)
4908 *NumTokens = 0;
4909
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004910 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004911 if (!CXXUnit || !Tokens || !NumTokens)
4912 return;
4913
4914 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4915
4916 SourceRange R = cxloc::translateCXSourceRange(Range);
4917 if (R.isInvalid())
4918 return;
4919
4920 SmallVector<CXToken, 32> CXTokens;
4921 getTokens(CXXUnit, R, CXTokens);
4922
4923 if (CXTokens.empty())
4924 return;
4925
4926 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4927 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4928 *NumTokens = CXTokens.size();
4929}
4930
4931void clang_disposeTokens(CXTranslationUnit TU,
4932 CXToken *Tokens, unsigned NumTokens) {
4933 free(Tokens);
4934}
4935
4936} // end: extern "C"
4937
4938//===----------------------------------------------------------------------===//
4939// Token annotation APIs.
4940//===----------------------------------------------------------------------===//
4941
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004942static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4943 CXCursor parent,
4944 CXClientData client_data);
4945static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4946 CXClientData client_data);
4947
4948namespace {
4949class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004950 CXToken *Tokens;
4951 CXCursor *Cursors;
4952 unsigned NumTokens;
4953 unsigned TokIdx;
4954 unsigned PreprocessingTokIdx;
4955 CursorVisitor AnnotateVis;
4956 SourceManager &SrcMgr;
4957 bool HasContextSensitiveKeywords;
4958
4959 struct PostChildrenInfo {
4960 CXCursor Cursor;
4961 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004962 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004963 unsigned BeforeChildrenTokenIdx;
4964 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004965 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004966
4967 bool MoreTokens() const { return TokIdx < NumTokens; }
4968 unsigned NextToken() const { return TokIdx; }
4969 void AdvanceToken() { ++TokIdx; }
4970 SourceLocation GetTokenLoc(unsigned tokI) {
4971 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4972 }
4973 bool isFunctionMacroToken(unsigned tokI) const {
4974 return Tokens[tokI].int_data[3] != 0;
4975 }
4976 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4977 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4978 }
4979
4980 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004981 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004982 SourceRange);
4983
4984public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004985 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004986 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004987 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004988 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004989 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004990 AnnotateTokensVisitor, this,
4991 /*VisitPreprocessorLast=*/true,
4992 /*VisitIncludedEntities=*/false,
4993 RegionOfInterest,
4994 /*VisitDeclsOnly=*/false,
4995 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004996 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004997 HasContextSensitiveKeywords(false) { }
4998
4999 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5000 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5001 bool postVisitChildren(CXCursor cursor);
5002 void AnnotateTokens();
5003
5004 /// \brief Determine whether the annotator saw any cursors that have
5005 /// context-sensitive keywords.
5006 bool hasContextSensitiveKeywords() const {
5007 return HasContextSensitiveKeywords;
5008 }
5009
5010 ~AnnotateTokensWorker() {
5011 assert(PostChildrenInfos.empty());
5012 }
5013};
5014}
5015
5016void AnnotateTokensWorker::AnnotateTokens() {
5017 // Walk the AST within the region of interest, annotating tokens
5018 // along the way.
5019 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005020}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005021
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005022static inline void updateCursorAnnotation(CXCursor &Cursor,
5023 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005024 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005025 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005026 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005027}
5028
5029/// \brief It annotates and advances tokens with a cursor until the comparison
5030//// between the cursor location and the source range is the same as
5031/// \arg compResult.
5032///
5033/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5034/// Pass RangeOverlap to annotate tokens inside a range.
5035void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5036 RangeComparisonResult compResult,
5037 SourceRange range) {
5038 while (MoreTokens()) {
5039 const unsigned I = NextToken();
5040 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005041 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5042 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005043
5044 SourceLocation TokLoc = GetTokenLoc(I);
5045 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005046 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005047 AdvanceToken();
5048 continue;
5049 }
5050 break;
5051 }
5052}
5053
5054/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005055/// \returns true if it advanced beyond all macro tokens, false otherwise.
5056bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005057 CXCursor updateC,
5058 RangeComparisonResult compResult,
5059 SourceRange range) {
5060 assert(MoreTokens());
5061 assert(isFunctionMacroToken(NextToken()) &&
5062 "Should be called only for macro arg tokens");
5063
5064 // This works differently than annotateAndAdvanceTokens; because expanded
5065 // macro arguments can have arbitrary translation-unit source order, we do not
5066 // advance the token index one by one until a token fails the range test.
5067 // We only advance once past all of the macro arg tokens if all of them
5068 // pass the range test. If one of them fails we keep the token index pointing
5069 // at the start of the macro arg tokens so that the failing token will be
5070 // annotated by a subsequent annotation try.
5071
5072 bool atLeastOneCompFail = false;
5073
5074 unsigned I = NextToken();
5075 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5076 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5077 if (TokLoc.isFileID())
5078 continue; // not macro arg token, it's parens or comma.
5079 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5080 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5081 Cursors[I] = updateC;
5082 } else
5083 atLeastOneCompFail = true;
5084 }
5085
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005086 if (atLeastOneCompFail)
5087 return false;
5088
5089 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5090 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005091}
5092
5093enum CXChildVisitResult
5094AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005095 SourceRange cursorRange = getRawCursorExtent(cursor);
5096 if (cursorRange.isInvalid())
5097 return CXChildVisit_Recurse;
5098
5099 if (!HasContextSensitiveKeywords) {
5100 // Objective-C properties can have context-sensitive keywords.
5101 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005102 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005103 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5104 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5105 }
5106 // Objective-C methods can have context-sensitive keywords.
5107 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5108 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005109 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005110 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5111 if (Method->getObjCDeclQualifier())
5112 HasContextSensitiveKeywords = true;
5113 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005114 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5115 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005116 P != PEnd; ++P) {
5117 if ((*P)->getObjCDeclQualifier()) {
5118 HasContextSensitiveKeywords = true;
5119 break;
5120 }
5121 }
5122 }
5123 }
5124 }
5125 // C++ methods can have context-sensitive keywords.
5126 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005127 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005128 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5129 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5130 HasContextSensitiveKeywords = true;
5131 }
5132 }
5133 // C++ classes can have context-sensitive keywords.
5134 else if (cursor.kind == CXCursor_StructDecl ||
5135 cursor.kind == CXCursor_ClassDecl ||
5136 cursor.kind == CXCursor_ClassTemplate ||
5137 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005138 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005139 if (D->hasAttr<FinalAttr>())
5140 HasContextSensitiveKeywords = true;
5141 }
5142 }
5143
5144 if (clang_isPreprocessing(cursor.kind)) {
5145 // Items in the preprocessing record are kept separate from items in
5146 // declarations, so we keep a separate token index.
5147 unsigned SavedTokIdx = TokIdx;
5148 TokIdx = PreprocessingTokIdx;
5149
5150 // Skip tokens up until we catch up to the beginning of the preprocessing
5151 // entry.
5152 while (MoreTokens()) {
5153 const unsigned I = NextToken();
5154 SourceLocation TokLoc = GetTokenLoc(I);
5155 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5156 case RangeBefore:
5157 AdvanceToken();
5158 continue;
5159 case RangeAfter:
5160 case RangeOverlap:
5161 break;
5162 }
5163 break;
5164 }
5165
5166 // Look at all of the tokens within this range.
5167 while (MoreTokens()) {
5168 const unsigned I = NextToken();
5169 SourceLocation TokLoc = GetTokenLoc(I);
5170 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5171 case RangeBefore:
5172 llvm_unreachable("Infeasible");
5173 case RangeAfter:
5174 break;
5175 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005176 // For macro expansions, just note where the beginning of the macro
5177 // expansion occurs.
5178 if (cursor.kind == CXCursor_MacroExpansion) {
5179 if (TokLoc == cursorRange.getBegin())
5180 Cursors[I] = cursor;
5181 AdvanceToken();
5182 break;
5183 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005184 // We may have already annotated macro names inside macro definitions.
5185 if (Cursors[I].kind != CXCursor_MacroExpansion)
5186 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005187 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005188 continue;
5189 }
5190 break;
5191 }
5192
5193 // Save the preprocessing token index; restore the non-preprocessing
5194 // token index.
5195 PreprocessingTokIdx = TokIdx;
5196 TokIdx = SavedTokIdx;
5197 return CXChildVisit_Recurse;
5198 }
5199
5200 if (cursorRange.isInvalid())
5201 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005202
5203 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005204 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005205 const enum CXCursorKind K = clang_getCursorKind(parent);
5206 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005207 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5208 // Attributes are annotated out-of-order, skip tokens until we reach it.
5209 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005210 ? clang_getNullCursor() : parent;
5211
5212 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5213
5214 // Avoid having the cursor of an expression "overwrite" the annotation of the
5215 // variable declaration that it belongs to.
5216 // This can happen for C++ constructor expressions whose range generally
5217 // include the variable declaration, e.g.:
5218 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5219 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005220 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005221 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005222 const unsigned I = NextToken();
5223 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5224 E->getLocStart() == D->getLocation() &&
5225 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005226 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005227 AdvanceToken();
5228 }
5229 }
5230 }
5231
5232 // Before recursing into the children keep some state that we are going
5233 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5234 // extra work after the child nodes are visited.
5235 // Note that we don't call VisitChildren here to avoid traversing statements
5236 // code-recursively which can blow the stack.
5237
5238 PostChildrenInfo Info;
5239 Info.Cursor = cursor;
5240 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005241 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005242 Info.BeforeChildrenTokenIdx = NextToken();
5243 PostChildrenInfos.push_back(Info);
5244
5245 return CXChildVisit_Recurse;
5246}
5247
5248bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5249 if (PostChildrenInfos.empty())
5250 return false;
5251 const PostChildrenInfo &Info = PostChildrenInfos.back();
5252 if (!clang_equalCursors(Info.Cursor, cursor))
5253 return false;
5254
5255 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5256 const unsigned AfterChildren = NextToken();
5257 SourceRange cursorRange = Info.CursorRange;
5258
5259 // Scan the tokens that are at the end of the cursor, but are not captured
5260 // but the child cursors.
5261 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5262
5263 // Scan the tokens that are at the beginning of the cursor, but are not
5264 // capture by the child cursors.
5265 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5266 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5267 break;
5268
5269 Cursors[I] = cursor;
5270 }
5271
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005272 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5273 // encountered the attribute cursor.
5274 if (clang_isAttribute(cursor.kind))
5275 TokIdx = Info.BeforeReachingCursorIdx;
5276
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005277 PostChildrenInfos.pop_back();
5278 return false;
5279}
5280
5281static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5282 CXCursor parent,
5283 CXClientData client_data) {
5284 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5285}
5286
5287static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5288 CXClientData client_data) {
5289 return static_cast<AnnotateTokensWorker*>(client_data)->
5290 postVisitChildren(cursor);
5291}
5292
5293namespace {
5294
5295/// \brief Uses the macro expansions in the preprocessing record to find
5296/// and mark tokens that are macro arguments. This info is used by the
5297/// AnnotateTokensWorker.
5298class MarkMacroArgTokensVisitor {
5299 SourceManager &SM;
5300 CXToken *Tokens;
5301 unsigned NumTokens;
5302 unsigned CurIdx;
5303
5304public:
5305 MarkMacroArgTokensVisitor(SourceManager &SM,
5306 CXToken *tokens, unsigned numTokens)
5307 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5308
5309 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5310 if (cursor.kind != CXCursor_MacroExpansion)
5311 return CXChildVisit_Continue;
5312
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005313 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005314 if (macroRange.getBegin() == macroRange.getEnd())
5315 return CXChildVisit_Continue; // it's not a function macro.
5316
5317 for (; CurIdx < NumTokens; ++CurIdx) {
5318 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5319 macroRange.getBegin()))
5320 break;
5321 }
5322
5323 if (CurIdx == NumTokens)
5324 return CXChildVisit_Break;
5325
5326 for (; CurIdx < NumTokens; ++CurIdx) {
5327 SourceLocation tokLoc = getTokenLoc(CurIdx);
5328 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5329 break;
5330
5331 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5332 }
5333
5334 if (CurIdx == NumTokens)
5335 return CXChildVisit_Break;
5336
5337 return CXChildVisit_Continue;
5338 }
5339
5340private:
5341 SourceLocation getTokenLoc(unsigned tokI) {
5342 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5343 }
5344
5345 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5346 // The third field is reserved and currently not used. Use it here
5347 // to mark macro arg expanded tokens with their expanded locations.
5348 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5349 }
5350};
5351
5352} // end anonymous namespace
5353
5354static CXChildVisitResult
5355MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5356 CXClientData client_data) {
5357 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5358 parent);
5359}
5360
5361namespace {
5362 struct clang_annotateTokens_Data {
5363 CXTranslationUnit TU;
5364 ASTUnit *CXXUnit;
5365 CXToken *Tokens;
5366 unsigned NumTokens;
5367 CXCursor *Cursors;
5368 };
5369}
5370
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005371/// \brief Used by \c annotatePreprocessorTokens.
5372/// \returns true if lexing was finished, false otherwise.
5373static bool lexNext(Lexer &Lex, Token &Tok,
5374 unsigned &NextIdx, unsigned NumTokens) {
5375 if (NextIdx >= NumTokens)
5376 return true;
5377
5378 ++NextIdx;
5379 Lex.LexFromRawLexer(Tok);
5380 if (Tok.is(tok::eof))
5381 return true;
5382
5383 return false;
5384}
5385
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005386static void annotatePreprocessorTokens(CXTranslationUnit TU,
5387 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005388 CXCursor *Cursors,
5389 CXToken *Tokens,
5390 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005391 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005392
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005393 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005394 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5395 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005396 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005397 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005398 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005399
5400 if (BeginLocInfo.first != EndLocInfo.first)
5401 return;
5402
5403 StringRef Buffer;
5404 bool Invalid = false;
5405 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5406 if (Buffer.empty() || Invalid)
5407 return;
5408
5409 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5410 CXXUnit->getASTContext().getLangOpts(),
5411 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5412 Buffer.end());
5413 Lex.SetCommentRetentionState(true);
5414
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005415 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005416 // Lex tokens in raw mode until we hit the end of the range, to avoid
5417 // entering #includes or expanding macros.
5418 while (true) {
5419 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005420 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5421 break;
5422 unsigned TokIdx = NextIdx-1;
5423 assert(Tok.getLocation() ==
5424 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005425
5426 reprocess:
5427 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005428 // We have found a preprocessing directive. Annotate the tokens
5429 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005430 //
5431 // FIXME: Some simple tests here could identify macro definitions and
5432 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005433
5434 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005435 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5436 break;
5437
5438 MacroInfo *MI = 0;
5439 if (Tok.is(tok::raw_identifier) &&
5440 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5441 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5442 break;
5443
5444 if (Tok.is(tok::raw_identifier)) {
5445 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5446 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5447 SourceLocation MappedTokLoc =
5448 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5449 MI = getMacroInfo(II, MappedTokLoc, TU);
5450 }
5451 }
5452
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005453 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005454 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005455 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5456 finished = true;
5457 break;
5458 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005459 // If we are in a macro definition, check if the token was ever a
5460 // macro name and annotate it if that's the case.
5461 if (MI) {
5462 SourceLocation SaveLoc = Tok.getLocation();
5463 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5464 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5465 Tok.setLocation(SaveLoc);
5466 if (MacroDef)
5467 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5468 Tok.getLocation(), TU);
5469 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005470 } while (!Tok.isAtStartOfLine());
5471
5472 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5473 assert(TokIdx <= LastIdx);
5474 SourceLocation EndLoc =
5475 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5476 CXCursor Cursor =
5477 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5478
5479 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005480 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005481
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005482 if (finished)
5483 break;
5484 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005485 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005486 }
5487}
5488
5489// This gets run a separate thread to avoid stack blowout.
5490static void clang_annotateTokensImpl(void *UserData) {
5491 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5492 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5493 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5494 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5495 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5496
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005497 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005498 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5499 setThreadBackgroundPriority();
5500
5501 // Determine the region of interest, which contains all of the tokens.
5502 SourceRange RegionOfInterest;
5503 RegionOfInterest.setBegin(
5504 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5505 RegionOfInterest.setEnd(
5506 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5507 Tokens[NumTokens-1])));
5508
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005509 // Relex the tokens within the source range to look for preprocessing
5510 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005511 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005512
5513 // If begin location points inside a macro argument, set it to the expansion
5514 // location so we can have the full context when annotating semantically.
5515 {
5516 SourceManager &SM = CXXUnit->getSourceManager();
5517 SourceLocation Loc =
5518 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5519 if (Loc.isMacroID())
5520 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5521 }
5522
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005523 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5524 // Search and mark tokens that are macro argument expansions.
5525 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5526 Tokens, NumTokens);
5527 CursorVisitor MacroArgMarker(TU,
5528 MarkMacroArgTokensVisitorDelegate, &Visitor,
5529 /*VisitPreprocessorLast=*/true,
5530 /*VisitIncludedEntities=*/false,
5531 RegionOfInterest);
5532 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5533 }
5534
5535 // Annotate all of the source locations in the region of interest that map to
5536 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005537 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005538
5539 // FIXME: We use a ridiculous stack size here because the data-recursion
5540 // algorithm uses a large stack frame than the non-data recursive version,
5541 // and AnnotationTokensWorker currently transforms the data-recursion
5542 // algorithm back into a traditional recursion by explicitly calling
5543 // VisitChildren(). We will need to remove this explicit recursive call.
5544 W.AnnotateTokens();
5545
5546 // If we ran into any entities that involve context-sensitive keywords,
5547 // take another pass through the tokens to mark them as such.
5548 if (W.hasContextSensitiveKeywords()) {
5549 for (unsigned I = 0; I != NumTokens; ++I) {
5550 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5551 continue;
5552
5553 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5554 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005555 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005556 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5557 if (Property->getPropertyAttributesAsWritten() != 0 &&
5558 llvm::StringSwitch<bool>(II->getName())
5559 .Case("readonly", true)
5560 .Case("assign", true)
5561 .Case("unsafe_unretained", true)
5562 .Case("readwrite", true)
5563 .Case("retain", true)
5564 .Case("copy", true)
5565 .Case("nonatomic", true)
5566 .Case("atomic", true)
5567 .Case("getter", true)
5568 .Case("setter", true)
5569 .Case("strong", true)
5570 .Case("weak", true)
5571 .Default(false))
5572 Tokens[I].int_data[0] = CXToken_Keyword;
5573 }
5574 continue;
5575 }
5576
5577 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5578 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5579 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5580 if (llvm::StringSwitch<bool>(II->getName())
5581 .Case("in", true)
5582 .Case("out", true)
5583 .Case("inout", true)
5584 .Case("oneway", true)
5585 .Case("bycopy", true)
5586 .Case("byref", true)
5587 .Default(false))
5588 Tokens[I].int_data[0] = CXToken_Keyword;
5589 continue;
5590 }
5591
5592 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5593 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5594 Tokens[I].int_data[0] = CXToken_Keyword;
5595 continue;
5596 }
5597 }
5598 }
5599}
5600
5601extern "C" {
5602
5603void clang_annotateTokens(CXTranslationUnit TU,
5604 CXToken *Tokens, unsigned NumTokens,
5605 CXCursor *Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005606 if (NumTokens == 0 || !Tokens || !Cursors) {
5607 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005608 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005609 }
5610
5611 LOG_FUNC_SECTION {
5612 *Log << TU << ' ';
5613 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5614 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5615 *Log << clang_getRange(bloc, eloc);
5616 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005617
5618 // Any token we don't specifically annotate will have a NULL cursor.
5619 CXCursor C = clang_getNullCursor();
5620 for (unsigned I = 0; I != NumTokens; ++I)
5621 Cursors[I] = C;
5622
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005623 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005624 if (!CXXUnit)
5625 return;
5626
5627 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5628
5629 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5630 llvm::CrashRecoveryContext CRC;
5631 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5632 GetSafetyThreadStackSize() * 2)) {
5633 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5634 }
5635}
5636
5637} // end: extern "C"
5638
5639//===----------------------------------------------------------------------===//
5640// Operations for querying linkage of a cursor.
5641//===----------------------------------------------------------------------===//
5642
5643extern "C" {
5644CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5645 if (!clang_isDeclaration(cursor.kind))
5646 return CXLinkage_Invalid;
5647
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005648 const Decl *D = cxcursor::getCursorDecl(cursor);
5649 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005650 switch (ND->getLinkage()) {
5651 case NoLinkage: return CXLinkage_NoLinkage;
5652 case InternalLinkage: return CXLinkage_Internal;
5653 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5654 case ExternalLinkage: return CXLinkage_External;
5655 };
5656
5657 return CXLinkage_Invalid;
5658}
5659} // end: extern "C"
5660
5661//===----------------------------------------------------------------------===//
5662// Operations for querying language of a cursor.
5663//===----------------------------------------------------------------------===//
5664
5665static CXLanguageKind getDeclLanguage(const Decl *D) {
5666 if (!D)
5667 return CXLanguage_C;
5668
5669 switch (D->getKind()) {
5670 default:
5671 break;
5672 case Decl::ImplicitParam:
5673 case Decl::ObjCAtDefsField:
5674 case Decl::ObjCCategory:
5675 case Decl::ObjCCategoryImpl:
5676 case Decl::ObjCCompatibleAlias:
5677 case Decl::ObjCImplementation:
5678 case Decl::ObjCInterface:
5679 case Decl::ObjCIvar:
5680 case Decl::ObjCMethod:
5681 case Decl::ObjCProperty:
5682 case Decl::ObjCPropertyImpl:
5683 case Decl::ObjCProtocol:
5684 return CXLanguage_ObjC;
5685 case Decl::CXXConstructor:
5686 case Decl::CXXConversion:
5687 case Decl::CXXDestructor:
5688 case Decl::CXXMethod:
5689 case Decl::CXXRecord:
5690 case Decl::ClassTemplate:
5691 case Decl::ClassTemplatePartialSpecialization:
5692 case Decl::ClassTemplateSpecialization:
5693 case Decl::Friend:
5694 case Decl::FriendTemplate:
5695 case Decl::FunctionTemplate:
5696 case Decl::LinkageSpec:
5697 case Decl::Namespace:
5698 case Decl::NamespaceAlias:
5699 case Decl::NonTypeTemplateParm:
5700 case Decl::StaticAssert:
5701 case Decl::TemplateTemplateParm:
5702 case Decl::TemplateTypeParm:
5703 case Decl::UnresolvedUsingTypename:
5704 case Decl::UnresolvedUsingValue:
5705 case Decl::Using:
5706 case Decl::UsingDirective:
5707 case Decl::UsingShadow:
5708 return CXLanguage_CPlusPlus;
5709 }
5710
5711 return CXLanguage_C;
5712}
5713
5714extern "C" {
5715
5716enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5717 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005718 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005719 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5720 return CXAvailability_Available;
5721
5722 switch (D->getAvailability()) {
5723 case AR_Available:
5724 case AR_NotYetIntroduced:
5725 return CXAvailability_Available;
5726
5727 case AR_Deprecated:
5728 return CXAvailability_Deprecated;
5729
5730 case AR_Unavailable:
5731 return CXAvailability_NotAvailable;
5732 }
5733 }
5734
5735 return CXAvailability_Available;
5736}
5737
5738static CXVersion convertVersion(VersionTuple In) {
5739 CXVersion Out = { -1, -1, -1 };
5740 if (In.empty())
5741 return Out;
5742
5743 Out.Major = In.getMajor();
5744
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005745 Optional<unsigned> Minor = In.getMinor();
5746 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005747 Out.Minor = *Minor;
5748 else
5749 return Out;
5750
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005751 Optional<unsigned> Subminor = In.getSubminor();
5752 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005753 Out.Subminor = *Subminor;
5754
5755 return Out;
5756}
5757
5758int clang_getCursorPlatformAvailability(CXCursor cursor,
5759 int *always_deprecated,
5760 CXString *deprecated_message,
5761 int *always_unavailable,
5762 CXString *unavailable_message,
5763 CXPlatformAvailability *availability,
5764 int availability_size) {
5765 if (always_deprecated)
5766 *always_deprecated = 0;
5767 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005768 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005769 if (always_unavailable)
5770 *always_unavailable = 0;
5771 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005772 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005773
5774 if (!clang_isDeclaration(cursor.kind))
5775 return 0;
5776
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005777 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005778 if (!D)
5779 return 0;
5780
5781 int N = 0;
5782 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5783 ++A) {
5784 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5785 if (always_deprecated)
5786 *always_deprecated = 1;
5787 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005788 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005789 continue;
5790 }
5791
5792 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5793 if (always_unavailable)
5794 *always_unavailable = 1;
5795 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005796 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005797 }
5798 continue;
5799 }
5800
5801 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5802 if (N < availability_size) {
5803 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005804 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005805 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5806 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5807 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5808 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005809 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005810 }
5811 ++N;
5812 }
5813 }
5814
5815 return N;
5816}
5817
5818void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5819 clang_disposeString(availability->Platform);
5820 clang_disposeString(availability->Message);
5821}
5822
5823CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5824 if (clang_isDeclaration(cursor.kind))
5825 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5826
5827 return CXLanguage_Invalid;
5828}
5829
5830 /// \brief If the given cursor is the "templated" declaration
5831 /// descibing a class or function template, return the class or
5832 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005833static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005834 if (!D)
5835 return 0;
5836
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005837 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005838 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5839 return FunTmpl;
5840
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005841 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005842 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5843 return ClassTmpl;
5844
5845 return D;
5846}
5847
5848CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5849 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005850 if (const Decl *D = getCursorDecl(cursor)) {
5851 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005852 if (!DC)
5853 return clang_getNullCursor();
5854
5855 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5856 getCursorTU(cursor));
5857 }
5858 }
5859
5860 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005861 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005862 return MakeCXCursor(D, getCursorTU(cursor));
5863 }
5864
5865 return clang_getNullCursor();
5866}
5867
5868CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5869 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005870 if (const Decl *D = getCursorDecl(cursor)) {
5871 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005872 if (!DC)
5873 return clang_getNullCursor();
5874
5875 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5876 getCursorTU(cursor));
5877 }
5878 }
5879
5880 // FIXME: Note that we can't easily compute the lexical context of a
5881 // statement or expression, so we return nothing.
5882 return clang_getNullCursor();
5883}
5884
5885CXFile clang_getIncludedFile(CXCursor cursor) {
5886 if (cursor.kind != CXCursor_InclusionDirective)
5887 return 0;
5888
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005889 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005890 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005891}
5892
5893CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5894 if (!clang_isDeclaration(C.kind))
5895 return clang_getNullRange();
5896
5897 const Decl *D = getCursorDecl(C);
5898 ASTContext &Context = getCursorContext(C);
5899 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5900 if (!RC)
5901 return clang_getNullRange();
5902
5903 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5904}
5905
5906CXString clang_Cursor_getRawCommentText(CXCursor C) {
5907 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005908 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005909
5910 const Decl *D = getCursorDecl(C);
5911 ASTContext &Context = getCursorContext(C);
5912 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5913 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5914 StringRef();
5915
5916 // Don't duplicate the string because RawText points directly into source
5917 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005918 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005919}
5920
5921CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5922 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005923 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005924
5925 const Decl *D = getCursorDecl(C);
5926 const ASTContext &Context = getCursorContext(C);
5927 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5928
5929 if (RC) {
5930 StringRef BriefText = RC->getBriefText(Context);
5931
5932 // Don't duplicate the string because RawComment ensures that this memory
5933 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005934 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005935 }
5936
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005937 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005938}
5939
5940CXComment clang_Cursor_getParsedComment(CXCursor C) {
5941 if (!clang_isDeclaration(C.kind))
5942 return cxcomment::createCXComment(NULL, NULL);
5943
5944 const Decl *D = getCursorDecl(C);
5945 const ASTContext &Context = getCursorContext(C);
5946 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5947
5948 return cxcomment::createCXComment(FC, getCursorTU(C));
5949}
5950
5951CXModule clang_Cursor_getModule(CXCursor C) {
5952 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005953 if (const ImportDecl *ImportD =
5954 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005955 return ImportD->getImportedModule();
5956 }
5957
5958 return 0;
5959}
5960
5961CXModule clang_Module_getParent(CXModule CXMod) {
5962 if (!CXMod)
5963 return 0;
5964 Module *Mod = static_cast<Module*>(CXMod);
5965 return Mod->Parent;
5966}
5967
5968CXString clang_Module_getName(CXModule CXMod) {
5969 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005970 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005971 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005972 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005973}
5974
5975CXString clang_Module_getFullName(CXModule CXMod) {
5976 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005977 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005978 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005979 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005980}
5981
5982unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
5983 if (!CXMod)
5984 return 0;
5985 Module *Mod = static_cast<Module*>(CXMod);
5986 return Mod->TopHeaders.size();
5987}
5988
5989CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
5990 if (!CXMod)
5991 return 0;
5992 Module *Mod = static_cast<Module*>(CXMod);
5993
5994 if (Index < Mod->TopHeaders.size())
5995 return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
5996
5997 return 0;
5998}
5999
6000} // end: extern "C"
6001
6002//===----------------------------------------------------------------------===//
6003// C++ AST instrospection.
6004//===----------------------------------------------------------------------===//
6005
6006extern "C" {
6007unsigned clang_CXXMethod_isStatic(CXCursor C) {
6008 if (!clang_isDeclaration(C.kind))
6009 return 0;
6010
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006011 const CXXMethodDecl *Method = 0;
6012 const Decl *D = cxcursor::getCursorDecl(C);
6013 if (const FunctionTemplateDecl *FunTmpl =
6014 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006015 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6016 else
6017 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6018 return (Method && Method->isStatic()) ? 1 : 0;
6019}
6020
6021unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6022 if (!clang_isDeclaration(C.kind))
6023 return 0;
6024
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006025 const CXXMethodDecl *Method = 0;
6026 const Decl *D = cxcursor::getCursorDecl(C);
6027 if (const FunctionTemplateDecl *FunTmpl =
6028 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006029 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6030 else
6031 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6032 return (Method && Method->isVirtual()) ? 1 : 0;
6033}
6034} // end: extern "C"
6035
6036//===----------------------------------------------------------------------===//
6037// Attribute introspection.
6038//===----------------------------------------------------------------------===//
6039
6040extern "C" {
6041CXType clang_getIBOutletCollectionType(CXCursor C) {
6042 if (C.kind != CXCursor_IBOutletCollectionAttr)
6043 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6044
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006045 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006046 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6047
6048 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6049}
6050} // end: extern "C"
6051
6052//===----------------------------------------------------------------------===//
6053// Inspecting memory usage.
6054//===----------------------------------------------------------------------===//
6055
6056typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6057
6058static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6059 enum CXTUResourceUsageKind k,
6060 unsigned long amount) {
6061 CXTUResourceUsageEntry entry = { k, amount };
6062 entries.push_back(entry);
6063}
6064
6065extern "C" {
6066
6067const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6068 const char *str = "";
6069 switch (kind) {
6070 case CXTUResourceUsage_AST:
6071 str = "ASTContext: expressions, declarations, and types";
6072 break;
6073 case CXTUResourceUsage_Identifiers:
6074 str = "ASTContext: identifiers";
6075 break;
6076 case CXTUResourceUsage_Selectors:
6077 str = "ASTContext: selectors";
6078 break;
6079 case CXTUResourceUsage_GlobalCompletionResults:
6080 str = "Code completion: cached global results";
6081 break;
6082 case CXTUResourceUsage_SourceManagerContentCache:
6083 str = "SourceManager: content cache allocator";
6084 break;
6085 case CXTUResourceUsage_AST_SideTables:
6086 str = "ASTContext: side tables";
6087 break;
6088 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6089 str = "SourceManager: malloc'ed memory buffers";
6090 break;
6091 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6092 str = "SourceManager: mmap'ed memory buffers";
6093 break;
6094 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6095 str = "ExternalASTSource: malloc'ed memory buffers";
6096 break;
6097 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6098 str = "ExternalASTSource: mmap'ed memory buffers";
6099 break;
6100 case CXTUResourceUsage_Preprocessor:
6101 str = "Preprocessor: malloc'ed memory";
6102 break;
6103 case CXTUResourceUsage_PreprocessingRecord:
6104 str = "Preprocessor: PreprocessingRecord";
6105 break;
6106 case CXTUResourceUsage_SourceManager_DataStructures:
6107 str = "SourceManager: data structures and tables";
6108 break;
6109 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6110 str = "Preprocessor: header search tables";
6111 break;
6112 }
6113 return str;
6114}
6115
6116CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6117 if (!TU) {
6118 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6119 return usage;
6120 }
6121
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006122 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006123 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6124 ASTContext &astContext = astUnit->getASTContext();
6125
6126 // How much memory is used by AST nodes and types?
6127 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6128 (unsigned long) astContext.getASTAllocatedMemory());
6129
6130 // How much memory is used by identifiers?
6131 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6132 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6133
6134 // How much memory is used for selectors?
6135 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6136 (unsigned long) astContext.Selectors.getTotalMemory());
6137
6138 // How much memory is used by ASTContext's side tables?
6139 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6140 (unsigned long) astContext.getSideTableAllocatedMemory());
6141
6142 // How much memory is used for caching global code completion results?
6143 unsigned long completionBytes = 0;
6144 if (GlobalCodeCompletionAllocator *completionAllocator =
6145 astUnit->getCachedCompletionAllocator().getPtr()) {
6146 completionBytes = completionAllocator->getTotalMemory();
6147 }
6148 createCXTUResourceUsageEntry(*entries,
6149 CXTUResourceUsage_GlobalCompletionResults,
6150 completionBytes);
6151
6152 // How much memory is being used by SourceManager's content cache?
6153 createCXTUResourceUsageEntry(*entries,
6154 CXTUResourceUsage_SourceManagerContentCache,
6155 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6156
6157 // How much memory is being used by the MemoryBuffer's in SourceManager?
6158 const SourceManager::MemoryBufferSizes &srcBufs =
6159 astUnit->getSourceManager().getMemoryBufferSizes();
6160
6161 createCXTUResourceUsageEntry(*entries,
6162 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6163 (unsigned long) srcBufs.malloc_bytes);
6164 createCXTUResourceUsageEntry(*entries,
6165 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6166 (unsigned long) srcBufs.mmap_bytes);
6167 createCXTUResourceUsageEntry(*entries,
6168 CXTUResourceUsage_SourceManager_DataStructures,
6169 (unsigned long) astContext.getSourceManager()
6170 .getDataStructureSizes());
6171
6172 // How much memory is being used by the ExternalASTSource?
6173 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6174 const ExternalASTSource::MemoryBufferSizes &sizes =
6175 esrc->getMemoryBufferSizes();
6176
6177 createCXTUResourceUsageEntry(*entries,
6178 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6179 (unsigned long) sizes.malloc_bytes);
6180 createCXTUResourceUsageEntry(*entries,
6181 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6182 (unsigned long) sizes.mmap_bytes);
6183 }
6184
6185 // How much memory is being used by the Preprocessor?
6186 Preprocessor &pp = astUnit->getPreprocessor();
6187 createCXTUResourceUsageEntry(*entries,
6188 CXTUResourceUsage_Preprocessor,
6189 pp.getTotalMemory());
6190
6191 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6192 createCXTUResourceUsageEntry(*entries,
6193 CXTUResourceUsage_PreprocessingRecord,
6194 pRec->getTotalMemory());
6195 }
6196
6197 createCXTUResourceUsageEntry(*entries,
6198 CXTUResourceUsage_Preprocessor_HeaderSearch,
6199 pp.getHeaderSearchInfo().getTotalMemory());
6200
6201 CXTUResourceUsage usage = { (void*) entries.get(),
6202 (unsigned) entries->size(),
6203 entries->size() ? &(*entries)[0] : 0 };
6204 entries.take();
6205 return usage;
6206}
6207
6208void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6209 if (usage.data)
6210 delete (MemUsageEntries*) usage.data;
6211}
6212
6213} // end extern "C"
6214
6215void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6216 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6217 for (unsigned I = 0; I != Usage.numEntries; ++I)
6218 fprintf(stderr, " %s: %lu\n",
6219 clang_getTUResourceUsageName(Usage.entries[I].kind),
6220 Usage.entries[I].amount);
6221
6222 clang_disposeCXTUResourceUsage(Usage);
6223}
6224
6225//===----------------------------------------------------------------------===//
6226// Misc. utility functions.
6227//===----------------------------------------------------------------------===//
6228
6229/// Default to using an 8 MB stack size on "safety" threads.
6230static unsigned SafetyStackThreadSize = 8 << 20;
6231
6232namespace clang {
6233
6234bool RunSafely(llvm::CrashRecoveryContext &CRC,
6235 void (*Fn)(void*), void *UserData,
6236 unsigned Size) {
6237 if (!Size)
6238 Size = GetSafetyThreadStackSize();
6239 if (Size)
6240 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6241 return CRC.RunSafely(Fn, UserData);
6242}
6243
6244unsigned GetSafetyThreadStackSize() {
6245 return SafetyStackThreadSize;
6246}
6247
6248void SetSafetyThreadStackSize(unsigned Value) {
6249 SafetyStackThreadSize = Value;
6250}
6251
6252}
6253
6254void clang::setThreadBackgroundPriority() {
6255 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6256 return;
6257
6258 // FIXME: Move to llvm/Support and make it cross-platform.
6259#ifdef __APPLE__
6260 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6261#endif
6262}
6263
6264void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6265 if (!Unit)
6266 return;
6267
6268 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6269 DEnd = Unit->stored_diag_end();
6270 D != DEnd; ++D) {
6271 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6272 CXString Msg = clang_formatDiagnostic(&Diag,
6273 clang_defaultDiagnosticDisplayOptions());
6274 fprintf(stderr, "%s\n", clang_getCString(Msg));
6275 clang_disposeString(Msg);
6276 }
6277#ifdef LLVM_ON_WIN32
6278 // On Windows, force a flush, since there may be multiple copies of
6279 // stderr and stdout in the file system, all with different buffers
6280 // but writing to the same device.
6281 fflush(stderr);
6282#endif
6283}
6284
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006285MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6286 SourceLocation MacroDefLoc,
6287 CXTranslationUnit TU){
6288 if (MacroDefLoc.isInvalid() || !TU)
6289 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006290 if (!II.hadMacroDefinition())
6291 return 0;
6292
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006293 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006294 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006295 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
6296 while (MD) {
6297 if (MacroDefLoc == MD->getInfo()->getDefinitionLoc())
6298 return MD->getInfo();
6299 MD = MD->getPrevious();
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006300 }
6301
6302 return 0;
6303}
6304
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006305const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6306 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006307 if (!MacroDef || !TU)
6308 return 0;
6309 const IdentifierInfo *II = MacroDef->getName();
6310 if (!II)
6311 return 0;
6312
6313 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6314}
6315
6316MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6317 const Token &Tok,
6318 CXTranslationUnit TU) {
6319 if (!MI || !TU)
6320 return 0;
6321 if (Tok.isNot(tok::raw_identifier))
6322 return 0;
6323
6324 if (MI->getNumTokens() == 0)
6325 return 0;
6326 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6327 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006328 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006329
6330 // Check that the token is inside the definition and not its argument list.
6331 SourceManager &SM = Unit->getSourceManager();
6332 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6333 return 0;
6334 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6335 return 0;
6336
6337 Preprocessor &PP = Unit->getPreprocessor();
6338 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6339 if (!PPRec)
6340 return 0;
6341
6342 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6343 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6344 if (!II.hadMacroDefinition())
6345 return 0;
6346
6347 // Check that the identifier is not one of the macro arguments.
6348 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6349 return 0;
6350
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006351 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6352 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006353 return 0;
6354
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006355 return PPRec->findMacroDefinition(InnerMD->getInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006356}
6357
6358MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6359 SourceLocation Loc,
6360 CXTranslationUnit TU) {
6361 if (Loc.isInvalid() || !MI || !TU)
6362 return 0;
6363
6364 if (MI->getNumTokens() == 0)
6365 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006366 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006367 Preprocessor &PP = Unit->getPreprocessor();
6368 if (!PP.getPreprocessingRecord())
6369 return 0;
6370 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6371 Token Tok;
6372 if (PP.getRawToken(Loc, Tok))
6373 return 0;
6374
6375 return checkForMacroInMacroDefinition(MI, Tok, TU);
6376}
6377
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006378extern "C" {
6379
6380CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006381 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006382}
6383
6384} // end: extern "C"
6385
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006386Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6387 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006388 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006389 LogOS << '<' << Unit->getMainFileName() << '>';
6390 return *this;
6391 }
6392 }
6393
6394 LogOS << "<NULL TU>";
6395 return *this;
6396}
6397
6398Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6399 CXFile File;
6400 unsigned Line, Column;
6401 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6402 CXString FileName = clang_getFileName(File);
6403 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6404 clang_disposeString(FileName);
6405 return *this;
6406}
6407
6408Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6409 CXSourceLocation BLoc = clang_getRangeStart(range);
6410 CXSourceLocation ELoc = clang_getRangeEnd(range);
6411
6412 CXFile BFile;
6413 unsigned BLine, BColumn;
6414 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6415
6416 CXFile EFile;
6417 unsigned ELine, EColumn;
6418 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6419
6420 CXString BFileName = clang_getFileName(BFile);
6421 if (BFile == EFile) {
6422 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6423 BLine, BColumn, ELine, EColumn);
6424 } else {
6425 CXString EFileName = clang_getFileName(EFile);
6426 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6427 BLine, BColumn)
6428 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6429 ELine, EColumn);
6430 clang_disposeString(EFileName);
6431 }
6432 clang_disposeString(BFileName);
6433 return *this;
6434}
6435
6436Logger &cxindex::Logger::operator<<(CXString Str) {
6437 *this << clang_getCString(Str);
6438 return *this;
6439}
6440
6441Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6442 LogOS << Fmt;
6443 return *this;
6444}
6445
6446cxindex::Logger::~Logger() {
6447 LogOS.flush();
6448
6449 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6450
6451 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6452
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006453 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006454 OS << "[libclang:" << Name << ':';
6455
6456 // FIXME: Portability.
6457#if HAVE_PTHREAD_H && __APPLE__
6458 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6459 OS << tid << ':';
6460#endif
6461
6462 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6463 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6464 OS << Msg.str() << '\n';
6465
6466 if (Trace) {
6467 llvm::sys::PrintStackTrace(stderr);
6468 OS << "--------------------------------------------------\n";
6469 }
6470}