blob: 3d254a08c6c1fa82d83fbe83c5aabc84e5cffa2a [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;
4961 unsigned BeforeChildrenTokenIdx;
4962 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004963 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004964
4965 bool MoreTokens() const { return TokIdx < NumTokens; }
4966 unsigned NextToken() const { return TokIdx; }
4967 void AdvanceToken() { ++TokIdx; }
4968 SourceLocation GetTokenLoc(unsigned tokI) {
4969 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4970 }
4971 bool isFunctionMacroToken(unsigned tokI) const {
4972 return Tokens[tokI].int_data[3] != 0;
4973 }
4974 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4975 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4976 }
4977
4978 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
4979 void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
4980 SourceRange);
4981
4982public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004983 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004984 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004985 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004986 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004987 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004988 AnnotateTokensVisitor, this,
4989 /*VisitPreprocessorLast=*/true,
4990 /*VisitIncludedEntities=*/false,
4991 RegionOfInterest,
4992 /*VisitDeclsOnly=*/false,
4993 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004994 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004995 HasContextSensitiveKeywords(false) { }
4996
4997 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
4998 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
4999 bool postVisitChildren(CXCursor cursor);
5000 void AnnotateTokens();
5001
5002 /// \brief Determine whether the annotator saw any cursors that have
5003 /// context-sensitive keywords.
5004 bool hasContextSensitiveKeywords() const {
5005 return HasContextSensitiveKeywords;
5006 }
5007
5008 ~AnnotateTokensWorker() {
5009 assert(PostChildrenInfos.empty());
5010 }
5011};
5012}
5013
5014void AnnotateTokensWorker::AnnotateTokens() {
5015 // Walk the AST within the region of interest, annotating tokens
5016 // along the way.
5017 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005018}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005019
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005020static inline void updateCursorAnnotation(CXCursor &Cursor,
5021 const CXCursor &updateC) {
5022 if (clang_isInvalid(updateC.kind) || clang_isPreprocessing(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005023 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005024 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005025}
5026
5027/// \brief It annotates and advances tokens with a cursor until the comparison
5028//// between the cursor location and the source range is the same as
5029/// \arg compResult.
5030///
5031/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5032/// Pass RangeOverlap to annotate tokens inside a range.
5033void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5034 RangeComparisonResult compResult,
5035 SourceRange range) {
5036 while (MoreTokens()) {
5037 const unsigned I = NextToken();
5038 if (isFunctionMacroToken(I))
5039 return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
5040
5041 SourceLocation TokLoc = GetTokenLoc(I);
5042 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005043 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005044 AdvanceToken();
5045 continue;
5046 }
5047 break;
5048 }
5049}
5050
5051/// \brief Special annotation handling for macro argument tokens.
5052void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
5053 CXCursor updateC,
5054 RangeComparisonResult compResult,
5055 SourceRange range) {
5056 assert(MoreTokens());
5057 assert(isFunctionMacroToken(NextToken()) &&
5058 "Should be called only for macro arg tokens");
5059
5060 // This works differently than annotateAndAdvanceTokens; because expanded
5061 // macro arguments can have arbitrary translation-unit source order, we do not
5062 // advance the token index one by one until a token fails the range test.
5063 // We only advance once past all of the macro arg tokens if all of them
5064 // pass the range test. If one of them fails we keep the token index pointing
5065 // at the start of the macro arg tokens so that the failing token will be
5066 // annotated by a subsequent annotation try.
5067
5068 bool atLeastOneCompFail = false;
5069
5070 unsigned I = NextToken();
5071 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5072 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5073 if (TokLoc.isFileID())
5074 continue; // not macro arg token, it's parens or comma.
5075 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5076 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5077 Cursors[I] = updateC;
5078 } else
5079 atLeastOneCompFail = true;
5080 }
5081
5082 if (!atLeastOneCompFail)
5083 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5084}
5085
5086enum CXChildVisitResult
5087AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005088 SourceRange cursorRange = getRawCursorExtent(cursor);
5089 if (cursorRange.isInvalid())
5090 return CXChildVisit_Recurse;
5091
5092 if (!HasContextSensitiveKeywords) {
5093 // Objective-C properties can have context-sensitive keywords.
5094 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005095 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005096 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5097 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5098 }
5099 // Objective-C methods can have context-sensitive keywords.
5100 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5101 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005102 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005103 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5104 if (Method->getObjCDeclQualifier())
5105 HasContextSensitiveKeywords = true;
5106 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005107 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5108 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005109 P != PEnd; ++P) {
5110 if ((*P)->getObjCDeclQualifier()) {
5111 HasContextSensitiveKeywords = true;
5112 break;
5113 }
5114 }
5115 }
5116 }
5117 }
5118 // C++ methods can have context-sensitive keywords.
5119 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005120 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005121 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5122 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5123 HasContextSensitiveKeywords = true;
5124 }
5125 }
5126 // C++ classes can have context-sensitive keywords.
5127 else if (cursor.kind == CXCursor_StructDecl ||
5128 cursor.kind == CXCursor_ClassDecl ||
5129 cursor.kind == CXCursor_ClassTemplate ||
5130 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005131 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005132 if (D->hasAttr<FinalAttr>())
5133 HasContextSensitiveKeywords = true;
5134 }
5135 }
5136
5137 if (clang_isPreprocessing(cursor.kind)) {
5138 // Items in the preprocessing record are kept separate from items in
5139 // declarations, so we keep a separate token index.
5140 unsigned SavedTokIdx = TokIdx;
5141 TokIdx = PreprocessingTokIdx;
5142
5143 // Skip tokens up until we catch up to the beginning of the preprocessing
5144 // entry.
5145 while (MoreTokens()) {
5146 const unsigned I = NextToken();
5147 SourceLocation TokLoc = GetTokenLoc(I);
5148 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5149 case RangeBefore:
5150 AdvanceToken();
5151 continue;
5152 case RangeAfter:
5153 case RangeOverlap:
5154 break;
5155 }
5156 break;
5157 }
5158
5159 // Look at all of the tokens within this range.
5160 while (MoreTokens()) {
5161 const unsigned I = NextToken();
5162 SourceLocation TokLoc = GetTokenLoc(I);
5163 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5164 case RangeBefore:
5165 llvm_unreachable("Infeasible");
5166 case RangeAfter:
5167 break;
5168 case RangeOverlap:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005169 // We may have already annotated macro names inside macro definitions.
5170 if (Cursors[I].kind != CXCursor_MacroExpansion)
5171 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005172 AdvanceToken();
5173 // For macro expansions, just note where the beginning of the macro
5174 // expansion occurs.
5175 if (cursor.kind == CXCursor_MacroExpansion)
5176 break;
5177 continue;
5178 }
5179 break;
5180 }
5181
5182 // Save the preprocessing token index; restore the non-preprocessing
5183 // token index.
5184 PreprocessingTokIdx = TokIdx;
5185 TokIdx = SavedTokIdx;
5186 return CXChildVisit_Recurse;
5187 }
5188
5189 if (cursorRange.isInvalid())
5190 return CXChildVisit_Continue;
5191
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005192 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005193 const enum CXCursorKind K = clang_getCursorKind(parent);
5194 const CXCursor updateC =
5195 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
5196 ? clang_getNullCursor() : parent;
5197
5198 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5199
5200 // Avoid having the cursor of an expression "overwrite" the annotation of the
5201 // variable declaration that it belongs to.
5202 // This can happen for C++ constructor expressions whose range generally
5203 // include the variable declaration, e.g.:
5204 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5205 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005206 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005207 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005208 const unsigned I = NextToken();
5209 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5210 E->getLocStart() == D->getLocation() &&
5211 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005212 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005213 AdvanceToken();
5214 }
5215 }
5216 }
5217
5218 // Before recursing into the children keep some state that we are going
5219 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5220 // extra work after the child nodes are visited.
5221 // Note that we don't call VisitChildren here to avoid traversing statements
5222 // code-recursively which can blow the stack.
5223
5224 PostChildrenInfo Info;
5225 Info.Cursor = cursor;
5226 Info.CursorRange = cursorRange;
5227 Info.BeforeChildrenTokenIdx = NextToken();
5228 PostChildrenInfos.push_back(Info);
5229
5230 return CXChildVisit_Recurse;
5231}
5232
5233bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5234 if (PostChildrenInfos.empty())
5235 return false;
5236 const PostChildrenInfo &Info = PostChildrenInfos.back();
5237 if (!clang_equalCursors(Info.Cursor, cursor))
5238 return false;
5239
5240 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5241 const unsigned AfterChildren = NextToken();
5242 SourceRange cursorRange = Info.CursorRange;
5243
5244 // Scan the tokens that are at the end of the cursor, but are not captured
5245 // but the child cursors.
5246 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5247
5248 // Scan the tokens that are at the beginning of the cursor, but are not
5249 // capture by the child cursors.
5250 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5251 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5252 break;
5253
5254 Cursors[I] = cursor;
5255 }
5256
5257 PostChildrenInfos.pop_back();
5258 return false;
5259}
5260
5261static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5262 CXCursor parent,
5263 CXClientData client_data) {
5264 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5265}
5266
5267static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5268 CXClientData client_data) {
5269 return static_cast<AnnotateTokensWorker*>(client_data)->
5270 postVisitChildren(cursor);
5271}
5272
5273namespace {
5274
5275/// \brief Uses the macro expansions in the preprocessing record to find
5276/// and mark tokens that are macro arguments. This info is used by the
5277/// AnnotateTokensWorker.
5278class MarkMacroArgTokensVisitor {
5279 SourceManager &SM;
5280 CXToken *Tokens;
5281 unsigned NumTokens;
5282 unsigned CurIdx;
5283
5284public:
5285 MarkMacroArgTokensVisitor(SourceManager &SM,
5286 CXToken *tokens, unsigned numTokens)
5287 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5288
5289 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5290 if (cursor.kind != CXCursor_MacroExpansion)
5291 return CXChildVisit_Continue;
5292
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005293 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005294 if (macroRange.getBegin() == macroRange.getEnd())
5295 return CXChildVisit_Continue; // it's not a function macro.
5296
5297 for (; CurIdx < NumTokens; ++CurIdx) {
5298 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5299 macroRange.getBegin()))
5300 break;
5301 }
5302
5303 if (CurIdx == NumTokens)
5304 return CXChildVisit_Break;
5305
5306 for (; CurIdx < NumTokens; ++CurIdx) {
5307 SourceLocation tokLoc = getTokenLoc(CurIdx);
5308 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5309 break;
5310
5311 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5312 }
5313
5314 if (CurIdx == NumTokens)
5315 return CXChildVisit_Break;
5316
5317 return CXChildVisit_Continue;
5318 }
5319
5320private:
5321 SourceLocation getTokenLoc(unsigned tokI) {
5322 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5323 }
5324
5325 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5326 // The third field is reserved and currently not used. Use it here
5327 // to mark macro arg expanded tokens with their expanded locations.
5328 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5329 }
5330};
5331
5332} // end anonymous namespace
5333
5334static CXChildVisitResult
5335MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5336 CXClientData client_data) {
5337 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5338 parent);
5339}
5340
5341namespace {
5342 struct clang_annotateTokens_Data {
5343 CXTranslationUnit TU;
5344 ASTUnit *CXXUnit;
5345 CXToken *Tokens;
5346 unsigned NumTokens;
5347 CXCursor *Cursors;
5348 };
5349}
5350
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005351/// \brief Used by \c annotatePreprocessorTokens.
5352/// \returns true if lexing was finished, false otherwise.
5353static bool lexNext(Lexer &Lex, Token &Tok,
5354 unsigned &NextIdx, unsigned NumTokens) {
5355 if (NextIdx >= NumTokens)
5356 return true;
5357
5358 ++NextIdx;
5359 Lex.LexFromRawLexer(Tok);
5360 if (Tok.is(tok::eof))
5361 return true;
5362
5363 return false;
5364}
5365
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005366static void annotatePreprocessorTokens(CXTranslationUnit TU,
5367 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005368 CXCursor *Cursors,
5369 CXToken *Tokens,
5370 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005371 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005372
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005373 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005374 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5375 std::pair<FileID, unsigned> BeginLocInfo
5376 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
5377 std::pair<FileID, unsigned> EndLocInfo
5378 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
5379
5380 if (BeginLocInfo.first != EndLocInfo.first)
5381 return;
5382
5383 StringRef Buffer;
5384 bool Invalid = false;
5385 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5386 if (Buffer.empty() || Invalid)
5387 return;
5388
5389 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5390 CXXUnit->getASTContext().getLangOpts(),
5391 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5392 Buffer.end());
5393 Lex.SetCommentRetentionState(true);
5394
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005395 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005396 // Lex tokens in raw mode until we hit the end of the range, to avoid
5397 // entering #includes or expanding macros.
5398 while (true) {
5399 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005400 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5401 break;
5402 unsigned TokIdx = NextIdx-1;
5403 assert(Tok.getLocation() ==
5404 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005405
5406 reprocess:
5407 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005408 // We have found a preprocessing directive. Annotate the tokens
5409 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005410 //
5411 // FIXME: Some simple tests here could identify macro definitions and
5412 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005413
5414 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005415 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5416 break;
5417
5418 MacroInfo *MI = 0;
5419 if (Tok.is(tok::raw_identifier) &&
5420 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5421 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5422 break;
5423
5424 if (Tok.is(tok::raw_identifier)) {
5425 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5426 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5427 SourceLocation MappedTokLoc =
5428 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5429 MI = getMacroInfo(II, MappedTokLoc, TU);
5430 }
5431 }
5432
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005433 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005434 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005435 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5436 finished = true;
5437 break;
5438 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005439 // If we are in a macro definition, check if the token was ever a
5440 // macro name and annotate it if that's the case.
5441 if (MI) {
5442 SourceLocation SaveLoc = Tok.getLocation();
5443 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5444 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5445 Tok.setLocation(SaveLoc);
5446 if (MacroDef)
5447 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5448 Tok.getLocation(), TU);
5449 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005450 } while (!Tok.isAtStartOfLine());
5451
5452 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5453 assert(TokIdx <= LastIdx);
5454 SourceLocation EndLoc =
5455 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5456 CXCursor Cursor =
5457 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5458
5459 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005460 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005461
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005462 if (finished)
5463 break;
5464 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005465 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005466 }
5467}
5468
5469// This gets run a separate thread to avoid stack blowout.
5470static void clang_annotateTokensImpl(void *UserData) {
5471 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5472 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5473 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5474 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5475 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5476
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005477 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005478 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5479 setThreadBackgroundPriority();
5480
5481 // Determine the region of interest, which contains all of the tokens.
5482 SourceRange RegionOfInterest;
5483 RegionOfInterest.setBegin(
5484 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5485 RegionOfInterest.setEnd(
5486 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5487 Tokens[NumTokens-1])));
5488
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005489 // Relex the tokens within the source range to look for preprocessing
5490 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005491 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005492
5493 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5494 // Search and mark tokens that are macro argument expansions.
5495 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5496 Tokens, NumTokens);
5497 CursorVisitor MacroArgMarker(TU,
5498 MarkMacroArgTokensVisitorDelegate, &Visitor,
5499 /*VisitPreprocessorLast=*/true,
5500 /*VisitIncludedEntities=*/false,
5501 RegionOfInterest);
5502 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5503 }
5504
5505 // Annotate all of the source locations in the region of interest that map to
5506 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005507 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005508
5509 // FIXME: We use a ridiculous stack size here because the data-recursion
5510 // algorithm uses a large stack frame than the non-data recursive version,
5511 // and AnnotationTokensWorker currently transforms the data-recursion
5512 // algorithm back into a traditional recursion by explicitly calling
5513 // VisitChildren(). We will need to remove this explicit recursive call.
5514 W.AnnotateTokens();
5515
5516 // If we ran into any entities that involve context-sensitive keywords,
5517 // take another pass through the tokens to mark them as such.
5518 if (W.hasContextSensitiveKeywords()) {
5519 for (unsigned I = 0; I != NumTokens; ++I) {
5520 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5521 continue;
5522
5523 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5524 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005525 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005526 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5527 if (Property->getPropertyAttributesAsWritten() != 0 &&
5528 llvm::StringSwitch<bool>(II->getName())
5529 .Case("readonly", true)
5530 .Case("assign", true)
5531 .Case("unsafe_unretained", true)
5532 .Case("readwrite", true)
5533 .Case("retain", true)
5534 .Case("copy", true)
5535 .Case("nonatomic", true)
5536 .Case("atomic", true)
5537 .Case("getter", true)
5538 .Case("setter", true)
5539 .Case("strong", true)
5540 .Case("weak", true)
5541 .Default(false))
5542 Tokens[I].int_data[0] = CXToken_Keyword;
5543 }
5544 continue;
5545 }
5546
5547 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5548 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5549 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5550 if (llvm::StringSwitch<bool>(II->getName())
5551 .Case("in", true)
5552 .Case("out", true)
5553 .Case("inout", true)
5554 .Case("oneway", true)
5555 .Case("bycopy", true)
5556 .Case("byref", true)
5557 .Default(false))
5558 Tokens[I].int_data[0] = CXToken_Keyword;
5559 continue;
5560 }
5561
5562 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5563 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5564 Tokens[I].int_data[0] = CXToken_Keyword;
5565 continue;
5566 }
5567 }
5568 }
5569}
5570
5571extern "C" {
5572
5573void clang_annotateTokens(CXTranslationUnit TU,
5574 CXToken *Tokens, unsigned NumTokens,
5575 CXCursor *Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005576 if (NumTokens == 0 || !Tokens || !Cursors) {
5577 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005578 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005579 }
5580
5581 LOG_FUNC_SECTION {
5582 *Log << TU << ' ';
5583 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5584 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5585 *Log << clang_getRange(bloc, eloc);
5586 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005587
5588 // Any token we don't specifically annotate will have a NULL cursor.
5589 CXCursor C = clang_getNullCursor();
5590 for (unsigned I = 0; I != NumTokens; ++I)
5591 Cursors[I] = C;
5592
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005593 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005594 if (!CXXUnit)
5595 return;
5596
5597 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5598
5599 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5600 llvm::CrashRecoveryContext CRC;
5601 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5602 GetSafetyThreadStackSize() * 2)) {
5603 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5604 }
5605}
5606
5607} // end: extern "C"
5608
5609//===----------------------------------------------------------------------===//
5610// Operations for querying linkage of a cursor.
5611//===----------------------------------------------------------------------===//
5612
5613extern "C" {
5614CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5615 if (!clang_isDeclaration(cursor.kind))
5616 return CXLinkage_Invalid;
5617
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005618 const Decl *D = cxcursor::getCursorDecl(cursor);
5619 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005620 switch (ND->getLinkage()) {
5621 case NoLinkage: return CXLinkage_NoLinkage;
5622 case InternalLinkage: return CXLinkage_Internal;
5623 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5624 case ExternalLinkage: return CXLinkage_External;
5625 };
5626
5627 return CXLinkage_Invalid;
5628}
5629} // end: extern "C"
5630
5631//===----------------------------------------------------------------------===//
5632// Operations for querying language of a cursor.
5633//===----------------------------------------------------------------------===//
5634
5635static CXLanguageKind getDeclLanguage(const Decl *D) {
5636 if (!D)
5637 return CXLanguage_C;
5638
5639 switch (D->getKind()) {
5640 default:
5641 break;
5642 case Decl::ImplicitParam:
5643 case Decl::ObjCAtDefsField:
5644 case Decl::ObjCCategory:
5645 case Decl::ObjCCategoryImpl:
5646 case Decl::ObjCCompatibleAlias:
5647 case Decl::ObjCImplementation:
5648 case Decl::ObjCInterface:
5649 case Decl::ObjCIvar:
5650 case Decl::ObjCMethod:
5651 case Decl::ObjCProperty:
5652 case Decl::ObjCPropertyImpl:
5653 case Decl::ObjCProtocol:
5654 return CXLanguage_ObjC;
5655 case Decl::CXXConstructor:
5656 case Decl::CXXConversion:
5657 case Decl::CXXDestructor:
5658 case Decl::CXXMethod:
5659 case Decl::CXXRecord:
5660 case Decl::ClassTemplate:
5661 case Decl::ClassTemplatePartialSpecialization:
5662 case Decl::ClassTemplateSpecialization:
5663 case Decl::Friend:
5664 case Decl::FriendTemplate:
5665 case Decl::FunctionTemplate:
5666 case Decl::LinkageSpec:
5667 case Decl::Namespace:
5668 case Decl::NamespaceAlias:
5669 case Decl::NonTypeTemplateParm:
5670 case Decl::StaticAssert:
5671 case Decl::TemplateTemplateParm:
5672 case Decl::TemplateTypeParm:
5673 case Decl::UnresolvedUsingTypename:
5674 case Decl::UnresolvedUsingValue:
5675 case Decl::Using:
5676 case Decl::UsingDirective:
5677 case Decl::UsingShadow:
5678 return CXLanguage_CPlusPlus;
5679 }
5680
5681 return CXLanguage_C;
5682}
5683
5684extern "C" {
5685
5686enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5687 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005688 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005689 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5690 return CXAvailability_Available;
5691
5692 switch (D->getAvailability()) {
5693 case AR_Available:
5694 case AR_NotYetIntroduced:
5695 return CXAvailability_Available;
5696
5697 case AR_Deprecated:
5698 return CXAvailability_Deprecated;
5699
5700 case AR_Unavailable:
5701 return CXAvailability_NotAvailable;
5702 }
5703 }
5704
5705 return CXAvailability_Available;
5706}
5707
5708static CXVersion convertVersion(VersionTuple In) {
5709 CXVersion Out = { -1, -1, -1 };
5710 if (In.empty())
5711 return Out;
5712
5713 Out.Major = In.getMajor();
5714
5715 if (llvm::Optional<unsigned> Minor = In.getMinor())
5716 Out.Minor = *Minor;
5717 else
5718 return Out;
5719
5720 if (llvm::Optional<unsigned> Subminor = In.getSubminor())
5721 Out.Subminor = *Subminor;
5722
5723 return Out;
5724}
5725
5726int clang_getCursorPlatformAvailability(CXCursor cursor,
5727 int *always_deprecated,
5728 CXString *deprecated_message,
5729 int *always_unavailable,
5730 CXString *unavailable_message,
5731 CXPlatformAvailability *availability,
5732 int availability_size) {
5733 if (always_deprecated)
5734 *always_deprecated = 0;
5735 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005736 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005737 if (always_unavailable)
5738 *always_unavailable = 0;
5739 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005740 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005741
5742 if (!clang_isDeclaration(cursor.kind))
5743 return 0;
5744
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005745 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005746 if (!D)
5747 return 0;
5748
5749 int N = 0;
5750 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5751 ++A) {
5752 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5753 if (always_deprecated)
5754 *always_deprecated = 1;
5755 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005756 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005757 continue;
5758 }
5759
5760 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5761 if (always_unavailable)
5762 *always_unavailable = 1;
5763 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005764 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005765 }
5766 continue;
5767 }
5768
5769 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5770 if (N < availability_size) {
5771 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005772 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005773 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5774 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5775 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5776 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005777 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005778 }
5779 ++N;
5780 }
5781 }
5782
5783 return N;
5784}
5785
5786void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5787 clang_disposeString(availability->Platform);
5788 clang_disposeString(availability->Message);
5789}
5790
5791CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5792 if (clang_isDeclaration(cursor.kind))
5793 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5794
5795 return CXLanguage_Invalid;
5796}
5797
5798 /// \brief If the given cursor is the "templated" declaration
5799 /// descibing a class or function template, return the class or
5800 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005801static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005802 if (!D)
5803 return 0;
5804
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005805 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005806 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5807 return FunTmpl;
5808
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005809 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005810 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5811 return ClassTmpl;
5812
5813 return D;
5814}
5815
5816CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5817 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005818 if (const Decl *D = getCursorDecl(cursor)) {
5819 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005820 if (!DC)
5821 return clang_getNullCursor();
5822
5823 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5824 getCursorTU(cursor));
5825 }
5826 }
5827
5828 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005829 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005830 return MakeCXCursor(D, getCursorTU(cursor));
5831 }
5832
5833 return clang_getNullCursor();
5834}
5835
5836CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5837 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005838 if (const Decl *D = getCursorDecl(cursor)) {
5839 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005840 if (!DC)
5841 return clang_getNullCursor();
5842
5843 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5844 getCursorTU(cursor));
5845 }
5846 }
5847
5848 // FIXME: Note that we can't easily compute the lexical context of a
5849 // statement or expression, so we return nothing.
5850 return clang_getNullCursor();
5851}
5852
5853CXFile clang_getIncludedFile(CXCursor cursor) {
5854 if (cursor.kind != CXCursor_InclusionDirective)
5855 return 0;
5856
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005857 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005858 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005859}
5860
5861CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5862 if (!clang_isDeclaration(C.kind))
5863 return clang_getNullRange();
5864
5865 const Decl *D = getCursorDecl(C);
5866 ASTContext &Context = getCursorContext(C);
5867 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5868 if (!RC)
5869 return clang_getNullRange();
5870
5871 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5872}
5873
5874CXString clang_Cursor_getRawCommentText(CXCursor C) {
5875 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005876 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005877
5878 const Decl *D = getCursorDecl(C);
5879 ASTContext &Context = getCursorContext(C);
5880 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5881 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5882 StringRef();
5883
5884 // Don't duplicate the string because RawText points directly into source
5885 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005886 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005887}
5888
5889CXString clang_Cursor_getBriefCommentText(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 const ASTContext &Context = getCursorContext(C);
5895 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5896
5897 if (RC) {
5898 StringRef BriefText = RC->getBriefText(Context);
5899
5900 // Don't duplicate the string because RawComment ensures that this memory
5901 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005902 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005903 }
5904
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005905 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005906}
5907
5908CXComment clang_Cursor_getParsedComment(CXCursor C) {
5909 if (!clang_isDeclaration(C.kind))
5910 return cxcomment::createCXComment(NULL, NULL);
5911
5912 const Decl *D = getCursorDecl(C);
5913 const ASTContext &Context = getCursorContext(C);
5914 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5915
5916 return cxcomment::createCXComment(FC, getCursorTU(C));
5917}
5918
5919CXModule clang_Cursor_getModule(CXCursor C) {
5920 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005921 if (const ImportDecl *ImportD =
5922 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005923 return ImportD->getImportedModule();
5924 }
5925
5926 return 0;
5927}
5928
5929CXModule clang_Module_getParent(CXModule CXMod) {
5930 if (!CXMod)
5931 return 0;
5932 Module *Mod = static_cast<Module*>(CXMod);
5933 return Mod->Parent;
5934}
5935
5936CXString clang_Module_getName(CXModule CXMod) {
5937 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005938 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005939 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005940 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005941}
5942
5943CXString clang_Module_getFullName(CXModule CXMod) {
5944 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005945 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005946 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005947 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005948}
5949
5950unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
5951 if (!CXMod)
5952 return 0;
5953 Module *Mod = static_cast<Module*>(CXMod);
5954 return Mod->TopHeaders.size();
5955}
5956
5957CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
5958 if (!CXMod)
5959 return 0;
5960 Module *Mod = static_cast<Module*>(CXMod);
5961
5962 if (Index < Mod->TopHeaders.size())
5963 return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
5964
5965 return 0;
5966}
5967
5968} // end: extern "C"
5969
5970//===----------------------------------------------------------------------===//
5971// C++ AST instrospection.
5972//===----------------------------------------------------------------------===//
5973
5974extern "C" {
5975unsigned clang_CXXMethod_isStatic(CXCursor C) {
5976 if (!clang_isDeclaration(C.kind))
5977 return 0;
5978
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005979 const CXXMethodDecl *Method = 0;
5980 const Decl *D = cxcursor::getCursorDecl(C);
5981 if (const FunctionTemplateDecl *FunTmpl =
5982 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005983 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5984 else
5985 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5986 return (Method && Method->isStatic()) ? 1 : 0;
5987}
5988
5989unsigned clang_CXXMethod_isVirtual(CXCursor C) {
5990 if (!clang_isDeclaration(C.kind))
5991 return 0;
5992
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005993 const CXXMethodDecl *Method = 0;
5994 const Decl *D = cxcursor::getCursorDecl(C);
5995 if (const FunctionTemplateDecl *FunTmpl =
5996 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005997 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5998 else
5999 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6000 return (Method && Method->isVirtual()) ? 1 : 0;
6001}
6002} // end: extern "C"
6003
6004//===----------------------------------------------------------------------===//
6005// Attribute introspection.
6006//===----------------------------------------------------------------------===//
6007
6008extern "C" {
6009CXType clang_getIBOutletCollectionType(CXCursor C) {
6010 if (C.kind != CXCursor_IBOutletCollectionAttr)
6011 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6012
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006013 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006014 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6015
6016 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6017}
6018} // end: extern "C"
6019
6020//===----------------------------------------------------------------------===//
6021// Inspecting memory usage.
6022//===----------------------------------------------------------------------===//
6023
6024typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6025
6026static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6027 enum CXTUResourceUsageKind k,
6028 unsigned long amount) {
6029 CXTUResourceUsageEntry entry = { k, amount };
6030 entries.push_back(entry);
6031}
6032
6033extern "C" {
6034
6035const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6036 const char *str = "";
6037 switch (kind) {
6038 case CXTUResourceUsage_AST:
6039 str = "ASTContext: expressions, declarations, and types";
6040 break;
6041 case CXTUResourceUsage_Identifiers:
6042 str = "ASTContext: identifiers";
6043 break;
6044 case CXTUResourceUsage_Selectors:
6045 str = "ASTContext: selectors";
6046 break;
6047 case CXTUResourceUsage_GlobalCompletionResults:
6048 str = "Code completion: cached global results";
6049 break;
6050 case CXTUResourceUsage_SourceManagerContentCache:
6051 str = "SourceManager: content cache allocator";
6052 break;
6053 case CXTUResourceUsage_AST_SideTables:
6054 str = "ASTContext: side tables";
6055 break;
6056 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6057 str = "SourceManager: malloc'ed memory buffers";
6058 break;
6059 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6060 str = "SourceManager: mmap'ed memory buffers";
6061 break;
6062 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6063 str = "ExternalASTSource: malloc'ed memory buffers";
6064 break;
6065 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6066 str = "ExternalASTSource: mmap'ed memory buffers";
6067 break;
6068 case CXTUResourceUsage_Preprocessor:
6069 str = "Preprocessor: malloc'ed memory";
6070 break;
6071 case CXTUResourceUsage_PreprocessingRecord:
6072 str = "Preprocessor: PreprocessingRecord";
6073 break;
6074 case CXTUResourceUsage_SourceManager_DataStructures:
6075 str = "SourceManager: data structures and tables";
6076 break;
6077 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6078 str = "Preprocessor: header search tables";
6079 break;
6080 }
6081 return str;
6082}
6083
6084CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6085 if (!TU) {
6086 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6087 return usage;
6088 }
6089
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006090 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006091 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6092 ASTContext &astContext = astUnit->getASTContext();
6093
6094 // How much memory is used by AST nodes and types?
6095 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6096 (unsigned long) astContext.getASTAllocatedMemory());
6097
6098 // How much memory is used by identifiers?
6099 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6100 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6101
6102 // How much memory is used for selectors?
6103 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6104 (unsigned long) astContext.Selectors.getTotalMemory());
6105
6106 // How much memory is used by ASTContext's side tables?
6107 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6108 (unsigned long) astContext.getSideTableAllocatedMemory());
6109
6110 // How much memory is used for caching global code completion results?
6111 unsigned long completionBytes = 0;
6112 if (GlobalCodeCompletionAllocator *completionAllocator =
6113 astUnit->getCachedCompletionAllocator().getPtr()) {
6114 completionBytes = completionAllocator->getTotalMemory();
6115 }
6116 createCXTUResourceUsageEntry(*entries,
6117 CXTUResourceUsage_GlobalCompletionResults,
6118 completionBytes);
6119
6120 // How much memory is being used by SourceManager's content cache?
6121 createCXTUResourceUsageEntry(*entries,
6122 CXTUResourceUsage_SourceManagerContentCache,
6123 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6124
6125 // How much memory is being used by the MemoryBuffer's in SourceManager?
6126 const SourceManager::MemoryBufferSizes &srcBufs =
6127 astUnit->getSourceManager().getMemoryBufferSizes();
6128
6129 createCXTUResourceUsageEntry(*entries,
6130 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6131 (unsigned long) srcBufs.malloc_bytes);
6132 createCXTUResourceUsageEntry(*entries,
6133 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6134 (unsigned long) srcBufs.mmap_bytes);
6135 createCXTUResourceUsageEntry(*entries,
6136 CXTUResourceUsage_SourceManager_DataStructures,
6137 (unsigned long) astContext.getSourceManager()
6138 .getDataStructureSizes());
6139
6140 // How much memory is being used by the ExternalASTSource?
6141 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6142 const ExternalASTSource::MemoryBufferSizes &sizes =
6143 esrc->getMemoryBufferSizes();
6144
6145 createCXTUResourceUsageEntry(*entries,
6146 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6147 (unsigned long) sizes.malloc_bytes);
6148 createCXTUResourceUsageEntry(*entries,
6149 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6150 (unsigned long) sizes.mmap_bytes);
6151 }
6152
6153 // How much memory is being used by the Preprocessor?
6154 Preprocessor &pp = astUnit->getPreprocessor();
6155 createCXTUResourceUsageEntry(*entries,
6156 CXTUResourceUsage_Preprocessor,
6157 pp.getTotalMemory());
6158
6159 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6160 createCXTUResourceUsageEntry(*entries,
6161 CXTUResourceUsage_PreprocessingRecord,
6162 pRec->getTotalMemory());
6163 }
6164
6165 createCXTUResourceUsageEntry(*entries,
6166 CXTUResourceUsage_Preprocessor_HeaderSearch,
6167 pp.getHeaderSearchInfo().getTotalMemory());
6168
6169 CXTUResourceUsage usage = { (void*) entries.get(),
6170 (unsigned) entries->size(),
6171 entries->size() ? &(*entries)[0] : 0 };
6172 entries.take();
6173 return usage;
6174}
6175
6176void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6177 if (usage.data)
6178 delete (MemUsageEntries*) usage.data;
6179}
6180
6181} // end extern "C"
6182
6183void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6184 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6185 for (unsigned I = 0; I != Usage.numEntries; ++I)
6186 fprintf(stderr, " %s: %lu\n",
6187 clang_getTUResourceUsageName(Usage.entries[I].kind),
6188 Usage.entries[I].amount);
6189
6190 clang_disposeCXTUResourceUsage(Usage);
6191}
6192
6193//===----------------------------------------------------------------------===//
6194// Misc. utility functions.
6195//===----------------------------------------------------------------------===//
6196
6197/// Default to using an 8 MB stack size on "safety" threads.
6198static unsigned SafetyStackThreadSize = 8 << 20;
6199
6200namespace clang {
6201
6202bool RunSafely(llvm::CrashRecoveryContext &CRC,
6203 void (*Fn)(void*), void *UserData,
6204 unsigned Size) {
6205 if (!Size)
6206 Size = GetSafetyThreadStackSize();
6207 if (Size)
6208 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6209 return CRC.RunSafely(Fn, UserData);
6210}
6211
6212unsigned GetSafetyThreadStackSize() {
6213 return SafetyStackThreadSize;
6214}
6215
6216void SetSafetyThreadStackSize(unsigned Value) {
6217 SafetyStackThreadSize = Value;
6218}
6219
6220}
6221
6222void clang::setThreadBackgroundPriority() {
6223 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6224 return;
6225
6226 // FIXME: Move to llvm/Support and make it cross-platform.
6227#ifdef __APPLE__
6228 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6229#endif
6230}
6231
6232void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6233 if (!Unit)
6234 return;
6235
6236 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6237 DEnd = Unit->stored_diag_end();
6238 D != DEnd; ++D) {
6239 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6240 CXString Msg = clang_formatDiagnostic(&Diag,
6241 clang_defaultDiagnosticDisplayOptions());
6242 fprintf(stderr, "%s\n", clang_getCString(Msg));
6243 clang_disposeString(Msg);
6244 }
6245#ifdef LLVM_ON_WIN32
6246 // On Windows, force a flush, since there may be multiple copies of
6247 // stderr and stdout in the file system, all with different buffers
6248 // but writing to the same device.
6249 fflush(stderr);
6250#endif
6251}
6252
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006253MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6254 SourceLocation MacroDefLoc,
6255 CXTranslationUnit TU){
6256 if (MacroDefLoc.isInvalid() || !TU)
6257 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006258 if (!II.hadMacroDefinition())
6259 return 0;
6260
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006261 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006262 Preprocessor &PP = Unit->getPreprocessor();
Dmitri Gribenkob3958472013-01-14 00:36:42 +00006263 MacroInfo *MI = PP.getMacroInfoHistory(&II);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006264 while (MI) {
6265 if (MacroDefLoc == MI->getDefinitionLoc())
6266 return MI;
6267 MI = MI->getPreviousDefinition();
6268 }
6269
6270 return 0;
6271}
6272
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006273const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6274 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006275 if (!MacroDef || !TU)
6276 return 0;
6277 const IdentifierInfo *II = MacroDef->getName();
6278 if (!II)
6279 return 0;
6280
6281 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6282}
6283
6284MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6285 const Token &Tok,
6286 CXTranslationUnit TU) {
6287 if (!MI || !TU)
6288 return 0;
6289 if (Tok.isNot(tok::raw_identifier))
6290 return 0;
6291
6292 if (MI->getNumTokens() == 0)
6293 return 0;
6294 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6295 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006296 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006297
6298 // Check that the token is inside the definition and not its argument list.
6299 SourceManager &SM = Unit->getSourceManager();
6300 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6301 return 0;
6302 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6303 return 0;
6304
6305 Preprocessor &PP = Unit->getPreprocessor();
6306 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6307 if (!PPRec)
6308 return 0;
6309
6310 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6311 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6312 if (!II.hadMacroDefinition())
6313 return 0;
6314
6315 // Check that the identifier is not one of the macro arguments.
6316 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6317 return 0;
6318
6319 MacroInfo *InnerMI = PP.getMacroInfoHistory(&II);
6320 if (!InnerMI)
6321 return 0;
6322
6323 return PPRec->findMacroDefinition(InnerMI);
6324}
6325
6326MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6327 SourceLocation Loc,
6328 CXTranslationUnit TU) {
6329 if (Loc.isInvalid() || !MI || !TU)
6330 return 0;
6331
6332 if (MI->getNumTokens() == 0)
6333 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006334 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006335 Preprocessor &PP = Unit->getPreprocessor();
6336 if (!PP.getPreprocessingRecord())
6337 return 0;
6338 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6339 Token Tok;
6340 if (PP.getRawToken(Loc, Tok))
6341 return 0;
6342
6343 return checkForMacroInMacroDefinition(MI, Tok, TU);
6344}
6345
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006346extern "C" {
6347
6348CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006349 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006350}
6351
6352} // end: extern "C"
6353
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006354Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6355 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006356 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006357 LogOS << '<' << Unit->getMainFileName() << '>';
6358 return *this;
6359 }
6360 }
6361
6362 LogOS << "<NULL TU>";
6363 return *this;
6364}
6365
6366Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6367 CXFile File;
6368 unsigned Line, Column;
6369 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6370 CXString FileName = clang_getFileName(File);
6371 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6372 clang_disposeString(FileName);
6373 return *this;
6374}
6375
6376Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6377 CXSourceLocation BLoc = clang_getRangeStart(range);
6378 CXSourceLocation ELoc = clang_getRangeEnd(range);
6379
6380 CXFile BFile;
6381 unsigned BLine, BColumn;
6382 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6383
6384 CXFile EFile;
6385 unsigned ELine, EColumn;
6386 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6387
6388 CXString BFileName = clang_getFileName(BFile);
6389 if (BFile == EFile) {
6390 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6391 BLine, BColumn, ELine, EColumn);
6392 } else {
6393 CXString EFileName = clang_getFileName(EFile);
6394 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6395 BLine, BColumn)
6396 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6397 ELine, EColumn);
6398 clang_disposeString(EFileName);
6399 }
6400 clang_disposeString(BFileName);
6401 return *this;
6402}
6403
6404Logger &cxindex::Logger::operator<<(CXString Str) {
6405 *this << clang_getCString(Str);
6406 return *this;
6407}
6408
6409Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6410 LogOS << Fmt;
6411 return *this;
6412}
6413
6414cxindex::Logger::~Logger() {
6415 LogOS.flush();
6416
6417 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6418
6419 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6420
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006421 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006422 OS << "[libclang:" << Name << ':';
6423
6424 // FIXME: Portability.
6425#if HAVE_PTHREAD_H && __APPLE__
6426 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6427 OS << tid << ':';
6428#endif
6429
6430 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6431 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6432 OS << Msg.str() << '\n';
6433
6434 if (Trace) {
6435 llvm::sys::PrintStackTrace(stderr);
6436 OS << "--------------------------------------------------\n";
6437 }
6438}