blob: 65d2901291980de1042039c77c39c28504dbfe3c [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
560llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
561 if (RegionOfInterest.isValid()) {
562 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
563 if (Range.isInvalid())
564 return llvm::Optional<bool>();
565
566 switch (CompareRegionOfInterest(Range)) {
567 case RangeBefore:
568 // This declaration comes before the region of interest; skip it.
569 return llvm::Optional<bool>();
570
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
620 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
621 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();
674 if (TemplateSpecializationTypeLoc *TSTLoc
675 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
676 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
677 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
678 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();
753 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
754
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.
758 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
759 (!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.
774 if (FTL && VisitFunctionTypeLoc(*FTL, true))
775 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);
984 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
985 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;
2363 } else if (isa<FunctionProtoTypeLoc>(TL)) {
2364 FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
2365 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
3425 SmallString<64> Str;
3426 llvm::raw_svector_ostream OS(Str);
3427 OS << *ClassSpec;
3428 OS << TemplateSpecializationType::PrintTemplateArgumentList(
3429 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.
4460 case Decl::TranslationUnit:
4461 break;
4462
4463 // Declaration kinds for which the definition is not resolvable.
4464 case Decl::UnresolvedUsingTypename:
4465 case Decl::UnresolvedUsingValue:
4466 break;
4467
4468 case Decl::UsingDirective:
4469 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4470 TU);
4471
4472 case Decl::NamespaceAlias:
4473 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4474
4475 case Decl::Enum:
4476 case Decl::Record:
4477 case Decl::CXXRecord:
4478 case Decl::ClassTemplateSpecialization:
4479 case Decl::ClassTemplatePartialSpecialization:
4480 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4481 return MakeCXCursor(Def, TU);
4482 return clang_getNullCursor();
4483
4484 case Decl::Function:
4485 case Decl::CXXMethod:
4486 case Decl::CXXConstructor:
4487 case Decl::CXXDestructor:
4488 case Decl::CXXConversion: {
4489 const FunctionDecl *Def = 0;
4490 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004491 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004492 return clang_getNullCursor();
4493 }
4494
4495 case Decl::Var: {
4496 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004497 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004498 return MakeCXCursor(Def, TU);
4499 return clang_getNullCursor();
4500 }
4501
4502 case Decl::FunctionTemplate: {
4503 const FunctionDecl *Def = 0;
4504 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4505 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4506 return clang_getNullCursor();
4507 }
4508
4509 case Decl::ClassTemplate: {
4510 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4511 ->getDefinition())
4512 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4513 TU);
4514 return clang_getNullCursor();
4515 }
4516
4517 case Decl::Using:
4518 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4519 D->getLocation(), TU);
4520
4521 case Decl::UsingShadow:
4522 return clang_getCursorDefinition(
4523 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4524 TU));
4525
4526 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004527 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004528 if (Method->isThisDeclarationADefinition())
4529 return C;
4530
4531 // Dig out the method definition in the associated
4532 // @implementation, if we have it.
4533 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004534 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004535 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4536 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4537 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4538 Method->isInstanceMethod()))
4539 if (Def->isThisDeclarationADefinition())
4540 return MakeCXCursor(Def, TU);
4541
4542 return clang_getNullCursor();
4543 }
4544
4545 case Decl::ObjCCategory:
4546 if (ObjCCategoryImplDecl *Impl
4547 = cast<ObjCCategoryDecl>(D)->getImplementation())
4548 return MakeCXCursor(Impl, TU);
4549 return clang_getNullCursor();
4550
4551 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004552 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004553 return MakeCXCursor(Def, TU);
4554 return clang_getNullCursor();
4555
4556 case Decl::ObjCInterface: {
4557 // There are two notions of a "definition" for an Objective-C
4558 // class: the interface and its implementation. When we resolved a
4559 // reference to an Objective-C class, produce the @interface as
4560 // the definition; when we were provided with the interface,
4561 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004562 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004563 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004564 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004565 return MakeCXCursor(Def, TU);
4566 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4567 return MakeCXCursor(Impl, TU);
4568 return clang_getNullCursor();
4569 }
4570
4571 case Decl::ObjCProperty:
4572 // FIXME: We don't really know where to find the
4573 // ObjCPropertyImplDecls that implement this property.
4574 return clang_getNullCursor();
4575
4576 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004577 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004578 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004579 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004580 return MakeCXCursor(Def, TU);
4581
4582 return clang_getNullCursor();
4583
4584 case Decl::Friend:
4585 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4586 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4587 return clang_getNullCursor();
4588
4589 case Decl::FriendTemplate:
4590 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4591 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4592 return clang_getNullCursor();
4593 }
4594
4595 return clang_getNullCursor();
4596}
4597
4598unsigned clang_isCursorDefinition(CXCursor C) {
4599 if (!clang_isDeclaration(C.kind))
4600 return 0;
4601
4602 return clang_getCursorDefinition(C) == C;
4603}
4604
4605CXCursor clang_getCanonicalCursor(CXCursor C) {
4606 if (!clang_isDeclaration(C.kind))
4607 return C;
4608
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004609 if (const Decl *D = getCursorDecl(C)) {
4610 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004611 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4612 return MakeCXCursor(CatD, getCursorTU(C));
4613
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004614 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4615 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004616 return MakeCXCursor(IFD, getCursorTU(C));
4617
4618 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4619 }
4620
4621 return C;
4622}
4623
4624int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4625 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4626}
4627
4628unsigned clang_getNumOverloadedDecls(CXCursor C) {
4629 if (C.kind != CXCursor_OverloadedDeclRef)
4630 return 0;
4631
4632 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004633 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004634 return E->getNumDecls();
4635
4636 if (OverloadedTemplateStorage *S
4637 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4638 return S->size();
4639
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004640 const Decl *D = Storage.get<const Decl *>();
4641 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004642 return Using->shadow_size();
4643
4644 return 0;
4645}
4646
4647CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4648 if (cursor.kind != CXCursor_OverloadedDeclRef)
4649 return clang_getNullCursor();
4650
4651 if (index >= clang_getNumOverloadedDecls(cursor))
4652 return clang_getNullCursor();
4653
4654 CXTranslationUnit TU = getCursorTU(cursor);
4655 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004656 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004657 return MakeCXCursor(E->decls_begin()[index], TU);
4658
4659 if (OverloadedTemplateStorage *S
4660 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4661 return MakeCXCursor(S->begin()[index], TU);
4662
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004663 const Decl *D = Storage.get<const Decl *>();
4664 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004665 // FIXME: This is, unfortunately, linear time.
4666 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4667 std::advance(Pos, index);
4668 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4669 }
4670
4671 return clang_getNullCursor();
4672}
4673
4674void clang_getDefinitionSpellingAndExtent(CXCursor C,
4675 const char **startBuf,
4676 const char **endBuf,
4677 unsigned *startLine,
4678 unsigned *startColumn,
4679 unsigned *endLine,
4680 unsigned *endColumn) {
4681 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004682 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004683 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4684
4685 SourceManager &SM = FD->getASTContext().getSourceManager();
4686 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4687 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4688 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4689 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4690 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4691 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4692}
4693
4694
4695CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4696 unsigned PieceIndex) {
4697 RefNamePieces Pieces;
4698
4699 switch (C.kind) {
4700 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004701 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004702 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4703 E->getQualifierLoc().getSourceRange());
4704 break;
4705
4706 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004707 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004708 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4709 E->getQualifierLoc().getSourceRange(),
4710 E->getOptionalExplicitTemplateArgs());
4711 break;
4712
4713 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004714 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004715 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004716 const Expr *Callee = OCE->getCallee();
4717 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004718 Callee = ICE->getSubExpr();
4719
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004720 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004721 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4722 DRE->getQualifierLoc().getSourceRange());
4723 }
4724 break;
4725
4726 default:
4727 break;
4728 }
4729
4730 if (Pieces.empty()) {
4731 if (PieceIndex == 0)
4732 return clang_getCursorExtent(C);
4733 } else if (PieceIndex < Pieces.size()) {
4734 SourceRange R = Pieces[PieceIndex];
4735 if (R.isValid())
4736 return cxloc::translateSourceRange(getCursorContext(C), R);
4737 }
4738
4739 return clang_getNullRange();
4740}
4741
4742void clang_enableStackTraces(void) {
4743 llvm::sys::PrintStackTraceOnErrorSignal();
4744}
4745
4746void clang_executeOnThread(void (*fn)(void*), void *user_data,
4747 unsigned stack_size) {
4748 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4749}
4750
4751} // end: extern "C"
4752
4753//===----------------------------------------------------------------------===//
4754// Token-based Operations.
4755//===----------------------------------------------------------------------===//
4756
4757/* CXToken layout:
4758 * int_data[0]: a CXTokenKind
4759 * int_data[1]: starting token location
4760 * int_data[2]: token length
4761 * int_data[3]: reserved
4762 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4763 * otherwise unused.
4764 */
4765extern "C" {
4766
4767CXTokenKind clang_getTokenKind(CXToken CXTok) {
4768 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4769}
4770
4771CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4772 switch (clang_getTokenKind(CXTok)) {
4773 case CXToken_Identifier:
4774 case CXToken_Keyword:
4775 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004776 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004777 ->getNameStart());
4778
4779 case CXToken_Literal: {
4780 // We have stashed the starting pointer in the ptr_data field. Use it.
4781 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004782 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004783 }
4784
4785 case CXToken_Punctuation:
4786 case CXToken_Comment:
4787 break;
4788 }
4789
4790 // We have to find the starting buffer pointer the hard way, by
4791 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004792 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004793 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004794 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004795
4796 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4797 std::pair<FileID, unsigned> LocInfo
4798 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4799 bool Invalid = false;
4800 StringRef Buffer
4801 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4802 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004803 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004804
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004805 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004806}
4807
4808CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004809 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004810 if (!CXXUnit)
4811 return clang_getNullLocation();
4812
4813 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4814 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4815}
4816
4817CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004818 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004819 if (!CXXUnit)
4820 return clang_getNullRange();
4821
4822 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4823 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4824}
4825
4826static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4827 SmallVectorImpl<CXToken> &CXTokens) {
4828 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4829 std::pair<FileID, unsigned> BeginLocInfo
4830 = SourceMgr.getDecomposedLoc(Range.getBegin());
4831 std::pair<FileID, unsigned> EndLocInfo
4832 = SourceMgr.getDecomposedLoc(Range.getEnd());
4833
4834 // Cannot tokenize across files.
4835 if (BeginLocInfo.first != EndLocInfo.first)
4836 return;
4837
4838 // Create a lexer
4839 bool Invalid = false;
4840 StringRef Buffer
4841 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4842 if (Invalid)
4843 return;
4844
4845 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4846 CXXUnit->getASTContext().getLangOpts(),
4847 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4848 Lex.SetCommentRetentionState(true);
4849
4850 // Lex tokens until we hit the end of the range.
4851 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4852 Token Tok;
4853 bool previousWasAt = false;
4854 do {
4855 // Lex the next token
4856 Lex.LexFromRawLexer(Tok);
4857 if (Tok.is(tok::eof))
4858 break;
4859
4860 // Initialize the CXToken.
4861 CXToken CXTok;
4862
4863 // - Common fields
4864 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4865 CXTok.int_data[2] = Tok.getLength();
4866 CXTok.int_data[3] = 0;
4867
4868 // - Kind-specific fields
4869 if (Tok.isLiteral()) {
4870 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004871 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004872 } else if (Tok.is(tok::raw_identifier)) {
4873 // Lookup the identifier to determine whether we have a keyword.
4874 IdentifierInfo *II
4875 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4876
4877 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4878 CXTok.int_data[0] = CXToken_Keyword;
4879 }
4880 else {
4881 CXTok.int_data[0] = Tok.is(tok::identifier)
4882 ? CXToken_Identifier
4883 : CXToken_Keyword;
4884 }
4885 CXTok.ptr_data = II;
4886 } else if (Tok.is(tok::comment)) {
4887 CXTok.int_data[0] = CXToken_Comment;
4888 CXTok.ptr_data = 0;
4889 } else {
4890 CXTok.int_data[0] = CXToken_Punctuation;
4891 CXTok.ptr_data = 0;
4892 }
4893 CXTokens.push_back(CXTok);
4894 previousWasAt = Tok.is(tok::at);
4895 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4896}
4897
4898void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4899 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004900 LOG_FUNC_SECTION {
4901 *Log << TU << ' ' << Range;
4902 }
4903
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004904 if (Tokens)
4905 *Tokens = 0;
4906 if (NumTokens)
4907 *NumTokens = 0;
4908
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004909 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004910 if (!CXXUnit || !Tokens || !NumTokens)
4911 return;
4912
4913 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4914
4915 SourceRange R = cxloc::translateCXSourceRange(Range);
4916 if (R.isInvalid())
4917 return;
4918
4919 SmallVector<CXToken, 32> CXTokens;
4920 getTokens(CXXUnit, R, CXTokens);
4921
4922 if (CXTokens.empty())
4923 return;
4924
4925 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4926 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4927 *NumTokens = CXTokens.size();
4928}
4929
4930void clang_disposeTokens(CXTranslationUnit TU,
4931 CXToken *Tokens, unsigned NumTokens) {
4932 free(Tokens);
4933}
4934
4935} // end: extern "C"
4936
4937//===----------------------------------------------------------------------===//
4938// Token annotation APIs.
4939//===----------------------------------------------------------------------===//
4940
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004941static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4942 CXCursor parent,
4943 CXClientData client_data);
4944static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4945 CXClientData client_data);
4946
4947namespace {
4948class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004949 CXToken *Tokens;
4950 CXCursor *Cursors;
4951 unsigned NumTokens;
4952 unsigned TokIdx;
4953 unsigned PreprocessingTokIdx;
4954 CursorVisitor AnnotateVis;
4955 SourceManager &SrcMgr;
4956 bool HasContextSensitiveKeywords;
4957
4958 struct PostChildrenInfo {
4959 CXCursor Cursor;
4960 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004961 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004962 unsigned BeforeChildrenTokenIdx;
4963 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004964 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004965
4966 bool MoreTokens() const { return TokIdx < NumTokens; }
4967 unsigned NextToken() const { return TokIdx; }
4968 void AdvanceToken() { ++TokIdx; }
4969 SourceLocation GetTokenLoc(unsigned tokI) {
4970 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4971 }
4972 bool isFunctionMacroToken(unsigned tokI) const {
4973 return Tokens[tokI].int_data[3] != 0;
4974 }
4975 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4976 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4977 }
4978
4979 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004980 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004981 SourceRange);
4982
4983public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004984 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004985 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004986 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004987 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004988 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004989 AnnotateTokensVisitor, this,
4990 /*VisitPreprocessorLast=*/true,
4991 /*VisitIncludedEntities=*/false,
4992 RegionOfInterest,
4993 /*VisitDeclsOnly=*/false,
4994 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004995 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004996 HasContextSensitiveKeywords(false) { }
4997
4998 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
4999 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5000 bool postVisitChildren(CXCursor cursor);
5001 void AnnotateTokens();
5002
5003 /// \brief Determine whether the annotator saw any cursors that have
5004 /// context-sensitive keywords.
5005 bool hasContextSensitiveKeywords() const {
5006 return HasContextSensitiveKeywords;
5007 }
5008
5009 ~AnnotateTokensWorker() {
5010 assert(PostChildrenInfos.empty());
5011 }
5012};
5013}
5014
5015void AnnotateTokensWorker::AnnotateTokens() {
5016 // Walk the AST within the region of interest, annotating tokens
5017 // along the way.
5018 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005019}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005020
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005021static inline void updateCursorAnnotation(CXCursor &Cursor,
5022 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005023 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005024 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005025 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005026}
5027
5028/// \brief It annotates and advances tokens with a cursor until the comparison
5029//// between the cursor location and the source range is the same as
5030/// \arg compResult.
5031///
5032/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5033/// Pass RangeOverlap to annotate tokens inside a range.
5034void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5035 RangeComparisonResult compResult,
5036 SourceRange range) {
5037 while (MoreTokens()) {
5038 const unsigned I = NextToken();
5039 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005040 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5041 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005042
5043 SourceLocation TokLoc = GetTokenLoc(I);
5044 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005045 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005046 AdvanceToken();
5047 continue;
5048 }
5049 break;
5050 }
5051}
5052
5053/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005054/// \returns true if it advanced beyond all macro tokens, false otherwise.
5055bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005056 CXCursor updateC,
5057 RangeComparisonResult compResult,
5058 SourceRange range) {
5059 assert(MoreTokens());
5060 assert(isFunctionMacroToken(NextToken()) &&
5061 "Should be called only for macro arg tokens");
5062
5063 // This works differently than annotateAndAdvanceTokens; because expanded
5064 // macro arguments can have arbitrary translation-unit source order, we do not
5065 // advance the token index one by one until a token fails the range test.
5066 // We only advance once past all of the macro arg tokens if all of them
5067 // pass the range test. If one of them fails we keep the token index pointing
5068 // at the start of the macro arg tokens so that the failing token will be
5069 // annotated by a subsequent annotation try.
5070
5071 bool atLeastOneCompFail = false;
5072
5073 unsigned I = NextToken();
5074 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5075 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5076 if (TokLoc.isFileID())
5077 continue; // not macro arg token, it's parens or comma.
5078 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5079 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5080 Cursors[I] = updateC;
5081 } else
5082 atLeastOneCompFail = true;
5083 }
5084
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005085 if (atLeastOneCompFail)
5086 return false;
5087
5088 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5089 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005090}
5091
5092enum CXChildVisitResult
5093AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005094 SourceRange cursorRange = getRawCursorExtent(cursor);
5095 if (cursorRange.isInvalid())
5096 return CXChildVisit_Recurse;
5097
5098 if (!HasContextSensitiveKeywords) {
5099 // Objective-C properties can have context-sensitive keywords.
5100 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005101 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005102 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5103 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5104 }
5105 // Objective-C methods can have context-sensitive keywords.
5106 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5107 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005108 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005109 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5110 if (Method->getObjCDeclQualifier())
5111 HasContextSensitiveKeywords = true;
5112 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005113 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5114 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005115 P != PEnd; ++P) {
5116 if ((*P)->getObjCDeclQualifier()) {
5117 HasContextSensitiveKeywords = true;
5118 break;
5119 }
5120 }
5121 }
5122 }
5123 }
5124 // C++ methods can have context-sensitive keywords.
5125 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005126 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005127 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5128 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5129 HasContextSensitiveKeywords = true;
5130 }
5131 }
5132 // C++ classes can have context-sensitive keywords.
5133 else if (cursor.kind == CXCursor_StructDecl ||
5134 cursor.kind == CXCursor_ClassDecl ||
5135 cursor.kind == CXCursor_ClassTemplate ||
5136 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005137 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005138 if (D->hasAttr<FinalAttr>())
5139 HasContextSensitiveKeywords = true;
5140 }
5141 }
5142
5143 if (clang_isPreprocessing(cursor.kind)) {
5144 // Items in the preprocessing record are kept separate from items in
5145 // declarations, so we keep a separate token index.
5146 unsigned SavedTokIdx = TokIdx;
5147 TokIdx = PreprocessingTokIdx;
5148
5149 // Skip tokens up until we catch up to the beginning of the preprocessing
5150 // entry.
5151 while (MoreTokens()) {
5152 const unsigned I = NextToken();
5153 SourceLocation TokLoc = GetTokenLoc(I);
5154 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5155 case RangeBefore:
5156 AdvanceToken();
5157 continue;
5158 case RangeAfter:
5159 case RangeOverlap:
5160 break;
5161 }
5162 break;
5163 }
5164
5165 // Look at all of the tokens within this range.
5166 while (MoreTokens()) {
5167 const unsigned I = NextToken();
5168 SourceLocation TokLoc = GetTokenLoc(I);
5169 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5170 case RangeBefore:
5171 llvm_unreachable("Infeasible");
5172 case RangeAfter:
5173 break;
5174 case RangeOverlap:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005175 // We may have already annotated macro names inside macro definitions.
5176 if (Cursors[I].kind != CXCursor_MacroExpansion)
5177 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005178 AdvanceToken();
5179 // For macro expansions, just note where the beginning of the macro
5180 // expansion occurs.
5181 if (cursor.kind == CXCursor_MacroExpansion)
5182 break;
5183 continue;
5184 }
5185 break;
5186 }
5187
5188 // Save the preprocessing token index; restore the non-preprocessing
5189 // token index.
5190 PreprocessingTokIdx = TokIdx;
5191 TokIdx = SavedTokIdx;
5192 return CXChildVisit_Recurse;
5193 }
5194
5195 if (cursorRange.isInvalid())
5196 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005197
5198 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005199 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005200 const enum CXCursorKind K = clang_getCursorKind(parent);
5201 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005202 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5203 // Attributes are annotated out-of-order, skip tokens until we reach it.
5204 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005205 ? clang_getNullCursor() : parent;
5206
5207 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5208
5209 // Avoid having the cursor of an expression "overwrite" the annotation of the
5210 // variable declaration that it belongs to.
5211 // This can happen for C++ constructor expressions whose range generally
5212 // include the variable declaration, e.g.:
5213 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5214 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005215 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005216 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005217 const unsigned I = NextToken();
5218 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5219 E->getLocStart() == D->getLocation() &&
5220 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005221 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005222 AdvanceToken();
5223 }
5224 }
5225 }
5226
5227 // Before recursing into the children keep some state that we are going
5228 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5229 // extra work after the child nodes are visited.
5230 // Note that we don't call VisitChildren here to avoid traversing statements
5231 // code-recursively which can blow the stack.
5232
5233 PostChildrenInfo Info;
5234 Info.Cursor = cursor;
5235 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005236 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005237 Info.BeforeChildrenTokenIdx = NextToken();
5238 PostChildrenInfos.push_back(Info);
5239
5240 return CXChildVisit_Recurse;
5241}
5242
5243bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5244 if (PostChildrenInfos.empty())
5245 return false;
5246 const PostChildrenInfo &Info = PostChildrenInfos.back();
5247 if (!clang_equalCursors(Info.Cursor, cursor))
5248 return false;
5249
5250 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5251 const unsigned AfterChildren = NextToken();
5252 SourceRange cursorRange = Info.CursorRange;
5253
5254 // Scan the tokens that are at the end of the cursor, but are not captured
5255 // but the child cursors.
5256 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5257
5258 // Scan the tokens that are at the beginning of the cursor, but are not
5259 // capture by the child cursors.
5260 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5261 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5262 break;
5263
5264 Cursors[I] = cursor;
5265 }
5266
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005267 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5268 // encountered the attribute cursor.
5269 if (clang_isAttribute(cursor.kind))
5270 TokIdx = Info.BeforeReachingCursorIdx;
5271
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005272 PostChildrenInfos.pop_back();
5273 return false;
5274}
5275
5276static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5277 CXCursor parent,
5278 CXClientData client_data) {
5279 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5280}
5281
5282static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5283 CXClientData client_data) {
5284 return static_cast<AnnotateTokensWorker*>(client_data)->
5285 postVisitChildren(cursor);
5286}
5287
5288namespace {
5289
5290/// \brief Uses the macro expansions in the preprocessing record to find
5291/// and mark tokens that are macro arguments. This info is used by the
5292/// AnnotateTokensWorker.
5293class MarkMacroArgTokensVisitor {
5294 SourceManager &SM;
5295 CXToken *Tokens;
5296 unsigned NumTokens;
5297 unsigned CurIdx;
5298
5299public:
5300 MarkMacroArgTokensVisitor(SourceManager &SM,
5301 CXToken *tokens, unsigned numTokens)
5302 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5303
5304 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5305 if (cursor.kind != CXCursor_MacroExpansion)
5306 return CXChildVisit_Continue;
5307
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005308 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005309 if (macroRange.getBegin() == macroRange.getEnd())
5310 return CXChildVisit_Continue; // it's not a function macro.
5311
5312 for (; CurIdx < NumTokens; ++CurIdx) {
5313 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5314 macroRange.getBegin()))
5315 break;
5316 }
5317
5318 if (CurIdx == NumTokens)
5319 return CXChildVisit_Break;
5320
5321 for (; CurIdx < NumTokens; ++CurIdx) {
5322 SourceLocation tokLoc = getTokenLoc(CurIdx);
5323 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5324 break;
5325
5326 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5327 }
5328
5329 if (CurIdx == NumTokens)
5330 return CXChildVisit_Break;
5331
5332 return CXChildVisit_Continue;
5333 }
5334
5335private:
5336 SourceLocation getTokenLoc(unsigned tokI) {
5337 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5338 }
5339
5340 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5341 // The third field is reserved and currently not used. Use it here
5342 // to mark macro arg expanded tokens with their expanded locations.
5343 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5344 }
5345};
5346
5347} // end anonymous namespace
5348
5349static CXChildVisitResult
5350MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5351 CXClientData client_data) {
5352 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5353 parent);
5354}
5355
5356namespace {
5357 struct clang_annotateTokens_Data {
5358 CXTranslationUnit TU;
5359 ASTUnit *CXXUnit;
5360 CXToken *Tokens;
5361 unsigned NumTokens;
5362 CXCursor *Cursors;
5363 };
5364}
5365
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005366/// \brief Used by \c annotatePreprocessorTokens.
5367/// \returns true if lexing was finished, false otherwise.
5368static bool lexNext(Lexer &Lex, Token &Tok,
5369 unsigned &NextIdx, unsigned NumTokens) {
5370 if (NextIdx >= NumTokens)
5371 return true;
5372
5373 ++NextIdx;
5374 Lex.LexFromRawLexer(Tok);
5375 if (Tok.is(tok::eof))
5376 return true;
5377
5378 return false;
5379}
5380
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005381static void annotatePreprocessorTokens(CXTranslationUnit TU,
5382 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005383 CXCursor *Cursors,
5384 CXToken *Tokens,
5385 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005386 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005387
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005388 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005389 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5390 std::pair<FileID, unsigned> BeginLocInfo
5391 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
5392 std::pair<FileID, unsigned> EndLocInfo
5393 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
5394
5395 if (BeginLocInfo.first != EndLocInfo.first)
5396 return;
5397
5398 StringRef Buffer;
5399 bool Invalid = false;
5400 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5401 if (Buffer.empty() || Invalid)
5402 return;
5403
5404 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5405 CXXUnit->getASTContext().getLangOpts(),
5406 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5407 Buffer.end());
5408 Lex.SetCommentRetentionState(true);
5409
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005410 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005411 // Lex tokens in raw mode until we hit the end of the range, to avoid
5412 // entering #includes or expanding macros.
5413 while (true) {
5414 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005415 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5416 break;
5417 unsigned TokIdx = NextIdx-1;
5418 assert(Tok.getLocation() ==
5419 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005420
5421 reprocess:
5422 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005423 // We have found a preprocessing directive. Annotate the tokens
5424 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005425 //
5426 // FIXME: Some simple tests here could identify macro definitions and
5427 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005428
5429 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005430 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5431 break;
5432
5433 MacroInfo *MI = 0;
5434 if (Tok.is(tok::raw_identifier) &&
5435 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5436 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5437 break;
5438
5439 if (Tok.is(tok::raw_identifier)) {
5440 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5441 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5442 SourceLocation MappedTokLoc =
5443 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5444 MI = getMacroInfo(II, MappedTokLoc, TU);
5445 }
5446 }
5447
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005448 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005449 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005450 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5451 finished = true;
5452 break;
5453 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005454 // If we are in a macro definition, check if the token was ever a
5455 // macro name and annotate it if that's the case.
5456 if (MI) {
5457 SourceLocation SaveLoc = Tok.getLocation();
5458 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5459 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5460 Tok.setLocation(SaveLoc);
5461 if (MacroDef)
5462 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5463 Tok.getLocation(), TU);
5464 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005465 } while (!Tok.isAtStartOfLine());
5466
5467 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5468 assert(TokIdx <= LastIdx);
5469 SourceLocation EndLoc =
5470 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5471 CXCursor Cursor =
5472 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5473
5474 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005475 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005476
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005477 if (finished)
5478 break;
5479 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005480 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005481 }
5482}
5483
5484// This gets run a separate thread to avoid stack blowout.
5485static void clang_annotateTokensImpl(void *UserData) {
5486 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5487 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5488 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5489 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5490 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5491
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005492 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005493 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5494 setThreadBackgroundPriority();
5495
5496 // Determine the region of interest, which contains all of the tokens.
5497 SourceRange RegionOfInterest;
5498 RegionOfInterest.setBegin(
5499 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5500 RegionOfInterest.setEnd(
5501 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5502 Tokens[NumTokens-1])));
5503
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005504 // Relex the tokens within the source range to look for preprocessing
5505 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005506 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005507
5508 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5509 // Search and mark tokens that are macro argument expansions.
5510 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5511 Tokens, NumTokens);
5512 CursorVisitor MacroArgMarker(TU,
5513 MarkMacroArgTokensVisitorDelegate, &Visitor,
5514 /*VisitPreprocessorLast=*/true,
5515 /*VisitIncludedEntities=*/false,
5516 RegionOfInterest);
5517 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5518 }
5519
5520 // Annotate all of the source locations in the region of interest that map to
5521 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005522 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005523
5524 // FIXME: We use a ridiculous stack size here because the data-recursion
5525 // algorithm uses a large stack frame than the non-data recursive version,
5526 // and AnnotationTokensWorker currently transforms the data-recursion
5527 // algorithm back into a traditional recursion by explicitly calling
5528 // VisitChildren(). We will need to remove this explicit recursive call.
5529 W.AnnotateTokens();
5530
5531 // If we ran into any entities that involve context-sensitive keywords,
5532 // take another pass through the tokens to mark them as such.
5533 if (W.hasContextSensitiveKeywords()) {
5534 for (unsigned I = 0; I != NumTokens; ++I) {
5535 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5536 continue;
5537
5538 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5539 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005540 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005541 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5542 if (Property->getPropertyAttributesAsWritten() != 0 &&
5543 llvm::StringSwitch<bool>(II->getName())
5544 .Case("readonly", true)
5545 .Case("assign", true)
5546 .Case("unsafe_unretained", true)
5547 .Case("readwrite", true)
5548 .Case("retain", true)
5549 .Case("copy", true)
5550 .Case("nonatomic", true)
5551 .Case("atomic", true)
5552 .Case("getter", true)
5553 .Case("setter", true)
5554 .Case("strong", true)
5555 .Case("weak", true)
5556 .Default(false))
5557 Tokens[I].int_data[0] = CXToken_Keyword;
5558 }
5559 continue;
5560 }
5561
5562 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5563 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5564 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5565 if (llvm::StringSwitch<bool>(II->getName())
5566 .Case("in", true)
5567 .Case("out", true)
5568 .Case("inout", true)
5569 .Case("oneway", true)
5570 .Case("bycopy", true)
5571 .Case("byref", true)
5572 .Default(false))
5573 Tokens[I].int_data[0] = CXToken_Keyword;
5574 continue;
5575 }
5576
5577 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5578 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5579 Tokens[I].int_data[0] = CXToken_Keyword;
5580 continue;
5581 }
5582 }
5583 }
5584}
5585
5586extern "C" {
5587
5588void clang_annotateTokens(CXTranslationUnit TU,
5589 CXToken *Tokens, unsigned NumTokens,
5590 CXCursor *Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005591 if (NumTokens == 0 || !Tokens || !Cursors) {
5592 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005593 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005594 }
5595
5596 LOG_FUNC_SECTION {
5597 *Log << TU << ' ';
5598 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5599 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5600 *Log << clang_getRange(bloc, eloc);
5601 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005602
5603 // Any token we don't specifically annotate will have a NULL cursor.
5604 CXCursor C = clang_getNullCursor();
5605 for (unsigned I = 0; I != NumTokens; ++I)
5606 Cursors[I] = C;
5607
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005608 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005609 if (!CXXUnit)
5610 return;
5611
5612 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5613
5614 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5615 llvm::CrashRecoveryContext CRC;
5616 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5617 GetSafetyThreadStackSize() * 2)) {
5618 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5619 }
5620}
5621
5622} // end: extern "C"
5623
5624//===----------------------------------------------------------------------===//
5625// Operations for querying linkage of a cursor.
5626//===----------------------------------------------------------------------===//
5627
5628extern "C" {
5629CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5630 if (!clang_isDeclaration(cursor.kind))
5631 return CXLinkage_Invalid;
5632
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005633 const Decl *D = cxcursor::getCursorDecl(cursor);
5634 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005635 switch (ND->getLinkage()) {
5636 case NoLinkage: return CXLinkage_NoLinkage;
5637 case InternalLinkage: return CXLinkage_Internal;
5638 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5639 case ExternalLinkage: return CXLinkage_External;
5640 };
5641
5642 return CXLinkage_Invalid;
5643}
5644} // end: extern "C"
5645
5646//===----------------------------------------------------------------------===//
5647// Operations for querying language of a cursor.
5648//===----------------------------------------------------------------------===//
5649
5650static CXLanguageKind getDeclLanguage(const Decl *D) {
5651 if (!D)
5652 return CXLanguage_C;
5653
5654 switch (D->getKind()) {
5655 default:
5656 break;
5657 case Decl::ImplicitParam:
5658 case Decl::ObjCAtDefsField:
5659 case Decl::ObjCCategory:
5660 case Decl::ObjCCategoryImpl:
5661 case Decl::ObjCCompatibleAlias:
5662 case Decl::ObjCImplementation:
5663 case Decl::ObjCInterface:
5664 case Decl::ObjCIvar:
5665 case Decl::ObjCMethod:
5666 case Decl::ObjCProperty:
5667 case Decl::ObjCPropertyImpl:
5668 case Decl::ObjCProtocol:
5669 return CXLanguage_ObjC;
5670 case Decl::CXXConstructor:
5671 case Decl::CXXConversion:
5672 case Decl::CXXDestructor:
5673 case Decl::CXXMethod:
5674 case Decl::CXXRecord:
5675 case Decl::ClassTemplate:
5676 case Decl::ClassTemplatePartialSpecialization:
5677 case Decl::ClassTemplateSpecialization:
5678 case Decl::Friend:
5679 case Decl::FriendTemplate:
5680 case Decl::FunctionTemplate:
5681 case Decl::LinkageSpec:
5682 case Decl::Namespace:
5683 case Decl::NamespaceAlias:
5684 case Decl::NonTypeTemplateParm:
5685 case Decl::StaticAssert:
5686 case Decl::TemplateTemplateParm:
5687 case Decl::TemplateTypeParm:
5688 case Decl::UnresolvedUsingTypename:
5689 case Decl::UnresolvedUsingValue:
5690 case Decl::Using:
5691 case Decl::UsingDirective:
5692 case Decl::UsingShadow:
5693 return CXLanguage_CPlusPlus;
5694 }
5695
5696 return CXLanguage_C;
5697}
5698
5699extern "C" {
5700
5701enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5702 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005703 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005704 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5705 return CXAvailability_Available;
5706
5707 switch (D->getAvailability()) {
5708 case AR_Available:
5709 case AR_NotYetIntroduced:
5710 return CXAvailability_Available;
5711
5712 case AR_Deprecated:
5713 return CXAvailability_Deprecated;
5714
5715 case AR_Unavailable:
5716 return CXAvailability_NotAvailable;
5717 }
5718 }
5719
5720 return CXAvailability_Available;
5721}
5722
5723static CXVersion convertVersion(VersionTuple In) {
5724 CXVersion Out = { -1, -1, -1 };
5725 if (In.empty())
5726 return Out;
5727
5728 Out.Major = In.getMajor();
5729
5730 if (llvm::Optional<unsigned> Minor = In.getMinor())
5731 Out.Minor = *Minor;
5732 else
5733 return Out;
5734
5735 if (llvm::Optional<unsigned> Subminor = In.getSubminor())
5736 Out.Subminor = *Subminor;
5737
5738 return Out;
5739}
5740
5741int clang_getCursorPlatformAvailability(CXCursor cursor,
5742 int *always_deprecated,
5743 CXString *deprecated_message,
5744 int *always_unavailable,
5745 CXString *unavailable_message,
5746 CXPlatformAvailability *availability,
5747 int availability_size) {
5748 if (always_deprecated)
5749 *always_deprecated = 0;
5750 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005751 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005752 if (always_unavailable)
5753 *always_unavailable = 0;
5754 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005755 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005756
5757 if (!clang_isDeclaration(cursor.kind))
5758 return 0;
5759
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005760 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005761 if (!D)
5762 return 0;
5763
5764 int N = 0;
5765 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5766 ++A) {
5767 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5768 if (always_deprecated)
5769 *always_deprecated = 1;
5770 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005771 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005772 continue;
5773 }
5774
5775 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5776 if (always_unavailable)
5777 *always_unavailable = 1;
5778 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005779 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005780 }
5781 continue;
5782 }
5783
5784 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5785 if (N < availability_size) {
5786 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005787 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005788 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5789 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5790 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5791 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005792 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005793 }
5794 ++N;
5795 }
5796 }
5797
5798 return N;
5799}
5800
5801void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5802 clang_disposeString(availability->Platform);
5803 clang_disposeString(availability->Message);
5804}
5805
5806CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5807 if (clang_isDeclaration(cursor.kind))
5808 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5809
5810 return CXLanguage_Invalid;
5811}
5812
5813 /// \brief If the given cursor is the "templated" declaration
5814 /// descibing a class or function template, return the class or
5815 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005816static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005817 if (!D)
5818 return 0;
5819
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005820 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005821 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5822 return FunTmpl;
5823
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005824 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005825 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5826 return ClassTmpl;
5827
5828 return D;
5829}
5830
5831CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5832 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005833 if (const Decl *D = getCursorDecl(cursor)) {
5834 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005835 if (!DC)
5836 return clang_getNullCursor();
5837
5838 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5839 getCursorTU(cursor));
5840 }
5841 }
5842
5843 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005844 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005845 return MakeCXCursor(D, getCursorTU(cursor));
5846 }
5847
5848 return clang_getNullCursor();
5849}
5850
5851CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5852 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005853 if (const Decl *D = getCursorDecl(cursor)) {
5854 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005855 if (!DC)
5856 return clang_getNullCursor();
5857
5858 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5859 getCursorTU(cursor));
5860 }
5861 }
5862
5863 // FIXME: Note that we can't easily compute the lexical context of a
5864 // statement or expression, so we return nothing.
5865 return clang_getNullCursor();
5866}
5867
5868CXFile clang_getIncludedFile(CXCursor cursor) {
5869 if (cursor.kind != CXCursor_InclusionDirective)
5870 return 0;
5871
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005872 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005873 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005874}
5875
5876CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5877 if (!clang_isDeclaration(C.kind))
5878 return clang_getNullRange();
5879
5880 const Decl *D = getCursorDecl(C);
5881 ASTContext &Context = getCursorContext(C);
5882 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5883 if (!RC)
5884 return clang_getNullRange();
5885
5886 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5887}
5888
5889CXString clang_Cursor_getRawCommentText(CXCursor C) {
5890 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005891 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005892
5893 const Decl *D = getCursorDecl(C);
5894 ASTContext &Context = getCursorContext(C);
5895 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5896 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5897 StringRef();
5898
5899 // Don't duplicate the string because RawText points directly into source
5900 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005901 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005902}
5903
5904CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5905 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005906 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005907
5908 const Decl *D = getCursorDecl(C);
5909 const ASTContext &Context = getCursorContext(C);
5910 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5911
5912 if (RC) {
5913 StringRef BriefText = RC->getBriefText(Context);
5914
5915 // Don't duplicate the string because RawComment ensures that this memory
5916 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005917 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005918 }
5919
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005920 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005921}
5922
5923CXComment clang_Cursor_getParsedComment(CXCursor C) {
5924 if (!clang_isDeclaration(C.kind))
5925 return cxcomment::createCXComment(NULL, NULL);
5926
5927 const Decl *D = getCursorDecl(C);
5928 const ASTContext &Context = getCursorContext(C);
5929 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5930
5931 return cxcomment::createCXComment(FC, getCursorTU(C));
5932}
5933
5934CXModule clang_Cursor_getModule(CXCursor C) {
5935 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005936 if (const ImportDecl *ImportD =
5937 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005938 return ImportD->getImportedModule();
5939 }
5940
5941 return 0;
5942}
5943
5944CXModule clang_Module_getParent(CXModule CXMod) {
5945 if (!CXMod)
5946 return 0;
5947 Module *Mod = static_cast<Module*>(CXMod);
5948 return Mod->Parent;
5949}
5950
5951CXString clang_Module_getName(CXModule CXMod) {
5952 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005953 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005954 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005955 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005956}
5957
5958CXString clang_Module_getFullName(CXModule CXMod) {
5959 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005960 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005961 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005962 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005963}
5964
5965unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
5966 if (!CXMod)
5967 return 0;
5968 Module *Mod = static_cast<Module*>(CXMod);
5969 return Mod->TopHeaders.size();
5970}
5971
5972CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
5973 if (!CXMod)
5974 return 0;
5975 Module *Mod = static_cast<Module*>(CXMod);
5976
5977 if (Index < Mod->TopHeaders.size())
5978 return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
5979
5980 return 0;
5981}
5982
5983} // end: extern "C"
5984
5985//===----------------------------------------------------------------------===//
5986// C++ AST instrospection.
5987//===----------------------------------------------------------------------===//
5988
5989extern "C" {
5990unsigned clang_CXXMethod_isStatic(CXCursor C) {
5991 if (!clang_isDeclaration(C.kind))
5992 return 0;
5993
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005994 const CXXMethodDecl *Method = 0;
5995 const Decl *D = cxcursor::getCursorDecl(C);
5996 if (const FunctionTemplateDecl *FunTmpl =
5997 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005998 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5999 else
6000 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6001 return (Method && Method->isStatic()) ? 1 : 0;
6002}
6003
6004unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6005 if (!clang_isDeclaration(C.kind))
6006 return 0;
6007
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006008 const CXXMethodDecl *Method = 0;
6009 const Decl *D = cxcursor::getCursorDecl(C);
6010 if (const FunctionTemplateDecl *FunTmpl =
6011 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006012 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6013 else
6014 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6015 return (Method && Method->isVirtual()) ? 1 : 0;
6016}
6017} // end: extern "C"
6018
6019//===----------------------------------------------------------------------===//
6020// Attribute introspection.
6021//===----------------------------------------------------------------------===//
6022
6023extern "C" {
6024CXType clang_getIBOutletCollectionType(CXCursor C) {
6025 if (C.kind != CXCursor_IBOutletCollectionAttr)
6026 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6027
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006028 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006029 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6030
6031 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6032}
6033} // end: extern "C"
6034
6035//===----------------------------------------------------------------------===//
6036// Inspecting memory usage.
6037//===----------------------------------------------------------------------===//
6038
6039typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6040
6041static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6042 enum CXTUResourceUsageKind k,
6043 unsigned long amount) {
6044 CXTUResourceUsageEntry entry = { k, amount };
6045 entries.push_back(entry);
6046}
6047
6048extern "C" {
6049
6050const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6051 const char *str = "";
6052 switch (kind) {
6053 case CXTUResourceUsage_AST:
6054 str = "ASTContext: expressions, declarations, and types";
6055 break;
6056 case CXTUResourceUsage_Identifiers:
6057 str = "ASTContext: identifiers";
6058 break;
6059 case CXTUResourceUsage_Selectors:
6060 str = "ASTContext: selectors";
6061 break;
6062 case CXTUResourceUsage_GlobalCompletionResults:
6063 str = "Code completion: cached global results";
6064 break;
6065 case CXTUResourceUsage_SourceManagerContentCache:
6066 str = "SourceManager: content cache allocator";
6067 break;
6068 case CXTUResourceUsage_AST_SideTables:
6069 str = "ASTContext: side tables";
6070 break;
6071 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6072 str = "SourceManager: malloc'ed memory buffers";
6073 break;
6074 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6075 str = "SourceManager: mmap'ed memory buffers";
6076 break;
6077 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6078 str = "ExternalASTSource: malloc'ed memory buffers";
6079 break;
6080 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6081 str = "ExternalASTSource: mmap'ed memory buffers";
6082 break;
6083 case CXTUResourceUsage_Preprocessor:
6084 str = "Preprocessor: malloc'ed memory";
6085 break;
6086 case CXTUResourceUsage_PreprocessingRecord:
6087 str = "Preprocessor: PreprocessingRecord";
6088 break;
6089 case CXTUResourceUsage_SourceManager_DataStructures:
6090 str = "SourceManager: data structures and tables";
6091 break;
6092 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6093 str = "Preprocessor: header search tables";
6094 break;
6095 }
6096 return str;
6097}
6098
6099CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6100 if (!TU) {
6101 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6102 return usage;
6103 }
6104
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006105 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006106 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6107 ASTContext &astContext = astUnit->getASTContext();
6108
6109 // How much memory is used by AST nodes and types?
6110 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6111 (unsigned long) astContext.getASTAllocatedMemory());
6112
6113 // How much memory is used by identifiers?
6114 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6115 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6116
6117 // How much memory is used for selectors?
6118 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6119 (unsigned long) astContext.Selectors.getTotalMemory());
6120
6121 // How much memory is used by ASTContext's side tables?
6122 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6123 (unsigned long) astContext.getSideTableAllocatedMemory());
6124
6125 // How much memory is used for caching global code completion results?
6126 unsigned long completionBytes = 0;
6127 if (GlobalCodeCompletionAllocator *completionAllocator =
6128 astUnit->getCachedCompletionAllocator().getPtr()) {
6129 completionBytes = completionAllocator->getTotalMemory();
6130 }
6131 createCXTUResourceUsageEntry(*entries,
6132 CXTUResourceUsage_GlobalCompletionResults,
6133 completionBytes);
6134
6135 // How much memory is being used by SourceManager's content cache?
6136 createCXTUResourceUsageEntry(*entries,
6137 CXTUResourceUsage_SourceManagerContentCache,
6138 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6139
6140 // How much memory is being used by the MemoryBuffer's in SourceManager?
6141 const SourceManager::MemoryBufferSizes &srcBufs =
6142 astUnit->getSourceManager().getMemoryBufferSizes();
6143
6144 createCXTUResourceUsageEntry(*entries,
6145 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6146 (unsigned long) srcBufs.malloc_bytes);
6147 createCXTUResourceUsageEntry(*entries,
6148 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6149 (unsigned long) srcBufs.mmap_bytes);
6150 createCXTUResourceUsageEntry(*entries,
6151 CXTUResourceUsage_SourceManager_DataStructures,
6152 (unsigned long) astContext.getSourceManager()
6153 .getDataStructureSizes());
6154
6155 // How much memory is being used by the ExternalASTSource?
6156 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6157 const ExternalASTSource::MemoryBufferSizes &sizes =
6158 esrc->getMemoryBufferSizes();
6159
6160 createCXTUResourceUsageEntry(*entries,
6161 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6162 (unsigned long) sizes.malloc_bytes);
6163 createCXTUResourceUsageEntry(*entries,
6164 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6165 (unsigned long) sizes.mmap_bytes);
6166 }
6167
6168 // How much memory is being used by the Preprocessor?
6169 Preprocessor &pp = astUnit->getPreprocessor();
6170 createCXTUResourceUsageEntry(*entries,
6171 CXTUResourceUsage_Preprocessor,
6172 pp.getTotalMemory());
6173
6174 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6175 createCXTUResourceUsageEntry(*entries,
6176 CXTUResourceUsage_PreprocessingRecord,
6177 pRec->getTotalMemory());
6178 }
6179
6180 createCXTUResourceUsageEntry(*entries,
6181 CXTUResourceUsage_Preprocessor_HeaderSearch,
6182 pp.getHeaderSearchInfo().getTotalMemory());
6183
6184 CXTUResourceUsage usage = { (void*) entries.get(),
6185 (unsigned) entries->size(),
6186 entries->size() ? &(*entries)[0] : 0 };
6187 entries.take();
6188 return usage;
6189}
6190
6191void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6192 if (usage.data)
6193 delete (MemUsageEntries*) usage.data;
6194}
6195
6196} // end extern "C"
6197
6198void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6199 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6200 for (unsigned I = 0; I != Usage.numEntries; ++I)
6201 fprintf(stderr, " %s: %lu\n",
6202 clang_getTUResourceUsageName(Usage.entries[I].kind),
6203 Usage.entries[I].amount);
6204
6205 clang_disposeCXTUResourceUsage(Usage);
6206}
6207
6208//===----------------------------------------------------------------------===//
6209// Misc. utility functions.
6210//===----------------------------------------------------------------------===//
6211
6212/// Default to using an 8 MB stack size on "safety" threads.
6213static unsigned SafetyStackThreadSize = 8 << 20;
6214
6215namespace clang {
6216
6217bool RunSafely(llvm::CrashRecoveryContext &CRC,
6218 void (*Fn)(void*), void *UserData,
6219 unsigned Size) {
6220 if (!Size)
6221 Size = GetSafetyThreadStackSize();
6222 if (Size)
6223 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6224 return CRC.RunSafely(Fn, UserData);
6225}
6226
6227unsigned GetSafetyThreadStackSize() {
6228 return SafetyStackThreadSize;
6229}
6230
6231void SetSafetyThreadStackSize(unsigned Value) {
6232 SafetyStackThreadSize = Value;
6233}
6234
6235}
6236
6237void clang::setThreadBackgroundPriority() {
6238 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6239 return;
6240
6241 // FIXME: Move to llvm/Support and make it cross-platform.
6242#ifdef __APPLE__
6243 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6244#endif
6245}
6246
6247void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6248 if (!Unit)
6249 return;
6250
6251 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6252 DEnd = Unit->stored_diag_end();
6253 D != DEnd; ++D) {
6254 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6255 CXString Msg = clang_formatDiagnostic(&Diag,
6256 clang_defaultDiagnosticDisplayOptions());
6257 fprintf(stderr, "%s\n", clang_getCString(Msg));
6258 clang_disposeString(Msg);
6259 }
6260#ifdef LLVM_ON_WIN32
6261 // On Windows, force a flush, since there may be multiple copies of
6262 // stderr and stdout in the file system, all with different buffers
6263 // but writing to the same device.
6264 fflush(stderr);
6265#endif
6266}
6267
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006268MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6269 SourceLocation MacroDefLoc,
6270 CXTranslationUnit TU){
6271 if (MacroDefLoc.isInvalid() || !TU)
6272 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006273 if (!II.hadMacroDefinition())
6274 return 0;
6275
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006276 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006277 Preprocessor &PP = Unit->getPreprocessor();
Dmitri Gribenkob3958472013-01-14 00:36:42 +00006278 MacroInfo *MI = PP.getMacroInfoHistory(&II);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006279 while (MI) {
6280 if (MacroDefLoc == MI->getDefinitionLoc())
6281 return MI;
6282 MI = MI->getPreviousDefinition();
6283 }
6284
6285 return 0;
6286}
6287
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006288const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6289 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006290 if (!MacroDef || !TU)
6291 return 0;
6292 const IdentifierInfo *II = MacroDef->getName();
6293 if (!II)
6294 return 0;
6295
6296 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6297}
6298
6299MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6300 const Token &Tok,
6301 CXTranslationUnit TU) {
6302 if (!MI || !TU)
6303 return 0;
6304 if (Tok.isNot(tok::raw_identifier))
6305 return 0;
6306
6307 if (MI->getNumTokens() == 0)
6308 return 0;
6309 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6310 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006311 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006312
6313 // Check that the token is inside the definition and not its argument list.
6314 SourceManager &SM = Unit->getSourceManager();
6315 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6316 return 0;
6317 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6318 return 0;
6319
6320 Preprocessor &PP = Unit->getPreprocessor();
6321 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6322 if (!PPRec)
6323 return 0;
6324
6325 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6326 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6327 if (!II.hadMacroDefinition())
6328 return 0;
6329
6330 // Check that the identifier is not one of the macro arguments.
6331 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6332 return 0;
6333
6334 MacroInfo *InnerMI = PP.getMacroInfoHistory(&II);
6335 if (!InnerMI)
6336 return 0;
6337
6338 return PPRec->findMacroDefinition(InnerMI);
6339}
6340
6341MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6342 SourceLocation Loc,
6343 CXTranslationUnit TU) {
6344 if (Loc.isInvalid() || !MI || !TU)
6345 return 0;
6346
6347 if (MI->getNumTokens() == 0)
6348 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006349 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006350 Preprocessor &PP = Unit->getPreprocessor();
6351 if (!PP.getPreprocessingRecord())
6352 return 0;
6353 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6354 Token Tok;
6355 if (PP.getRawToken(Loc, Tok))
6356 return 0;
6357
6358 return checkForMacroInMacroDefinition(MI, Tok, TU);
6359}
6360
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006361extern "C" {
6362
6363CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006364 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006365}
6366
6367} // end: extern "C"
6368
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006369Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6370 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006371 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006372 LogOS << '<' << Unit->getMainFileName() << '>';
6373 return *this;
6374 }
6375 }
6376
6377 LogOS << "<NULL TU>";
6378 return *this;
6379}
6380
6381Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6382 CXFile File;
6383 unsigned Line, Column;
6384 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6385 CXString FileName = clang_getFileName(File);
6386 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6387 clang_disposeString(FileName);
6388 return *this;
6389}
6390
6391Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6392 CXSourceLocation BLoc = clang_getRangeStart(range);
6393 CXSourceLocation ELoc = clang_getRangeEnd(range);
6394
6395 CXFile BFile;
6396 unsigned BLine, BColumn;
6397 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6398
6399 CXFile EFile;
6400 unsigned ELine, EColumn;
6401 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6402
6403 CXString BFileName = clang_getFileName(BFile);
6404 if (BFile == EFile) {
6405 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6406 BLine, BColumn, ELine, EColumn);
6407 } else {
6408 CXString EFileName = clang_getFileName(EFile);
6409 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6410 BLine, BColumn)
6411 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6412 ELine, EColumn);
6413 clang_disposeString(EFileName);
6414 }
6415 clang_disposeString(BFileName);
6416 return *this;
6417}
6418
6419Logger &cxindex::Logger::operator<<(CXString Str) {
6420 *this << clang_getCString(Str);
6421 return *this;
6422}
6423
6424Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6425 LogOS << Fmt;
6426 return *this;
6427}
6428
6429cxindex::Logger::~Logger() {
6430 LogOS.flush();
6431
6432 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6433
6434 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6435
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006436 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006437 OS << "[libclang:" << Name << ':';
6438
6439 // FIXME: Portability.
6440#if HAVE_PTHREAD_H && __APPLE__
6441 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6442 OS << tid << ':';
6443#endif
6444
6445 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6446 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6447 OS << Msg.str() << '\n';
6448
6449 if (Trace) {
6450 llvm::sys::PrintStackTrace(stderr);
6451 OS << "--------------------------------------------------\n";
6452 }
6453}