blob: 992451346b745e657da84a29ccf5143597611449 [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:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001401 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001402#define BUILTIN_TYPE(Id, SingletonId)
1403#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1404#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1405#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1406#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1407#include "clang/AST/BuiltinTypes.def"
1408 break;
1409
1410 case BuiltinType::ObjCId:
1411 VisitType = Context.getObjCIdType();
1412 break;
1413
1414 case BuiltinType::ObjCClass:
1415 VisitType = Context.getObjCClassType();
1416 break;
1417
1418 case BuiltinType::ObjCSel:
1419 VisitType = Context.getObjCSelType();
1420 break;
1421 }
1422
1423 if (!VisitType.isNull()) {
1424 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1425 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1426 TU));
1427 }
1428
1429 return false;
1430}
1431
1432bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1433 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1434}
1435
1436bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1437 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1438}
1439
1440bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1441 if (TL.isDefinition())
1442 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1443
1444 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1445}
1446
1447bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1448 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1449}
1450
1451bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1452 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1453 return true;
1454
1455 return false;
1456}
1457
1458bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1459 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1460 return true;
1461
1462 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1463 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1464 TU)))
1465 return true;
1466 }
1467
1468 return false;
1469}
1470
1471bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1472 return Visit(TL.getPointeeLoc());
1473}
1474
1475bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1476 return Visit(TL.getInnerLoc());
1477}
1478
1479bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1480 return Visit(TL.getPointeeLoc());
1481}
1482
1483bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1484 return Visit(TL.getPointeeLoc());
1485}
1486
1487bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1500 return Visit(TL.getModifiedLoc());
1501}
1502
1503bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1504 bool SkipResultType) {
1505 if (!SkipResultType && Visit(TL.getResultLoc()))
1506 return true;
1507
1508 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1509 if (Decl *D = TL.getArg(I))
1510 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1511 return true;
1512
1513 return false;
1514}
1515
1516bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1517 if (Visit(TL.getElementLoc()))
1518 return true;
1519
1520 if (Expr *Size = TL.getSizeExpr())
1521 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1522
1523 return false;
1524}
1525
1526bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1527 TemplateSpecializationTypeLoc TL) {
1528 // Visit the template name.
1529 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1530 TL.getTemplateNameLoc()))
1531 return true;
1532
1533 // Visit the template arguments.
1534 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1535 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1536 return true;
1537
1538 return false;
1539}
1540
1541bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1542 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1543}
1544
1545bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1546 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1547 return Visit(TSInfo->getTypeLoc());
1548
1549 return false;
1550}
1551
1552bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1553 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1554 return Visit(TSInfo->getTypeLoc());
1555
1556 return false;
1557}
1558
1559bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1560 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1561 return true;
1562
1563 return false;
1564}
1565
1566bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1567 DependentTemplateSpecializationTypeLoc TL) {
1568 // Visit the nested-name-specifier, if there is one.
1569 if (TL.getQualifierLoc() &&
1570 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1571 return true;
1572
1573 // Visit the template arguments.
1574 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1575 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1576 return true;
1577
1578 return false;
1579}
1580
1581bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1582 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1583 return true;
1584
1585 return Visit(TL.getNamedTypeLoc());
1586}
1587
1588bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1589 return Visit(TL.getPatternLoc());
1590}
1591
1592bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1593 if (Expr *E = TL.getUnderlyingExpr())
1594 return Visit(MakeCXCursor(E, StmtParent, TU));
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1600 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1601}
1602
1603bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1604 return Visit(TL.getValueLoc());
1605}
1606
1607#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1608bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1609 return Visit##PARENT##Loc(TL); \
1610}
1611
1612DEFAULT_TYPELOC_IMPL(Complex, Type)
1613DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1614DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1615DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1616DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1617DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1618DEFAULT_TYPELOC_IMPL(Vector, Type)
1619DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1620DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1621DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1622DEFAULT_TYPELOC_IMPL(Record, TagType)
1623DEFAULT_TYPELOC_IMPL(Enum, TagType)
1624DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1625DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1626DEFAULT_TYPELOC_IMPL(Auto, Type)
1627
1628bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1629 // Visit the nested-name-specifier, if present.
1630 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1631 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1632 return true;
1633
1634 if (D->isCompleteDefinition()) {
1635 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1636 E = D->bases_end(); I != E; ++I) {
1637 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1638 return true;
1639 }
1640 }
1641
1642 return VisitTagDecl(D);
1643}
1644
1645bool CursorVisitor::VisitAttributes(Decl *D) {
1646 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1647 i != e; ++i)
1648 if (Visit(MakeCXCursor(*i, D, TU)))
1649 return true;
1650
1651 return false;
1652}
1653
1654//===----------------------------------------------------------------------===//
1655// Data-recursive visitor methods.
1656//===----------------------------------------------------------------------===//
1657
1658namespace {
1659#define DEF_JOB(NAME, DATA, KIND)\
1660class NAME : public VisitorJob {\
1661public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001662 NAME(const DATA *d, CXCursor parent) : \
1663 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001664 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001665 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001666};
1667
1668DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1669DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1670DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1671DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1672DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1673 ExplicitTemplateArgsVisitKind)
1674DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1675DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1676DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1677#undef DEF_JOB
1678
1679class DeclVisit : public VisitorJob {
1680public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001681 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001682 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001683 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001684 static bool classof(const VisitorJob *VJ) {
1685 return VJ->getKind() == DeclVisitKind;
1686 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001687 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001688 bool isFirst() const { return data[1] ? true : false; }
1689};
1690class TypeLocVisit : public VisitorJob {
1691public:
1692 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1693 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1694 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1695
1696 static bool classof(const VisitorJob *VJ) {
1697 return VJ->getKind() == TypeLocVisitKind;
1698 }
1699
1700 TypeLoc get() const {
1701 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001702 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001703 }
1704};
1705
1706class LabelRefVisit : public VisitorJob {
1707public:
1708 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1709 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1710 labelLoc.getPtrEncoding()) {}
1711
1712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1714 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001715 const LabelDecl *get() const {
1716 return static_cast<const LabelDecl *>(data[0]);
1717 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001718 SourceLocation getLoc() const {
1719 return SourceLocation::getFromPtrEncoding(data[1]); }
1720};
1721
1722class NestedNameSpecifierLocVisit : public VisitorJob {
1723public:
1724 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1725 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1726 Qualifier.getNestedNameSpecifier(),
1727 Qualifier.getOpaqueData()) { }
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1731 }
1732
1733 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001734 return NestedNameSpecifierLoc(
1735 const_cast<NestedNameSpecifier *>(
1736 static_cast<const NestedNameSpecifier *>(data[0])),
1737 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001738 }
1739};
1740
1741class DeclarationNameInfoVisit : public VisitorJob {
1742public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001743 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001744 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1747 }
1748 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001749 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001750 switch (S->getStmtClass()) {
1751 default:
1752 llvm_unreachable("Unhandled Stmt");
1753 case clang::Stmt::MSDependentExistsStmtClass:
1754 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1755 case Stmt::CXXDependentScopeMemberExprClass:
1756 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1757 case Stmt::DependentScopeDeclRefExprClass:
1758 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1759 }
1760 }
1761};
1762class MemberRefVisit : public VisitorJob {
1763public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001764 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001765 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1766 L.getPtrEncoding()) {}
1767 static bool classof(const VisitorJob *VJ) {
1768 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1769 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001770 const FieldDecl *get() const {
1771 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001772 }
1773 SourceLocation getLoc() const {
1774 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1775 }
1776};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001777class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001778 VisitorWorkList &WL;
1779 CXCursor Parent;
1780public:
1781 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1782 : WL(wl), Parent(parent) {}
1783
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001784 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1785 void VisitBlockExpr(const BlockExpr *B);
1786 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1787 void VisitCompoundStmt(const CompoundStmt *S);
1788 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1789 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1790 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1791 void VisitCXXNewExpr(const CXXNewExpr *E);
1792 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1793 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1794 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1795 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1796 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1797 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1798 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1799 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1800 void VisitDeclRefExpr(const DeclRefExpr *D);
1801 void VisitDeclStmt(const DeclStmt *S);
1802 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1803 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1804 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1805 void VisitForStmt(const ForStmt *FS);
1806 void VisitGotoStmt(const GotoStmt *GS);
1807 void VisitIfStmt(const IfStmt *If);
1808 void VisitInitListExpr(const InitListExpr *IE);
1809 void VisitMemberExpr(const MemberExpr *M);
1810 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1811 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1812 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1813 void VisitOverloadExpr(const OverloadExpr *E);
1814 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1815 void VisitStmt(const Stmt *S);
1816 void VisitSwitchStmt(const SwitchStmt *S);
1817 void VisitWhileStmt(const WhileStmt *W);
1818 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1819 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1820 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1821 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1822 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1823 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1824 void VisitVAArgExpr(const VAArgExpr *E);
1825 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1826 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1827 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1828 void VisitLambdaExpr(const LambdaExpr *E);
1829
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001830private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001831 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001832 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1833 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001834 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1835 void AddStmt(const Stmt *S);
1836 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001837 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001838 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001839};
1840} // end anonyous namespace
1841
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001842void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001843 // 'S' should always be non-null, since it comes from the
1844 // statement we are visiting.
1845 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1846}
1847
1848void
1849EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1850 if (Qualifier)
1851 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1852}
1853
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001854void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001855 if (S)
1856 WL.push_back(StmtVisit(S, Parent));
1857}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001858void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001859 if (D)
1860 WL.push_back(DeclVisit(D, Parent, isFirst));
1861}
1862void EnqueueVisitor::
1863 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1864 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001865 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001866}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001867void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001868 if (D)
1869 WL.push_back(MemberRefVisit(D, L, Parent));
1870}
1871void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1872 if (TI)
1873 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1874 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001875void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001876 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001877 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001878 AddStmt(*Child);
1879 }
1880 if (size == WL.size())
1881 return;
1882 // Now reverse the entries we just added. This will match the DFS
1883 // ordering performed by the worklist.
1884 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1885 std::reverse(I, E);
1886}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001887void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001888 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1889}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001890void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001891 AddDecl(B->getBlockDecl());
1892}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001893void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001894 EnqueueChildren(E);
1895 AddTypeLoc(E->getTypeSourceInfo());
1896}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001897void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1898 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001899 E = S->body_rend(); I != E; ++I) {
1900 AddStmt(*I);
1901 }
1902}
1903void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001904VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001905 AddStmt(S->getSubStmt());
1906 AddDeclarationNameInfo(S);
1907 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1908 AddNestedNameSpecifierLoc(QualifierLoc);
1909}
1910
1911void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001912VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001913 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1914 AddDeclarationNameInfo(E);
1915 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1916 AddNestedNameSpecifierLoc(QualifierLoc);
1917 if (!E->isImplicitAccess())
1918 AddStmt(E->getBase());
1919}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001920void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001921 // Enqueue the initializer , if any.
1922 AddStmt(E->getInitializer());
1923 // Enqueue the array size, if any.
1924 AddStmt(E->getArraySize());
1925 // Enqueue the allocated type.
1926 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1927 // Enqueue the placement arguments.
1928 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1929 AddStmt(E->getPlacementArg(I-1));
1930}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001931void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001932 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1933 AddStmt(CE->getArg(I-1));
1934 AddStmt(CE->getCallee());
1935 AddStmt(CE->getArg(0));
1936}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001937void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1938 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001939 // Visit the name of the type being destroyed.
1940 AddTypeLoc(E->getDestroyedTypeInfo());
1941 // Visit the scope type that looks disturbingly like the nested-name-specifier
1942 // but isn't.
1943 AddTypeLoc(E->getScopeTypeInfo());
1944 // Visit the nested-name-specifier.
1945 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1946 AddNestedNameSpecifierLoc(QualifierLoc);
1947 // Visit base expression.
1948 AddStmt(E->getBase());
1949}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001950void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1951 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001952 AddTypeLoc(E->getTypeSourceInfo());
1953}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001954void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1955 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001956 EnqueueChildren(E);
1957 AddTypeLoc(E->getTypeSourceInfo());
1958}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001959void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001960 EnqueueChildren(E);
1961 if (E->isTypeOperand())
1962 AddTypeLoc(E->getTypeOperandSourceInfo());
1963}
1964
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001965void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1966 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001967 EnqueueChildren(E);
1968 AddTypeLoc(E->getTypeSourceInfo());
1969}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001970void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001971 EnqueueChildren(E);
1972 if (E->isTypeOperand())
1973 AddTypeLoc(E->getTypeOperandSourceInfo());
1974}
1975
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001977 EnqueueChildren(S);
1978 AddDecl(S->getExceptionDecl());
1979}
1980
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001982 if (DR->hasExplicitTemplateArgs()) {
1983 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1984 }
1985 WL.push_back(DeclRefExprParts(DR, Parent));
1986}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001987void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
1988 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001989 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1990 AddDeclarationNameInfo(E);
1991 AddNestedNameSpecifierLoc(E->getQualifierLoc());
1992}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001994 unsigned size = WL.size();
1995 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001996 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001997 D != DEnd; ++D) {
1998 AddDecl(*D, isFirst);
1999 isFirst = false;
2000 }
2001 if (size == WL.size())
2002 return;
2003 // Now reverse the entries we just added. This will match the DFS
2004 // ordering performed by the worklist.
2005 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2006 std::reverse(I, E);
2007}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002009 AddStmt(E->getInit());
2010 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002011 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002012 D = E->designators_rbegin(), DEnd = E->designators_rend();
2013 D != DEnd; ++D) {
2014 if (D->isFieldDesignator()) {
2015 if (FieldDecl *Field = D->getField())
2016 AddMemberRef(Field, D->getFieldLoc());
2017 continue;
2018 }
2019 if (D->isArrayDesignator()) {
2020 AddStmt(E->getArrayIndex(*D));
2021 continue;
2022 }
2023 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2024 AddStmt(E->getArrayRangeEnd(*D));
2025 AddStmt(E->getArrayRangeStart(*D));
2026 }
2027}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002029 EnqueueChildren(E);
2030 AddTypeLoc(E->getTypeInfoAsWritten());
2031}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002032void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002033 AddStmt(FS->getBody());
2034 AddStmt(FS->getInc());
2035 AddStmt(FS->getCond());
2036 AddDecl(FS->getConditionVariable());
2037 AddStmt(FS->getInit());
2038}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002040 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2041}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002043 AddStmt(If->getElse());
2044 AddStmt(If->getThen());
2045 AddStmt(If->getCond());
2046 AddDecl(If->getConditionVariable());
2047}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002049 // We care about the syntactic form of the initializer list, only.
2050 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2051 IE = Syntactic;
2052 EnqueueChildren(IE);
2053}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002055 WL.push_back(MemberExprParts(M, Parent));
2056
2057 // If the base of the member access expression is an implicit 'this', don't
2058 // visit it.
2059 // FIXME: If we ever want to show these implicit accesses, this will be
2060 // unfortunate. However, clang_getCursor() relies on this behavior.
2061 if (!M->isImplicitAccess())
2062 AddStmt(M->getBase());
2063}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002065 AddTypeLoc(E->getEncodedTypeSourceInfo());
2066}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002068 EnqueueChildren(M);
2069 AddTypeLoc(M->getClassReceiverTypeInfo());
2070}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002072 // Visit the components of the offsetof expression.
2073 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2074 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2075 const OffsetOfNode &Node = E->getComponent(I-1);
2076 switch (Node.getKind()) {
2077 case OffsetOfNode::Array:
2078 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2079 break;
2080 case OffsetOfNode::Field:
2081 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2082 break;
2083 case OffsetOfNode::Identifier:
2084 case OffsetOfNode::Base:
2085 continue;
2086 }
2087 }
2088 // Visit the type into which we're computing the offset.
2089 AddTypeLoc(E->getTypeSourceInfo());
2090}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002092 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2093 WL.push_back(OverloadExprParts(E, Parent));
2094}
2095void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002096 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 if (E->isArgumentType())
2099 AddTypeLoc(E->getArgumentTypeInfo());
2100}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002102 EnqueueChildren(S);
2103}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002105 AddStmt(S->getBody());
2106 AddStmt(S->getCond());
2107 AddDecl(S->getConditionVariable());
2108}
2109
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002111 AddStmt(W->getBody());
2112 AddStmt(W->getCond());
2113 AddDecl(W->getConditionVariable());
2114}
2115
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002117 AddTypeLoc(E->getQueriedTypeSourceInfo());
2118}
2119
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002121 AddTypeLoc(E->getRhsTypeSourceInfo());
2122 AddTypeLoc(E->getLhsTypeSourceInfo());
2123}
2124
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002126 for (unsigned I = E->getNumArgs(); I > 0; --I)
2127 AddTypeLoc(E->getArg(I-1));
2128}
2129
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002131 AddTypeLoc(E->getQueriedTypeSourceInfo());
2132}
2133
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002135 EnqueueChildren(E);
2136}
2137
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002139 VisitOverloadExpr(U);
2140 if (!U->isImplicitAccess())
2141 AddStmt(U->getBase());
2142}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002144 AddStmt(E->getSubExpr());
2145 AddTypeLoc(E->getWrittenTypeInfo());
2146}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002148 WL.push_back(SizeOfPackExprParts(E, Parent));
2149}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002151 // If the opaque value has a source expression, just transparently
2152 // visit that. This is useful for (e.g.) pseudo-object expressions.
2153 if (Expr *SourceExpr = E->getSourceExpr())
2154 return Visit(SourceExpr);
2155}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002157 AddStmt(E->getBody());
2158 WL.push_back(LambdaExprParts(E, Parent));
2159}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002161 // Treat the expression like its syntactic form.
2162 Visit(E->getSyntacticForm());
2163}
2164
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002165void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002166 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2167}
2168
2169bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2170 if (RegionOfInterest.isValid()) {
2171 SourceRange Range = getRawCursorExtent(C);
2172 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2173 return false;
2174 }
2175 return true;
2176}
2177
2178bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2179 while (!WL.empty()) {
2180 // Dequeue the worklist item.
2181 VisitorJob LI = WL.back();
2182 WL.pop_back();
2183
2184 // Set the Parent field, then back to its old value once we're done.
2185 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2186
2187 switch (LI.getKind()) {
2188 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002189 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002190 if (!D)
2191 continue;
2192
2193 // For now, perform default visitation for Decls.
2194 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2195 cast<DeclVisit>(&LI)->isFirst())))
2196 return true;
2197
2198 continue;
2199 }
2200 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2201 const ASTTemplateArgumentListInfo *ArgList =
2202 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2203 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2204 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2205 Arg != ArgEnd; ++Arg) {
2206 if (VisitTemplateArgumentLoc(*Arg))
2207 return true;
2208 }
2209 continue;
2210 }
2211 case VisitorJob::TypeLocVisitKind: {
2212 // Perform default visitation for TypeLocs.
2213 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2214 return true;
2215 continue;
2216 }
2217 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002218 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002219 if (LabelStmt *stmt = LS->getStmt()) {
2220 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2221 TU))) {
2222 return true;
2223 }
2224 }
2225 continue;
2226 }
2227
2228 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2229 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2230 if (VisitNestedNameSpecifierLoc(V->get()))
2231 return true;
2232 continue;
2233 }
2234
2235 case VisitorJob::DeclarationNameInfoVisitKind: {
2236 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2237 ->get()))
2238 return true;
2239 continue;
2240 }
2241 case VisitorJob::MemberRefVisitKind: {
2242 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2243 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2244 return true;
2245 continue;
2246 }
2247 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002248 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002249 if (!S)
2250 continue;
2251
2252 // Update the current cursor.
2253 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2254 if (!IsInRegionOfInterest(Cursor))
2255 continue;
2256 switch (Visitor(Cursor, Parent, ClientData)) {
2257 case CXChildVisit_Break: return true;
2258 case CXChildVisit_Continue: break;
2259 case CXChildVisit_Recurse:
2260 if (PostChildrenVisitor)
2261 WL.push_back(PostChildrenVisit(0, Cursor));
2262 EnqueueWorkList(WL, S);
2263 break;
2264 }
2265 continue;
2266 }
2267 case VisitorJob::MemberExprPartsKind: {
2268 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002269 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002270
2271 // Visit the nested-name-specifier
2272 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2273 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2274 return true;
2275
2276 // Visit the declaration name.
2277 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2278 return true;
2279
2280 // Visit the explicitly-specified template arguments, if any.
2281 if (M->hasExplicitTemplateArgs()) {
2282 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2283 *ArgEnd = Arg + M->getNumTemplateArgs();
2284 Arg != ArgEnd; ++Arg) {
2285 if (VisitTemplateArgumentLoc(*Arg))
2286 return true;
2287 }
2288 }
2289 continue;
2290 }
2291 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002292 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002293 // Visit nested-name-specifier, if present.
2294 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2295 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2296 return true;
2297 // Visit declaration name.
2298 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2299 return true;
2300 continue;
2301 }
2302 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002303 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002304 // Visit the nested-name-specifier.
2305 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2306 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2307 return true;
2308 // Visit the declaration name.
2309 if (VisitDeclarationNameInfo(O->getNameInfo()))
2310 return true;
2311 // Visit the overloaded declaration reference.
2312 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2313 return true;
2314 continue;
2315 }
2316 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002317 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002318 NamedDecl *Pack = E->getPack();
2319 if (isa<TemplateTypeParmDecl>(Pack)) {
2320 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2321 E->getPackLoc(), TU)))
2322 return true;
2323
2324 continue;
2325 }
2326
2327 if (isa<TemplateTemplateParmDecl>(Pack)) {
2328 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2329 E->getPackLoc(), TU)))
2330 return true;
2331
2332 continue;
2333 }
2334
2335 // Non-type template parameter packs and function parameter packs are
2336 // treated like DeclRefExpr cursors.
2337 continue;
2338 }
2339
2340 case VisitorJob::LambdaExprPartsKind: {
2341 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002342 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002343 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2344 CEnd = E->explicit_capture_end();
2345 C != CEnd; ++C) {
2346 if (C->capturesThis())
2347 continue;
2348
2349 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2350 C->getLocation(),
2351 TU)))
2352 return true;
2353 }
2354
2355 // Visit parameters and return type, if present.
2356 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2357 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2358 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2359 // Visit the whole type.
2360 if (Visit(TL))
2361 return true;
2362 } else if (isa<FunctionProtoTypeLoc>(TL)) {
2363 FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
2364 if (E->hasExplicitParameters()) {
2365 // Visit parameters.
2366 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2367 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2368 return true;
2369 } else {
2370 // Visit result type.
2371 if (Visit(Proto.getResultLoc()))
2372 return true;
2373 }
2374 }
2375 }
2376 break;
2377 }
2378
2379 case VisitorJob::PostChildrenVisitKind:
2380 if (PostChildrenVisitor(Parent, ClientData))
2381 return true;
2382 break;
2383 }
2384 }
2385 return false;
2386}
2387
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002388bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002389 VisitorWorkList *WL = 0;
2390 if (!WorkListFreeList.empty()) {
2391 WL = WorkListFreeList.back();
2392 WL->clear();
2393 WorkListFreeList.pop_back();
2394 }
2395 else {
2396 WL = new VisitorWorkList();
2397 WorkListCache.push_back(WL);
2398 }
2399 EnqueueWorkList(*WL, S);
2400 bool result = RunVisitorWorkList(*WL);
2401 WorkListFreeList.push_back(WL);
2402 return result;
2403}
2404
2405namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002406typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002407RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2408 const DeclarationNameInfo &NI,
2409 const SourceRange &QLoc,
2410 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2411 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2412 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2413 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2414
2415 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2416
2417 RefNamePieces Pieces;
2418
2419 if (WantQualifier && QLoc.isValid())
2420 Pieces.push_back(QLoc);
2421
2422 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2423 Pieces.push_back(NI.getLoc());
2424
2425 if (WantTemplateArgs && TemplateArgs)
2426 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2427 TemplateArgs->RAngleLoc));
2428
2429 if (Kind == DeclarationName::CXXOperatorName) {
2430 Pieces.push_back(SourceLocation::getFromRawEncoding(
2431 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2432 Pieces.push_back(SourceLocation::getFromRawEncoding(
2433 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2434 }
2435
2436 if (WantSinglePiece) {
2437 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2438 Pieces.clear();
2439 Pieces.push_back(R);
2440 }
2441
2442 return Pieces;
2443}
2444}
2445
2446//===----------------------------------------------------------------------===//
2447// Misc. API hooks.
2448//===----------------------------------------------------------------------===//
2449
2450static llvm::sys::Mutex EnableMultithreadingMutex;
2451static bool EnabledMultithreading;
2452
2453static void fatal_error_handler(void *user_data, const std::string& reason) {
2454 // Write the result out to stderr avoiding errs() because raw_ostreams can
2455 // call report_fatal_error.
2456 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2457 ::abort();
2458}
2459
2460extern "C" {
2461CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2462 int displayDiagnostics) {
2463 // Disable pretty stack trace functionality, which will otherwise be a very
2464 // poor citizen of the world and set up all sorts of signal handlers.
2465 llvm::DisablePrettyStackTrace = true;
2466
2467 // We use crash recovery to make some of our APIs more reliable, implicitly
2468 // enable it.
2469 llvm::CrashRecoveryContext::Enable();
2470
2471 // Enable support for multithreading in LLVM.
2472 {
2473 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2474 if (!EnabledMultithreading) {
2475 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2476 llvm::llvm_start_multithreaded();
2477 EnabledMultithreading = true;
2478 }
2479 }
2480
2481 CIndexer *CIdxr = new CIndexer();
2482 if (excludeDeclarationsFromPCH)
2483 CIdxr->setOnlyLocalDecls();
2484 if (displayDiagnostics)
2485 CIdxr->setDisplayDiagnostics();
2486
2487 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2488 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2489 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2490 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2491 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2492 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2493
2494 return CIdxr;
2495}
2496
2497void clang_disposeIndex(CXIndex CIdx) {
2498 if (CIdx)
2499 delete static_cast<CIndexer *>(CIdx);
2500}
2501
2502void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2503 if (CIdx)
2504 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2505}
2506
2507unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2508 if (CIdx)
2509 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2510 return 0;
2511}
2512
2513void clang_toggleCrashRecovery(unsigned isEnabled) {
2514 if (isEnabled)
2515 llvm::CrashRecoveryContext::Enable();
2516 else
2517 llvm::CrashRecoveryContext::Disable();
2518}
2519
2520CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2521 const char *ast_filename) {
2522 if (!CIdx)
2523 return 0;
2524
2525 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2526 FileSystemOptions FileSystemOpts;
2527
2528 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2529 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2530 CXXIdx->getOnlyLocalDecls(),
2531 0, 0,
2532 /*CaptureDiagnostics=*/true,
2533 /*AllowPCHWithCompilerErrors=*/true,
2534 /*UserFilesAreVolatile=*/true);
2535 return MakeCXTranslationUnit(CXXIdx, TU);
2536}
2537
2538unsigned clang_defaultEditingTranslationUnitOptions() {
2539 return CXTranslationUnit_PrecompiledPreamble |
2540 CXTranslationUnit_CacheCompletionResults;
2541}
2542
2543CXTranslationUnit
2544clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2545 const char *source_filename,
2546 int num_command_line_args,
2547 const char * const *command_line_args,
2548 unsigned num_unsaved_files,
2549 struct CXUnsavedFile *unsaved_files) {
2550 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2551 return clang_parseTranslationUnit(CIdx, source_filename,
2552 command_line_args, num_command_line_args,
2553 unsaved_files, num_unsaved_files,
2554 Options);
2555}
2556
2557struct ParseTranslationUnitInfo {
2558 CXIndex CIdx;
2559 const char *source_filename;
2560 const char *const *command_line_args;
2561 int num_command_line_args;
2562 struct CXUnsavedFile *unsaved_files;
2563 unsigned num_unsaved_files;
2564 unsigned options;
2565 CXTranslationUnit result;
2566};
2567static void clang_parseTranslationUnit_Impl(void *UserData) {
2568 ParseTranslationUnitInfo *PTUI =
2569 static_cast<ParseTranslationUnitInfo*>(UserData);
2570 CXIndex CIdx = PTUI->CIdx;
2571 const char *source_filename = PTUI->source_filename;
2572 const char * const *command_line_args = PTUI->command_line_args;
2573 int num_command_line_args = PTUI->num_command_line_args;
2574 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2575 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2576 unsigned options = PTUI->options;
2577 PTUI->result = 0;
2578
2579 if (!CIdx)
2580 return;
2581
2582 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2583
2584 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2585 setThreadBackgroundPriority();
2586
2587 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2588 // FIXME: Add a flag for modules.
2589 TranslationUnitKind TUKind
2590 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2591 bool CacheCodeCompetionResults
2592 = options & CXTranslationUnit_CacheCompletionResults;
2593 bool IncludeBriefCommentsInCodeCompletion
2594 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2595 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2596 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2597
2598 // Configure the diagnostics.
2599 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002600 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002601
2602 // Recover resources if we crash before exiting this function.
2603 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2604 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2605 DiagCleanup(Diags.getPtr());
2606
2607 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2608 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2609
2610 // Recover resources if we crash before exiting this function.
2611 llvm::CrashRecoveryContextCleanupRegistrar<
2612 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2613
2614 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2615 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2616 const llvm::MemoryBuffer *Buffer
2617 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2618 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2619 Buffer));
2620 }
2621
2622 OwningPtr<std::vector<const char *> >
2623 Args(new std::vector<const char*>());
2624
2625 // Recover resources if we crash before exiting this method.
2626 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2627 ArgsCleanup(Args.get());
2628
2629 // Since the Clang C library is primarily used by batch tools dealing with
2630 // (often very broken) source code, where spell-checking can have a
2631 // significant negative impact on performance (particularly when
2632 // precompiled headers are involved), we disable it by default.
2633 // Only do this if we haven't found a spell-checking-related argument.
2634 bool FoundSpellCheckingArgument = false;
2635 for (int I = 0; I != num_command_line_args; ++I) {
2636 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2637 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2638 FoundSpellCheckingArgument = true;
2639 break;
2640 }
2641 }
2642 if (!FoundSpellCheckingArgument)
2643 Args->push_back("-fno-spell-checking");
2644
2645 Args->insert(Args->end(), command_line_args,
2646 command_line_args + num_command_line_args);
2647
2648 // The 'source_filename' argument is optional. If the caller does not
2649 // specify it then it is assumed that the source file is specified
2650 // in the actual argument list.
2651 // Put the source file after command_line_args otherwise if '-x' flag is
2652 // present it will be unused.
2653 if (source_filename)
2654 Args->push_back(source_filename);
2655
2656 // Do we need the detailed preprocessing record?
2657 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2658 Args->push_back("-Xclang");
2659 Args->push_back("-detailed-preprocessing-record");
2660 }
2661
2662 unsigned NumErrors = Diags->getClient()->getNumErrors();
2663 OwningPtr<ASTUnit> ErrUnit;
2664 OwningPtr<ASTUnit> Unit(
2665 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2666 /* vector::data() not portable */,
2667 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2668 Diags,
2669 CXXIdx->getClangResourcesPath(),
2670 CXXIdx->getOnlyLocalDecls(),
2671 /*CaptureDiagnostics=*/true,
2672 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2673 RemappedFiles->size(),
2674 /*RemappedFilesKeepOriginalName=*/true,
2675 PrecompilePreamble,
2676 TUKind,
2677 CacheCodeCompetionResults,
2678 IncludeBriefCommentsInCodeCompletion,
2679 /*AllowPCHWithCompilerErrors=*/true,
2680 SkipFunctionBodies,
2681 /*UserFilesAreVolatile=*/true,
2682 ForSerialization,
2683 &ErrUnit));
2684
2685 if (NumErrors != Diags->getClient()->getNumErrors()) {
2686 // Make sure to check that 'Unit' is non-NULL.
2687 if (CXXIdx->getDisplayDiagnostics())
2688 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2689 }
2690
2691 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2692}
2693CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2694 const char *source_filename,
2695 const char * const *command_line_args,
2696 int num_command_line_args,
2697 struct CXUnsavedFile *unsaved_files,
2698 unsigned num_unsaved_files,
2699 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002700 LOG_FUNC_SECTION {
2701 *Log << source_filename << ": ";
2702 for (int i = 0; i != num_command_line_args; ++i)
2703 *Log << command_line_args[i] << " ";
2704 }
2705
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002706 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2707 num_command_line_args, unsaved_files,
2708 num_unsaved_files, options, 0 };
2709 llvm::CrashRecoveryContext CRC;
2710
2711 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2712 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2713 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2714 fprintf(stderr, " 'command_line_args' : [");
2715 for (int i = 0; i != num_command_line_args; ++i) {
2716 if (i)
2717 fprintf(stderr, ", ");
2718 fprintf(stderr, "'%s'", command_line_args[i]);
2719 }
2720 fprintf(stderr, "],\n");
2721 fprintf(stderr, " 'unsaved_files' : [");
2722 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2723 if (i)
2724 fprintf(stderr, ", ");
2725 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2726 unsaved_files[i].Length);
2727 }
2728 fprintf(stderr, "],\n");
2729 fprintf(stderr, " 'options' : %d,\n", options);
2730 fprintf(stderr, "}\n");
2731
2732 return 0;
2733 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2734 PrintLibclangResourceUsage(PTUI.result);
2735 }
2736
2737 return PTUI.result;
2738}
2739
2740unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2741 return CXSaveTranslationUnit_None;
2742}
2743
2744namespace {
2745
2746struct SaveTranslationUnitInfo {
2747 CXTranslationUnit TU;
2748 const char *FileName;
2749 unsigned options;
2750 CXSaveError result;
2751};
2752
2753}
2754
2755static void clang_saveTranslationUnit_Impl(void *UserData) {
2756 SaveTranslationUnitInfo *STUI =
2757 static_cast<SaveTranslationUnitInfo*>(UserData);
2758
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002759 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002760 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2761 setThreadBackgroundPriority();
2762
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002763 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002764 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2765}
2766
2767int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2768 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002769 LOG_FUNC_SECTION {
2770 *Log << TU << ' ' << FileName;
2771 }
2772
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002773 if (!TU)
2774 return CXSaveError_InvalidTU;
2775
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002776 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002777 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2778 if (!CXXUnit->hasSema())
2779 return CXSaveError_InvalidTU;
2780
2781 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2782
2783 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2784 getenv("LIBCLANG_NOTHREADS")) {
2785 clang_saveTranslationUnit_Impl(&STUI);
2786
2787 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2788 PrintLibclangResourceUsage(TU);
2789
2790 return STUI.result;
2791 }
2792
2793 // We have an AST that has invalid nodes due to compiler errors.
2794 // Use a crash recovery thread for protection.
2795
2796 llvm::CrashRecoveryContext CRC;
2797
2798 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2799 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2800 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2801 fprintf(stderr, " 'options' : %d,\n", options);
2802 fprintf(stderr, "}\n");
2803
2804 return CXSaveError_Unknown;
2805
2806 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2807 PrintLibclangResourceUsage(TU);
2808 }
2809
2810 return STUI.result;
2811}
2812
2813void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2814 if (CTUnit) {
2815 // If the translation unit has been marked as unsafe to free, just discard
2816 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002817 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002818 return;
2819
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002820 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002821 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002822 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2823 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002824 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002825 delete CTUnit;
2826 }
2827}
2828
2829unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2830 return CXReparse_None;
2831}
2832
2833struct ReparseTranslationUnitInfo {
2834 CXTranslationUnit TU;
2835 unsigned num_unsaved_files;
2836 struct CXUnsavedFile *unsaved_files;
2837 unsigned options;
2838 int result;
2839};
2840
2841static void clang_reparseTranslationUnit_Impl(void *UserData) {
2842 ReparseTranslationUnitInfo *RTUI =
2843 static_cast<ReparseTranslationUnitInfo*>(UserData);
2844 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002845 if (!TU)
2846 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002847
2848 // Reset the associated diagnostics.
2849 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2850 TU->Diagnostics = 0;
2851
2852 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2853 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2854 unsigned options = RTUI->options;
2855 (void) options;
2856 RTUI->result = 1;
2857
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002858 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002859 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2860 setThreadBackgroundPriority();
2861
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002862 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002863 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2864
2865 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2866 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2867
2868 // Recover resources if we crash before exiting this function.
2869 llvm::CrashRecoveryContextCleanupRegistrar<
2870 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2871
2872 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2873 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2874 const llvm::MemoryBuffer *Buffer
2875 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2876 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2877 Buffer));
2878 }
2879
2880 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2881 RemappedFiles->size()))
2882 RTUI->result = 0;
2883}
2884
2885int clang_reparseTranslationUnit(CXTranslationUnit TU,
2886 unsigned num_unsaved_files,
2887 struct CXUnsavedFile *unsaved_files,
2888 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002889 LOG_FUNC_SECTION {
2890 *Log << TU;
2891 }
2892
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002893 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2894 options, 0 };
2895
2896 if (getenv("LIBCLANG_NOTHREADS")) {
2897 clang_reparseTranslationUnit_Impl(&RTUI);
2898 return RTUI.result;
2899 }
2900
2901 llvm::CrashRecoveryContext CRC;
2902
2903 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2904 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002905 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002906 return 1;
2907 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2908 PrintLibclangResourceUsage(TU);
2909
2910 return RTUI.result;
2911}
2912
2913
2914CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2915 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002916 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002917
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002918 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002919 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002920}
2921
2922CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002923 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002924 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2925}
2926
2927} // end: extern "C"
2928
2929//===----------------------------------------------------------------------===//
2930// CXFile Operations.
2931//===----------------------------------------------------------------------===//
2932
2933extern "C" {
2934CXString clang_getFileName(CXFile SFile) {
2935 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002936 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002937
2938 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002939 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002940}
2941
2942time_t clang_getFileTime(CXFile SFile) {
2943 if (!SFile)
2944 return 0;
2945
2946 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2947 return FEnt->getModificationTime();
2948}
2949
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002950CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2951 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002952 return 0;
2953
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002954 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002955
2956 FileManager &FMgr = CXXUnit->getFileManager();
2957 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2958}
2959
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002960unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2961 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002962 return 0;
2963
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002964 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002965 FileEntry *FEnt = static_cast<FileEntry *>(file);
2966 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2967 .isFileMultipleIncludeGuarded(FEnt);
2968}
2969
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002970int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2971 if (!file || !outID)
2972 return 1;
2973
2974#ifdef LLVM_ON_WIN32
2975 return 1; // inodes not supported on windows.
2976#else
2977 FileEntry *FEnt = static_cast<FileEntry *>(file);
2978 outID->data[0] = FEnt->getDevice();
2979 outID->data[1] = FEnt->getInode();
2980 outID->data[2] = FEnt->getModificationTime();
2981 return 0;
2982#endif
2983}
2984
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002985} // end: extern "C"
2986
2987//===----------------------------------------------------------------------===//
2988// CXCursor Operations.
2989//===----------------------------------------------------------------------===//
2990
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002991static const Decl *getDeclFromExpr(const Stmt *E) {
2992 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002993 return getDeclFromExpr(CE->getSubExpr());
2994
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002995 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002996 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002997 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002998 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00002999 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003000 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003001 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003002 if (PRE->isExplicitProperty())
3003 return PRE->getExplicitProperty();
3004 // It could be messaging both getter and setter as in:
3005 // ++myobj.myprop;
3006 // in which case prefer to associate the setter since it is less obvious
3007 // from inspecting the source that the setter is going to get called.
3008 if (PRE->isMessagingSetter())
3009 return PRE->getImplicitPropertySetter();
3010 return PRE->getImplicitPropertyGetter();
3011 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003012 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003013 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003014 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003015 if (Expr *Src = OVE->getSourceExpr())
3016 return getDeclFromExpr(Src);
3017
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003018 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003019 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003020 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003021 if (!CE->isElidable())
3022 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003023 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003024 return OME->getMethodDecl();
3025
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003026 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003027 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003028 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003029 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3030 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003031 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003032 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3033 isa<ParmVarDecl>(SizeOfPack->getPack()))
3034 return SizeOfPack->getPack();
3035
3036 return 0;
3037}
3038
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003039static SourceLocation getLocationFromExpr(const Expr *E) {
3040 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003041 return getLocationFromExpr(CE->getSubExpr());
3042
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003043 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003044 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003045 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003046 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003047 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003048 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003049 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003050 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003051 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003052 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003053 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003054 return PropRef->getLocation();
3055
3056 return E->getLocStart();
3057}
3058
3059extern "C" {
3060
3061unsigned clang_visitChildren(CXCursor parent,
3062 CXCursorVisitor visitor,
3063 CXClientData client_data) {
3064 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3065 /*VisitPreprocessorLast=*/false);
3066 return CursorVis.VisitChildren(parent);
3067}
3068
3069#ifndef __has_feature
3070#define __has_feature(x) 0
3071#endif
3072#if __has_feature(blocks)
3073typedef enum CXChildVisitResult
3074 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3075
3076static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3077 CXClientData client_data) {
3078 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3079 return block(cursor, parent);
3080}
3081#else
3082// If we are compiled with a compiler that doesn't have native blocks support,
3083// define and call the block manually, so the
3084typedef struct _CXChildVisitResult
3085{
3086 void *isa;
3087 int flags;
3088 int reserved;
3089 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3090 CXCursor);
3091} *CXCursorVisitorBlock;
3092
3093static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3094 CXClientData client_data) {
3095 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3096 return block->invoke(block, cursor, parent);
3097}
3098#endif
3099
3100
3101unsigned clang_visitChildrenWithBlock(CXCursor parent,
3102 CXCursorVisitorBlock block) {
3103 return clang_visitChildren(parent, visitWithBlock, block);
3104}
3105
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003106static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003107 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003108 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003109
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003110 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003111 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003112 if (const ObjCPropertyImplDecl *PropImpl =
3113 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003114 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003115 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003116
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003117 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003118 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003119 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003120
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003121 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003122 }
3123
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003124 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003125 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003126
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003127 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003128 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3129 // and returns different names. NamedDecl returns the class name and
3130 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003131 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003132
3133 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003134 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135
3136 SmallString<1024> S;
3137 llvm::raw_svector_ostream os(S);
3138 ND->printName(os);
3139
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003140 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003141}
3142
3143CXString clang_getCursorSpelling(CXCursor C) {
3144 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003145 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003146
3147 if (clang_isReference(C.kind)) {
3148 switch (C.kind) {
3149 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003150 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003151 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003152 }
3153 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003154 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003155 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003156 }
3157 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003158 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003159 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003160 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003161 }
3162 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003163 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003164 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003165 }
3166 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003167 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003168 assert(Type && "Missing type decl");
3169
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003170 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003171 getAsString());
3172 }
3173 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003174 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003175 assert(Template && "Missing template decl");
3176
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003177 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003178 }
3179
3180 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003181 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003182 assert(NS && "Missing namespace decl");
3183
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003184 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003185 }
3186
3187 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003188 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003189 assert(Field && "Missing member decl");
3190
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003191 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 }
3193
3194 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003195 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003196 assert(Label && "Missing label");
3197
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003198 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 }
3200
3201 case CXCursor_OverloadedDeclRef: {
3202 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003203 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3204 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003205 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003206 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003207 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003208 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003209 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003210 OverloadedTemplateStorage *Ovl
3211 = Storage.get<OverloadedTemplateStorage*>();
3212 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003213 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003214 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003215 }
3216
3217 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003218 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003219 assert(Var && "Missing variable decl");
3220
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003221 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003222 }
3223
3224 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003225 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003226 }
3227 }
3228
3229 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003230 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003231 if (D)
3232 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003233 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003234 }
3235
3236 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003237 const Stmt *S = getCursorStmt(C);
3238 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003239 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003240
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003241 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 }
3243
3244 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003245 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246 ->getNameStart());
3247
3248 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003249 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003250 ->getNameStart());
3251
3252 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003253 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003254
3255 if (clang_isDeclaration(C.kind))
3256 return getDeclSpelling(getCursorDecl(C));
3257
3258 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003259 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003260 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003261 }
3262
3263 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003264 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003265 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003266 }
3267
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003268 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003269}
3270
3271CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3272 unsigned pieceIndex,
3273 unsigned options) {
3274 if (clang_Cursor_isNull(C))
3275 return clang_getNullRange();
3276
3277 ASTContext &Ctx = getCursorContext(C);
3278
3279 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003280 const Stmt *S = getCursorStmt(C);
3281 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282 if (pieceIndex > 0)
3283 return clang_getNullRange();
3284 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3285 }
3286
3287 return clang_getNullRange();
3288 }
3289
3290 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003291 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003292 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3293 if (pieceIndex >= ME->getNumSelectorLocs())
3294 return clang_getNullRange();
3295 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3296 }
3297 }
3298
3299 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3300 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003301 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003302 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3303 if (pieceIndex >= MD->getNumSelectorLocs())
3304 return clang_getNullRange();
3305 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3306 }
3307 }
3308
3309 if (C.kind == CXCursor_ObjCCategoryDecl ||
3310 C.kind == CXCursor_ObjCCategoryImplDecl) {
3311 if (pieceIndex > 0)
3312 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003313 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003314 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3315 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003316 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003317 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3318 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3319 }
3320
3321 if (C.kind == CXCursor_ModuleImportDecl) {
3322 if (pieceIndex > 0)
3323 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003324 if (const ImportDecl *ImportD =
3325 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003326 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3327 if (!Locs.empty())
3328 return cxloc::translateSourceRange(Ctx,
3329 SourceRange(Locs.front(), Locs.back()));
3330 }
3331 return clang_getNullRange();
3332 }
3333
3334 // FIXME: A CXCursor_InclusionDirective should give the location of the
3335 // filename, but we don't keep track of this.
3336
3337 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3338 // but we don't keep track of this.
3339
3340 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3341 // but we don't keep track of this.
3342
3343 // Default handling, give the location of the cursor.
3344
3345 if (pieceIndex > 0)
3346 return clang_getNullRange();
3347
3348 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3349 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3350 return cxloc::translateSourceRange(Ctx, Loc);
3351}
3352
3353CXString clang_getCursorDisplayName(CXCursor C) {
3354 if (!clang_isDeclaration(C.kind))
3355 return clang_getCursorSpelling(C);
3356
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003357 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003358 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003359 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003360
3361 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003362 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003363 D = FunTmpl->getTemplatedDecl();
3364
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003365 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003366 SmallString<64> Str;
3367 llvm::raw_svector_ostream OS(Str);
3368 OS << *Function;
3369 if (Function->getPrimaryTemplate())
3370 OS << "<>";
3371 OS << "(";
3372 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3373 if (I)
3374 OS << ", ";
3375 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3376 }
3377
3378 if (Function->isVariadic()) {
3379 if (Function->getNumParams())
3380 OS << ", ";
3381 OS << "...";
3382 }
3383 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003384 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003385 }
3386
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003387 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003388 SmallString<64> Str;
3389 llvm::raw_svector_ostream OS(Str);
3390 OS << *ClassTemplate;
3391 OS << "<";
3392 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3393 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3394 if (I)
3395 OS << ", ";
3396
3397 NamedDecl *Param = Params->getParam(I);
3398 if (Param->getIdentifier()) {
3399 OS << Param->getIdentifier()->getName();
3400 continue;
3401 }
3402
3403 // There is no parameter name, which makes this tricky. Try to come up
3404 // with something useful that isn't too long.
3405 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3406 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3407 else if (NonTypeTemplateParmDecl *NTTP
3408 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3409 OS << NTTP->getType().getAsString(Policy);
3410 else
3411 OS << "template<...> class";
3412 }
3413
3414 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003415 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003416 }
3417
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003418 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003419 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3420 // If the type was explicitly written, use that.
3421 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003422 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003423
3424 SmallString<64> Str;
3425 llvm::raw_svector_ostream OS(Str);
3426 OS << *ClassSpec;
3427 OS << TemplateSpecializationType::PrintTemplateArgumentList(
3428 ClassSpec->getTemplateArgs().data(),
3429 ClassSpec->getTemplateArgs().size(),
3430 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003431 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003432 }
3433
3434 return clang_getCursorSpelling(C);
3435}
3436
3437CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3438 switch (Kind) {
3439 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003440 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003441 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003442 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003443 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003444 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003445 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003446 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003447 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003448 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003449 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003450 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003452 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003453 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003454 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003455 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003456 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003457 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003458 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003459 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003460 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003461 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003462 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003463 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003464 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003465 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003466 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003467 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003468 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003469 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003470 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003472 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003474 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("ObjCBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 }
3732
3733 llvm_unreachable("Unhandled CXCursorKind");
3734}
3735
3736struct GetCursorData {
3737 SourceLocation TokenBeginLoc;
3738 bool PointsAtMacroArgExpansion;
3739 bool VisitedObjCPropertyImplDecl;
3740 SourceLocation VisitedDeclaratorDeclStartLoc;
3741 CXCursor &BestCursor;
3742
3743 GetCursorData(SourceManager &SM,
3744 SourceLocation tokenBegin, CXCursor &outputCursor)
3745 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3746 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3747 VisitedObjCPropertyImplDecl = false;
3748 }
3749};
3750
3751static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3752 CXCursor parent,
3753 CXClientData client_data) {
3754 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3755 CXCursor *BestCursor = &Data->BestCursor;
3756
3757 // If we point inside a macro argument we should provide info of what the
3758 // token is so use the actual cursor, don't replace it with a macro expansion
3759 // cursor.
3760 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3761 return CXChildVisit_Recurse;
3762
3763 if (clang_isDeclaration(cursor.kind)) {
3764 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003765 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003766 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3767 if (MD->isImplicit())
3768 return CXChildVisit_Break;
3769
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003770 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003771 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3772 // Check that when we have multiple @class references in the same line,
3773 // that later ones do not override the previous ones.
3774 // If we have:
3775 // @class Foo, Bar;
3776 // source ranges for both start at '@', so 'Bar' will end up overriding
3777 // 'Foo' even though the cursor location was at 'Foo'.
3778 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3779 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003780 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003781 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3782 if (PrevID != ID &&
3783 !PrevID->isThisDeclarationADefinition() &&
3784 !ID->isThisDeclarationADefinition())
3785 return CXChildVisit_Break;
3786 }
3787
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003788 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003789 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3790 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3791 // Check that when we have multiple declarators in the same line,
3792 // that later ones do not override the previous ones.
3793 // If we have:
3794 // int Foo, Bar;
3795 // source ranges for both start at 'int', so 'Bar' will end up overriding
3796 // 'Foo' even though the cursor location was at 'Foo'.
3797 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3798 return CXChildVisit_Break;
3799 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3800
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003801 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003802 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3803 (void)PropImp;
3804 // Check that when we have multiple @synthesize in the same line,
3805 // that later ones do not override the previous ones.
3806 // If we have:
3807 // @synthesize Foo, Bar;
3808 // source ranges for both start at '@', so 'Bar' will end up overriding
3809 // 'Foo' even though the cursor location was at 'Foo'.
3810 if (Data->VisitedObjCPropertyImplDecl)
3811 return CXChildVisit_Break;
3812 Data->VisitedObjCPropertyImplDecl = true;
3813 }
3814 }
3815
3816 if (clang_isExpression(cursor.kind) &&
3817 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003818 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003819 // Avoid having the cursor of an expression replace the declaration cursor
3820 // when the expression source range overlaps the declaration range.
3821 // This can happen for C++ constructor expressions whose range generally
3822 // include the variable declaration, e.g.:
3823 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3824 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3825 D->getLocation() == Data->TokenBeginLoc)
3826 return CXChildVisit_Break;
3827 }
3828 }
3829
3830 // If our current best cursor is the construction of a temporary object,
3831 // don't replace that cursor with a type reference, because we want
3832 // clang_getCursor() to point at the constructor.
3833 if (clang_isExpression(BestCursor->kind) &&
3834 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3835 cursor.kind == CXCursor_TypeRef) {
3836 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3837 // as having the actual point on the type reference.
3838 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3839 return CXChildVisit_Recurse;
3840 }
3841
3842 *BestCursor = cursor;
3843 return CXChildVisit_Recurse;
3844}
3845
3846CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3847 if (!TU)
3848 return clang_getNullCursor();
3849
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003850 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003851 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3852
3853 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3854 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3855
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003856 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003857 CXFile SearchFile;
3858 unsigned SearchLine, SearchColumn;
3859 CXFile ResultFile;
3860 unsigned ResultLine, ResultColumn;
3861 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3862 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3863 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3864
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003865 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3866 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003867 &ResultColumn, 0);
3868 SearchFileName = clang_getFileName(SearchFile);
3869 ResultFileName = clang_getFileName(ResultFile);
3870 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3871 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003872 *Log << llvm::format("(%s:%d:%d) = %s",
3873 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3874 clang_getCString(KindSpelling))
3875 << llvm::format("(%s:%d:%d):%s%s",
3876 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3877 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003878 clang_disposeString(SearchFileName);
3879 clang_disposeString(ResultFileName);
3880 clang_disposeString(KindSpelling);
3881 clang_disposeString(USR);
3882
3883 CXCursor Definition = clang_getCursorDefinition(Result);
3884 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3885 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3886 CXString DefinitionKindSpelling
3887 = clang_getCursorKindSpelling(Definition.kind);
3888 CXFile DefinitionFile;
3889 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003890 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003891 &DefinitionLine, &DefinitionColumn, 0);
3892 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003893 *Log << llvm::format(" -> %s(%s:%d:%d)",
3894 clang_getCString(DefinitionKindSpelling),
3895 clang_getCString(DefinitionFileName),
3896 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003897 clang_disposeString(DefinitionFileName);
3898 clang_disposeString(DefinitionKindSpelling);
3899 }
3900 }
3901
3902 return Result;
3903}
3904
3905CXCursor clang_getNullCursor(void) {
3906 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3907}
3908
3909unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003910 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3911 // can't set consistently. For example, when visiting a DeclStmt we will set
3912 // it but we don't set it on the result of clang_getCursorDefinition for
3913 // a reference of the same declaration.
3914 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3915 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3916 // to provide that kind of info.
3917 if (clang_isDeclaration(X.kind))
3918 X.data[1] = 0;
3919 if (clang_isDeclaration(Y.kind))
3920 Y.data[1] = 0;
3921
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003922 return X == Y;
3923}
3924
3925unsigned clang_hashCursor(CXCursor C) {
3926 unsigned Index = 0;
3927 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3928 Index = 1;
3929
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003930 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003931 std::make_pair(C.kind, C.data[Index]));
3932}
3933
3934unsigned clang_isInvalid(enum CXCursorKind K) {
3935 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3936}
3937
3938unsigned clang_isDeclaration(enum CXCursorKind K) {
3939 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3940 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3941}
3942
3943unsigned clang_isReference(enum CXCursorKind K) {
3944 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3945}
3946
3947unsigned clang_isExpression(enum CXCursorKind K) {
3948 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3949}
3950
3951unsigned clang_isStatement(enum CXCursorKind K) {
3952 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3953}
3954
3955unsigned clang_isAttribute(enum CXCursorKind K) {
3956 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3957}
3958
3959unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3960 return K == CXCursor_TranslationUnit;
3961}
3962
3963unsigned clang_isPreprocessing(enum CXCursorKind K) {
3964 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3965}
3966
3967unsigned clang_isUnexposed(enum CXCursorKind K) {
3968 switch (K) {
3969 case CXCursor_UnexposedDecl:
3970 case CXCursor_UnexposedExpr:
3971 case CXCursor_UnexposedStmt:
3972 case CXCursor_UnexposedAttr:
3973 return true;
3974 default:
3975 return false;
3976 }
3977}
3978
3979CXCursorKind clang_getCursorKind(CXCursor C) {
3980 return C.kind;
3981}
3982
3983CXSourceLocation clang_getCursorLocation(CXCursor C) {
3984 if (clang_isReference(C.kind)) {
3985 switch (C.kind) {
3986 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003987 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003988 = getCursorObjCSuperClassRef(C);
3989 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3990 }
3991
3992 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003993 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003994 = getCursorObjCProtocolRef(C);
3995 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3996 }
3997
3998 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003999 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004000 = getCursorObjCClassRef(C);
4001 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4002 }
4003
4004 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004005 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004006 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4007 }
4008
4009 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004010 std::pair<const TemplateDecl *, SourceLocation> P =
4011 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004012 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4013 }
4014
4015 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004016 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004017 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4018 }
4019
4020 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004021 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004022 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4023 }
4024
4025 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004026 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004027 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4028 }
4029
4030 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004031 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004032 if (!BaseSpec)
4033 return clang_getNullLocation();
4034
4035 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4036 return cxloc::translateSourceLocation(getCursorContext(C),
4037 TSInfo->getTypeLoc().getBeginLoc());
4038
4039 return cxloc::translateSourceLocation(getCursorContext(C),
4040 BaseSpec->getLocStart());
4041 }
4042
4043 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004044 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004045 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4046 }
4047
4048 case CXCursor_OverloadedDeclRef:
4049 return cxloc::translateSourceLocation(getCursorContext(C),
4050 getCursorOverloadedDeclRef(C).second);
4051
4052 default:
4053 // FIXME: Need a way to enumerate all non-reference cases.
4054 llvm_unreachable("Missed a reference kind");
4055 }
4056 }
4057
4058 if (clang_isExpression(C.kind))
4059 return cxloc::translateSourceLocation(getCursorContext(C),
4060 getLocationFromExpr(getCursorExpr(C)));
4061
4062 if (clang_isStatement(C.kind))
4063 return cxloc::translateSourceLocation(getCursorContext(C),
4064 getCursorStmt(C)->getLocStart());
4065
4066 if (C.kind == CXCursor_PreprocessingDirective) {
4067 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4068 return cxloc::translateSourceLocation(getCursorContext(C), L);
4069 }
4070
4071 if (C.kind == CXCursor_MacroExpansion) {
4072 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004073 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004074 return cxloc::translateSourceLocation(getCursorContext(C), L);
4075 }
4076
4077 if (C.kind == CXCursor_MacroDefinition) {
4078 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4079 return cxloc::translateSourceLocation(getCursorContext(C), L);
4080 }
4081
4082 if (C.kind == CXCursor_InclusionDirective) {
4083 SourceLocation L
4084 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4085 return cxloc::translateSourceLocation(getCursorContext(C), L);
4086 }
4087
4088 if (!clang_isDeclaration(C.kind))
4089 return clang_getNullLocation();
4090
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004091 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004092 if (!D)
4093 return clang_getNullLocation();
4094
4095 SourceLocation Loc = D->getLocation();
4096 // FIXME: Multiple variables declared in a single declaration
4097 // currently lack the information needed to correctly determine their
4098 // ranges when accounting for the type-specifier. We use context
4099 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4100 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004101 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004102 if (!cxcursor::isFirstInDeclGroup(C))
4103 Loc = VD->getLocation();
4104 }
4105
4106 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004107 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004108 Loc = MD->getSelectorStartLoc();
4109
4110 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4111}
4112
4113} // end extern "C"
4114
4115CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4116 assert(TU);
4117
4118 // Guard against an invalid SourceLocation, or we may assert in one
4119 // of the following calls.
4120 if (SLoc.isInvalid())
4121 return clang_getNullCursor();
4122
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004123 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004124
4125 // Translate the given source location to make it point at the beginning of
4126 // the token under the cursor.
4127 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4128 CXXUnit->getASTContext().getLangOpts());
4129
4130 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4131 if (SLoc.isValid()) {
4132 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4133 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4134 /*VisitPreprocessorLast=*/true,
4135 /*VisitIncludedEntities=*/false,
4136 SourceLocation(SLoc));
4137 CursorVis.visitFileRegion();
4138 }
4139
4140 return Result;
4141}
4142
4143static SourceRange getRawCursorExtent(CXCursor C) {
4144 if (clang_isReference(C.kind)) {
4145 switch (C.kind) {
4146 case CXCursor_ObjCSuperClassRef:
4147 return getCursorObjCSuperClassRef(C).second;
4148
4149 case CXCursor_ObjCProtocolRef:
4150 return getCursorObjCProtocolRef(C).second;
4151
4152 case CXCursor_ObjCClassRef:
4153 return getCursorObjCClassRef(C).second;
4154
4155 case CXCursor_TypeRef:
4156 return getCursorTypeRef(C).second;
4157
4158 case CXCursor_TemplateRef:
4159 return getCursorTemplateRef(C).second;
4160
4161 case CXCursor_NamespaceRef:
4162 return getCursorNamespaceRef(C).second;
4163
4164 case CXCursor_MemberRef:
4165 return getCursorMemberRef(C).second;
4166
4167 case CXCursor_CXXBaseSpecifier:
4168 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4169
4170 case CXCursor_LabelRef:
4171 return getCursorLabelRef(C).second;
4172
4173 case CXCursor_OverloadedDeclRef:
4174 return getCursorOverloadedDeclRef(C).second;
4175
4176 case CXCursor_VariableRef:
4177 return getCursorVariableRef(C).second;
4178
4179 default:
4180 // FIXME: Need a way to enumerate all non-reference cases.
4181 llvm_unreachable("Missed a reference kind");
4182 }
4183 }
4184
4185 if (clang_isExpression(C.kind))
4186 return getCursorExpr(C)->getSourceRange();
4187
4188 if (clang_isStatement(C.kind))
4189 return getCursorStmt(C)->getSourceRange();
4190
4191 if (clang_isAttribute(C.kind))
4192 return getCursorAttr(C)->getRange();
4193
4194 if (C.kind == CXCursor_PreprocessingDirective)
4195 return cxcursor::getCursorPreprocessingDirective(C);
4196
4197 if (C.kind == CXCursor_MacroExpansion) {
4198 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004199 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004200 return TU->mapRangeFromPreamble(Range);
4201 }
4202
4203 if (C.kind == CXCursor_MacroDefinition) {
4204 ASTUnit *TU = getCursorASTUnit(C);
4205 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4206 return TU->mapRangeFromPreamble(Range);
4207 }
4208
4209 if (C.kind == CXCursor_InclusionDirective) {
4210 ASTUnit *TU = getCursorASTUnit(C);
4211 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4212 return TU->mapRangeFromPreamble(Range);
4213 }
4214
4215 if (C.kind == CXCursor_TranslationUnit) {
4216 ASTUnit *TU = getCursorASTUnit(C);
4217 FileID MainID = TU->getSourceManager().getMainFileID();
4218 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4219 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4220 return SourceRange(Start, End);
4221 }
4222
4223 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004224 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004225 if (!D)
4226 return SourceRange();
4227
4228 SourceRange R = D->getSourceRange();
4229 // FIXME: Multiple variables declared in a single declaration
4230 // currently lack the information needed to correctly determine their
4231 // ranges when accounting for the type-specifier. We use context
4232 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4233 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004234 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004235 if (!cxcursor::isFirstInDeclGroup(C))
4236 R.setBegin(VD->getLocation());
4237 }
4238 return R;
4239 }
4240 return SourceRange();
4241}
4242
4243/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4244/// the decl-specifier-seq for declarations.
4245static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4246 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004247 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004248 if (!D)
4249 return SourceRange();
4250
4251 SourceRange R = D->getSourceRange();
4252
4253 // Adjust the start of the location for declarations preceded by
4254 // declaration specifiers.
4255 SourceLocation StartLoc;
4256 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4257 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4258 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004259 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004260 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4261 StartLoc = TI->getTypeLoc().getLocStart();
4262 }
4263
4264 if (StartLoc.isValid() && R.getBegin().isValid() &&
4265 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4266 R.setBegin(StartLoc);
4267
4268 // FIXME: Multiple variables declared in a single declaration
4269 // currently lack the information needed to correctly determine their
4270 // ranges when accounting for the type-specifier. We use context
4271 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4272 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004273 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004274 if (!cxcursor::isFirstInDeclGroup(C))
4275 R.setBegin(VD->getLocation());
4276 }
4277
4278 return R;
4279 }
4280
4281 return getRawCursorExtent(C);
4282}
4283
4284extern "C" {
4285
4286CXSourceRange clang_getCursorExtent(CXCursor C) {
4287 SourceRange R = getRawCursorExtent(C);
4288 if (R.isInvalid())
4289 return clang_getNullRange();
4290
4291 return cxloc::translateSourceRange(getCursorContext(C), R);
4292}
4293
4294CXCursor clang_getCursorReferenced(CXCursor C) {
4295 if (clang_isInvalid(C.kind))
4296 return clang_getNullCursor();
4297
4298 CXTranslationUnit tu = getCursorTU(C);
4299 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004300 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004301 if (!D)
4302 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004303 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004304 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004305 if (const ObjCPropertyImplDecl *PropImpl =
4306 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004307 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4308 return MakeCXCursor(Property, tu);
4309
4310 return C;
4311 }
4312
4313 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004314 const Expr *E = getCursorExpr(C);
4315 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004316 if (D) {
4317 CXCursor declCursor = MakeCXCursor(D, tu);
4318 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4319 declCursor);
4320 return declCursor;
4321 }
4322
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004323 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004324 return MakeCursorOverloadedDeclRef(Ovl, tu);
4325
4326 return clang_getNullCursor();
4327 }
4328
4329 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004330 const Stmt *S = getCursorStmt(C);
4331 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004332 if (LabelDecl *label = Goto->getLabel())
4333 if (LabelStmt *labelS = label->getStmt())
4334 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4335
4336 return clang_getNullCursor();
4337 }
4338
4339 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004340 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004341 return MakeMacroDefinitionCursor(Def, tu);
4342 }
4343
4344 if (!clang_isReference(C.kind))
4345 return clang_getNullCursor();
4346
4347 switch (C.kind) {
4348 case CXCursor_ObjCSuperClassRef:
4349 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4350
4351 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004352 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4353 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004354 return MakeCXCursor(Def, tu);
4355
4356 return MakeCXCursor(Prot, tu);
4357 }
4358
4359 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004360 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4361 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004362 return MakeCXCursor(Def, tu);
4363
4364 return MakeCXCursor(Class, tu);
4365 }
4366
4367 case CXCursor_TypeRef:
4368 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4369
4370 case CXCursor_TemplateRef:
4371 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4372
4373 case CXCursor_NamespaceRef:
4374 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4375
4376 case CXCursor_MemberRef:
4377 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4378
4379 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004380 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004381 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4382 tu ));
4383 }
4384
4385 case CXCursor_LabelRef:
4386 // FIXME: We end up faking the "parent" declaration here because we
4387 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004388 return MakeCXCursor(getCursorLabelRef(C).first,
4389 cxtu::getASTUnit(tu)->getASTContext()
4390 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004391 tu);
4392
4393 case CXCursor_OverloadedDeclRef:
4394 return C;
4395
4396 case CXCursor_VariableRef:
4397 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4398
4399 default:
4400 // We would prefer to enumerate all non-reference cursor kinds here.
4401 llvm_unreachable("Unhandled reference cursor kind");
4402 }
4403}
4404
4405CXCursor clang_getCursorDefinition(CXCursor C) {
4406 if (clang_isInvalid(C.kind))
4407 return clang_getNullCursor();
4408
4409 CXTranslationUnit TU = getCursorTU(C);
4410
4411 bool WasReference = false;
4412 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4413 C = clang_getCursorReferenced(C);
4414 WasReference = true;
4415 }
4416
4417 if (C.kind == CXCursor_MacroExpansion)
4418 return clang_getCursorReferenced(C);
4419
4420 if (!clang_isDeclaration(C.kind))
4421 return clang_getNullCursor();
4422
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004423 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004424 if (!D)
4425 return clang_getNullCursor();
4426
4427 switch (D->getKind()) {
4428 // Declaration kinds that don't really separate the notions of
4429 // declaration and definition.
4430 case Decl::Namespace:
4431 case Decl::Typedef:
4432 case Decl::TypeAlias:
4433 case Decl::TypeAliasTemplate:
4434 case Decl::TemplateTypeParm:
4435 case Decl::EnumConstant:
4436 case Decl::Field:
4437 case Decl::IndirectField:
4438 case Decl::ObjCIvar:
4439 case Decl::ObjCAtDefsField:
4440 case Decl::ImplicitParam:
4441 case Decl::ParmVar:
4442 case Decl::NonTypeTemplateParm:
4443 case Decl::TemplateTemplateParm:
4444 case Decl::ObjCCategoryImpl:
4445 case Decl::ObjCImplementation:
4446 case Decl::AccessSpec:
4447 case Decl::LinkageSpec:
4448 case Decl::ObjCPropertyImpl:
4449 case Decl::FileScopeAsm:
4450 case Decl::StaticAssert:
4451 case Decl::Block:
4452 case Decl::Label: // FIXME: Is this right??
4453 case Decl::ClassScopeFunctionSpecialization:
4454 case Decl::Import:
4455 return C;
4456
4457 // Declaration kinds that don't make any sense here, but are
4458 // nonetheless harmless.
4459 case Decl::TranslationUnit:
4460 break;
4461
4462 // Declaration kinds for which the definition is not resolvable.
4463 case Decl::UnresolvedUsingTypename:
4464 case Decl::UnresolvedUsingValue:
4465 break;
4466
4467 case Decl::UsingDirective:
4468 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4469 TU);
4470
4471 case Decl::NamespaceAlias:
4472 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4473
4474 case Decl::Enum:
4475 case Decl::Record:
4476 case Decl::CXXRecord:
4477 case Decl::ClassTemplateSpecialization:
4478 case Decl::ClassTemplatePartialSpecialization:
4479 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4480 return MakeCXCursor(Def, TU);
4481 return clang_getNullCursor();
4482
4483 case Decl::Function:
4484 case Decl::CXXMethod:
4485 case Decl::CXXConstructor:
4486 case Decl::CXXDestructor:
4487 case Decl::CXXConversion: {
4488 const FunctionDecl *Def = 0;
4489 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004490 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004491 return clang_getNullCursor();
4492 }
4493
4494 case Decl::Var: {
4495 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004496 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004497 return MakeCXCursor(Def, TU);
4498 return clang_getNullCursor();
4499 }
4500
4501 case Decl::FunctionTemplate: {
4502 const FunctionDecl *Def = 0;
4503 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4504 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4505 return clang_getNullCursor();
4506 }
4507
4508 case Decl::ClassTemplate: {
4509 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4510 ->getDefinition())
4511 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4512 TU);
4513 return clang_getNullCursor();
4514 }
4515
4516 case Decl::Using:
4517 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4518 D->getLocation(), TU);
4519
4520 case Decl::UsingShadow:
4521 return clang_getCursorDefinition(
4522 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4523 TU));
4524
4525 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004526 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004527 if (Method->isThisDeclarationADefinition())
4528 return C;
4529
4530 // Dig out the method definition in the associated
4531 // @implementation, if we have it.
4532 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004533 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004534 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4535 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4536 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4537 Method->isInstanceMethod()))
4538 if (Def->isThisDeclarationADefinition())
4539 return MakeCXCursor(Def, TU);
4540
4541 return clang_getNullCursor();
4542 }
4543
4544 case Decl::ObjCCategory:
4545 if (ObjCCategoryImplDecl *Impl
4546 = cast<ObjCCategoryDecl>(D)->getImplementation())
4547 return MakeCXCursor(Impl, TU);
4548 return clang_getNullCursor();
4549
4550 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004551 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004552 return MakeCXCursor(Def, TU);
4553 return clang_getNullCursor();
4554
4555 case Decl::ObjCInterface: {
4556 // There are two notions of a "definition" for an Objective-C
4557 // class: the interface and its implementation. When we resolved a
4558 // reference to an Objective-C class, produce the @interface as
4559 // the definition; when we were provided with the interface,
4560 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004561 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004562 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004563 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004564 return MakeCXCursor(Def, TU);
4565 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4566 return MakeCXCursor(Impl, TU);
4567 return clang_getNullCursor();
4568 }
4569
4570 case Decl::ObjCProperty:
4571 // FIXME: We don't really know where to find the
4572 // ObjCPropertyImplDecls that implement this property.
4573 return clang_getNullCursor();
4574
4575 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004576 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004577 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004578 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004579 return MakeCXCursor(Def, TU);
4580
4581 return clang_getNullCursor();
4582
4583 case Decl::Friend:
4584 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4585 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4586 return clang_getNullCursor();
4587
4588 case Decl::FriendTemplate:
4589 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4590 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4591 return clang_getNullCursor();
4592 }
4593
4594 return clang_getNullCursor();
4595}
4596
4597unsigned clang_isCursorDefinition(CXCursor C) {
4598 if (!clang_isDeclaration(C.kind))
4599 return 0;
4600
4601 return clang_getCursorDefinition(C) == C;
4602}
4603
4604CXCursor clang_getCanonicalCursor(CXCursor C) {
4605 if (!clang_isDeclaration(C.kind))
4606 return C;
4607
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004608 if (const Decl *D = getCursorDecl(C)) {
4609 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004610 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4611 return MakeCXCursor(CatD, getCursorTU(C));
4612
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004613 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4614 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004615 return MakeCXCursor(IFD, getCursorTU(C));
4616
4617 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4618 }
4619
4620 return C;
4621}
4622
4623int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4624 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4625}
4626
4627unsigned clang_getNumOverloadedDecls(CXCursor C) {
4628 if (C.kind != CXCursor_OverloadedDeclRef)
4629 return 0;
4630
4631 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004632 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004633 return E->getNumDecls();
4634
4635 if (OverloadedTemplateStorage *S
4636 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4637 return S->size();
4638
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004639 const Decl *D = Storage.get<const Decl *>();
4640 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004641 return Using->shadow_size();
4642
4643 return 0;
4644}
4645
4646CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4647 if (cursor.kind != CXCursor_OverloadedDeclRef)
4648 return clang_getNullCursor();
4649
4650 if (index >= clang_getNumOverloadedDecls(cursor))
4651 return clang_getNullCursor();
4652
4653 CXTranslationUnit TU = getCursorTU(cursor);
4654 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004655 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004656 return MakeCXCursor(E->decls_begin()[index], TU);
4657
4658 if (OverloadedTemplateStorage *S
4659 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4660 return MakeCXCursor(S->begin()[index], TU);
4661
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004662 const Decl *D = Storage.get<const Decl *>();
4663 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004664 // FIXME: This is, unfortunately, linear time.
4665 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4666 std::advance(Pos, index);
4667 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4668 }
4669
4670 return clang_getNullCursor();
4671}
4672
4673void clang_getDefinitionSpellingAndExtent(CXCursor C,
4674 const char **startBuf,
4675 const char **endBuf,
4676 unsigned *startLine,
4677 unsigned *startColumn,
4678 unsigned *endLine,
4679 unsigned *endColumn) {
4680 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004681 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004682 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4683
4684 SourceManager &SM = FD->getASTContext().getSourceManager();
4685 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4686 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4687 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4688 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4689 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4690 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4691}
4692
4693
4694CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4695 unsigned PieceIndex) {
4696 RefNamePieces Pieces;
4697
4698 switch (C.kind) {
4699 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004700 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004701 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4702 E->getQualifierLoc().getSourceRange());
4703 break;
4704
4705 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004706 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004707 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4708 E->getQualifierLoc().getSourceRange(),
4709 E->getOptionalExplicitTemplateArgs());
4710 break;
4711
4712 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004713 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004714 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004715 const Expr *Callee = OCE->getCallee();
4716 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004717 Callee = ICE->getSubExpr();
4718
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004719 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004720 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4721 DRE->getQualifierLoc().getSourceRange());
4722 }
4723 break;
4724
4725 default:
4726 break;
4727 }
4728
4729 if (Pieces.empty()) {
4730 if (PieceIndex == 0)
4731 return clang_getCursorExtent(C);
4732 } else if (PieceIndex < Pieces.size()) {
4733 SourceRange R = Pieces[PieceIndex];
4734 if (R.isValid())
4735 return cxloc::translateSourceRange(getCursorContext(C), R);
4736 }
4737
4738 return clang_getNullRange();
4739}
4740
4741void clang_enableStackTraces(void) {
4742 llvm::sys::PrintStackTraceOnErrorSignal();
4743}
4744
4745void clang_executeOnThread(void (*fn)(void*), void *user_data,
4746 unsigned stack_size) {
4747 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4748}
4749
4750} // end: extern "C"
4751
4752//===----------------------------------------------------------------------===//
4753// Token-based Operations.
4754//===----------------------------------------------------------------------===//
4755
4756/* CXToken layout:
4757 * int_data[0]: a CXTokenKind
4758 * int_data[1]: starting token location
4759 * int_data[2]: token length
4760 * int_data[3]: reserved
4761 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4762 * otherwise unused.
4763 */
4764extern "C" {
4765
4766CXTokenKind clang_getTokenKind(CXToken CXTok) {
4767 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4768}
4769
4770CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4771 switch (clang_getTokenKind(CXTok)) {
4772 case CXToken_Identifier:
4773 case CXToken_Keyword:
4774 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004775 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004776 ->getNameStart());
4777
4778 case CXToken_Literal: {
4779 // We have stashed the starting pointer in the ptr_data field. Use it.
4780 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004781 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004782 }
4783
4784 case CXToken_Punctuation:
4785 case CXToken_Comment:
4786 break;
4787 }
4788
4789 // We have to find the starting buffer pointer the hard way, by
4790 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004791 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004792 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004793 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004794
4795 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4796 std::pair<FileID, unsigned> LocInfo
4797 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4798 bool Invalid = false;
4799 StringRef Buffer
4800 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4801 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004802 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004803
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004804 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004805}
4806
4807CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004808 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004809 if (!CXXUnit)
4810 return clang_getNullLocation();
4811
4812 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4813 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4814}
4815
4816CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004817 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004818 if (!CXXUnit)
4819 return clang_getNullRange();
4820
4821 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4822 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4823}
4824
4825static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4826 SmallVectorImpl<CXToken> &CXTokens) {
4827 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4828 std::pair<FileID, unsigned> BeginLocInfo
4829 = SourceMgr.getDecomposedLoc(Range.getBegin());
4830 std::pair<FileID, unsigned> EndLocInfo
4831 = SourceMgr.getDecomposedLoc(Range.getEnd());
4832
4833 // Cannot tokenize across files.
4834 if (BeginLocInfo.first != EndLocInfo.first)
4835 return;
4836
4837 // Create a lexer
4838 bool Invalid = false;
4839 StringRef Buffer
4840 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4841 if (Invalid)
4842 return;
4843
4844 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4845 CXXUnit->getASTContext().getLangOpts(),
4846 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4847 Lex.SetCommentRetentionState(true);
4848
4849 // Lex tokens until we hit the end of the range.
4850 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4851 Token Tok;
4852 bool previousWasAt = false;
4853 do {
4854 // Lex the next token
4855 Lex.LexFromRawLexer(Tok);
4856 if (Tok.is(tok::eof))
4857 break;
4858
4859 // Initialize the CXToken.
4860 CXToken CXTok;
4861
4862 // - Common fields
4863 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4864 CXTok.int_data[2] = Tok.getLength();
4865 CXTok.int_data[3] = 0;
4866
4867 // - Kind-specific fields
4868 if (Tok.isLiteral()) {
4869 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004870 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004871 } else if (Tok.is(tok::raw_identifier)) {
4872 // Lookup the identifier to determine whether we have a keyword.
4873 IdentifierInfo *II
4874 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4875
4876 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4877 CXTok.int_data[0] = CXToken_Keyword;
4878 }
4879 else {
4880 CXTok.int_data[0] = Tok.is(tok::identifier)
4881 ? CXToken_Identifier
4882 : CXToken_Keyword;
4883 }
4884 CXTok.ptr_data = II;
4885 } else if (Tok.is(tok::comment)) {
4886 CXTok.int_data[0] = CXToken_Comment;
4887 CXTok.ptr_data = 0;
4888 } else {
4889 CXTok.int_data[0] = CXToken_Punctuation;
4890 CXTok.ptr_data = 0;
4891 }
4892 CXTokens.push_back(CXTok);
4893 previousWasAt = Tok.is(tok::at);
4894 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4895}
4896
4897void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4898 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004899 LOG_FUNC_SECTION {
4900 *Log << TU << ' ' << Range;
4901 }
4902
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004903 if (Tokens)
4904 *Tokens = 0;
4905 if (NumTokens)
4906 *NumTokens = 0;
4907
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004908 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004909 if (!CXXUnit || !Tokens || !NumTokens)
4910 return;
4911
4912 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4913
4914 SourceRange R = cxloc::translateCXSourceRange(Range);
4915 if (R.isInvalid())
4916 return;
4917
4918 SmallVector<CXToken, 32> CXTokens;
4919 getTokens(CXXUnit, R, CXTokens);
4920
4921 if (CXTokens.empty())
4922 return;
4923
4924 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4925 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4926 *NumTokens = CXTokens.size();
4927}
4928
4929void clang_disposeTokens(CXTranslationUnit TU,
4930 CXToken *Tokens, unsigned NumTokens) {
4931 free(Tokens);
4932}
4933
4934} // end: extern "C"
4935
4936//===----------------------------------------------------------------------===//
4937// Token annotation APIs.
4938//===----------------------------------------------------------------------===//
4939
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004940static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4941 CXCursor parent,
4942 CXClientData client_data);
4943static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4944 CXClientData client_data);
4945
4946namespace {
4947class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004948 CXToken *Tokens;
4949 CXCursor *Cursors;
4950 unsigned NumTokens;
4951 unsigned TokIdx;
4952 unsigned PreprocessingTokIdx;
4953 CursorVisitor AnnotateVis;
4954 SourceManager &SrcMgr;
4955 bool HasContextSensitiveKeywords;
4956
4957 struct PostChildrenInfo {
4958 CXCursor Cursor;
4959 SourceRange CursorRange;
4960 unsigned BeforeChildrenTokenIdx;
4961 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004962 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004963
4964 bool MoreTokens() const { return TokIdx < NumTokens; }
4965 unsigned NextToken() const { return TokIdx; }
4966 void AdvanceToken() { ++TokIdx; }
4967 SourceLocation GetTokenLoc(unsigned tokI) {
4968 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4969 }
4970 bool isFunctionMacroToken(unsigned tokI) const {
4971 return Tokens[tokI].int_data[3] != 0;
4972 }
4973 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4974 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4975 }
4976
4977 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
4978 void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
4979 SourceRange);
4980
4981public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004982 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004983 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004984 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004985 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004986 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004987 AnnotateTokensVisitor, this,
4988 /*VisitPreprocessorLast=*/true,
4989 /*VisitIncludedEntities=*/false,
4990 RegionOfInterest,
4991 /*VisitDeclsOnly=*/false,
4992 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004993 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004994 HasContextSensitiveKeywords(false) { }
4995
4996 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
4997 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
4998 bool postVisitChildren(CXCursor cursor);
4999 void AnnotateTokens();
5000
5001 /// \brief Determine whether the annotator saw any cursors that have
5002 /// context-sensitive keywords.
5003 bool hasContextSensitiveKeywords() const {
5004 return HasContextSensitiveKeywords;
5005 }
5006
5007 ~AnnotateTokensWorker() {
5008 assert(PostChildrenInfos.empty());
5009 }
5010};
5011}
5012
5013void AnnotateTokensWorker::AnnotateTokens() {
5014 // Walk the AST within the region of interest, annotating tokens
5015 // along the way.
5016 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005017}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005018
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005019static inline void updateCursorAnnotation(CXCursor &Cursor,
5020 const CXCursor &updateC) {
5021 if (clang_isInvalid(updateC.kind) || clang_isPreprocessing(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005022 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005023 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005024}
5025
5026/// \brief It annotates and advances tokens with a cursor until the comparison
5027//// between the cursor location and the source range is the same as
5028/// \arg compResult.
5029///
5030/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5031/// Pass RangeOverlap to annotate tokens inside a range.
5032void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5033 RangeComparisonResult compResult,
5034 SourceRange range) {
5035 while (MoreTokens()) {
5036 const unsigned I = NextToken();
5037 if (isFunctionMacroToken(I))
5038 return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
5039
5040 SourceLocation TokLoc = GetTokenLoc(I);
5041 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005042 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005043 AdvanceToken();
5044 continue;
5045 }
5046 break;
5047 }
5048}
5049
5050/// \brief Special annotation handling for macro argument tokens.
5051void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
5052 CXCursor updateC,
5053 RangeComparisonResult compResult,
5054 SourceRange range) {
5055 assert(MoreTokens());
5056 assert(isFunctionMacroToken(NextToken()) &&
5057 "Should be called only for macro arg tokens");
5058
5059 // This works differently than annotateAndAdvanceTokens; because expanded
5060 // macro arguments can have arbitrary translation-unit source order, we do not
5061 // advance the token index one by one until a token fails the range test.
5062 // We only advance once past all of the macro arg tokens if all of them
5063 // pass the range test. If one of them fails we keep the token index pointing
5064 // at the start of the macro arg tokens so that the failing token will be
5065 // annotated by a subsequent annotation try.
5066
5067 bool atLeastOneCompFail = false;
5068
5069 unsigned I = NextToken();
5070 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5071 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5072 if (TokLoc.isFileID())
5073 continue; // not macro arg token, it's parens or comma.
5074 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5075 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5076 Cursors[I] = updateC;
5077 } else
5078 atLeastOneCompFail = true;
5079 }
5080
5081 if (!atLeastOneCompFail)
5082 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5083}
5084
5085enum CXChildVisitResult
5086AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005087 SourceRange cursorRange = getRawCursorExtent(cursor);
5088 if (cursorRange.isInvalid())
5089 return CXChildVisit_Recurse;
5090
5091 if (!HasContextSensitiveKeywords) {
5092 // Objective-C properties can have context-sensitive keywords.
5093 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005094 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005095 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5096 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5097 }
5098 // Objective-C methods can have context-sensitive keywords.
5099 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5100 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005101 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005102 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5103 if (Method->getObjCDeclQualifier())
5104 HasContextSensitiveKeywords = true;
5105 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005106 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5107 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005108 P != PEnd; ++P) {
5109 if ((*P)->getObjCDeclQualifier()) {
5110 HasContextSensitiveKeywords = true;
5111 break;
5112 }
5113 }
5114 }
5115 }
5116 }
5117 // C++ methods can have context-sensitive keywords.
5118 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005119 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005120 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5121 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5122 HasContextSensitiveKeywords = true;
5123 }
5124 }
5125 // C++ classes can have context-sensitive keywords.
5126 else if (cursor.kind == CXCursor_StructDecl ||
5127 cursor.kind == CXCursor_ClassDecl ||
5128 cursor.kind == CXCursor_ClassTemplate ||
5129 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005130 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005131 if (D->hasAttr<FinalAttr>())
5132 HasContextSensitiveKeywords = true;
5133 }
5134 }
5135
5136 if (clang_isPreprocessing(cursor.kind)) {
5137 // Items in the preprocessing record are kept separate from items in
5138 // declarations, so we keep a separate token index.
5139 unsigned SavedTokIdx = TokIdx;
5140 TokIdx = PreprocessingTokIdx;
5141
5142 // Skip tokens up until we catch up to the beginning of the preprocessing
5143 // entry.
5144 while (MoreTokens()) {
5145 const unsigned I = NextToken();
5146 SourceLocation TokLoc = GetTokenLoc(I);
5147 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5148 case RangeBefore:
5149 AdvanceToken();
5150 continue;
5151 case RangeAfter:
5152 case RangeOverlap:
5153 break;
5154 }
5155 break;
5156 }
5157
5158 // Look at all of the tokens within this range.
5159 while (MoreTokens()) {
5160 const unsigned I = NextToken();
5161 SourceLocation TokLoc = GetTokenLoc(I);
5162 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5163 case RangeBefore:
5164 llvm_unreachable("Infeasible");
5165 case RangeAfter:
5166 break;
5167 case RangeOverlap:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005168 // We may have already annotated macro names inside macro definitions.
5169 if (Cursors[I].kind != CXCursor_MacroExpansion)
5170 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005171 AdvanceToken();
5172 // For macro expansions, just note where the beginning of the macro
5173 // expansion occurs.
5174 if (cursor.kind == CXCursor_MacroExpansion)
5175 break;
5176 continue;
5177 }
5178 break;
5179 }
5180
5181 // Save the preprocessing token index; restore the non-preprocessing
5182 // token index.
5183 PreprocessingTokIdx = TokIdx;
5184 TokIdx = SavedTokIdx;
5185 return CXChildVisit_Recurse;
5186 }
5187
5188 if (cursorRange.isInvalid())
5189 return CXChildVisit_Continue;
5190
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005191 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005192 const enum CXCursorKind K = clang_getCursorKind(parent);
5193 const CXCursor updateC =
5194 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
5195 ? clang_getNullCursor() : parent;
5196
5197 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5198
5199 // Avoid having the cursor of an expression "overwrite" the annotation of the
5200 // variable declaration that it belongs to.
5201 // This can happen for C++ constructor expressions whose range generally
5202 // include the variable declaration, e.g.:
5203 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5204 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005205 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005206 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005207 const unsigned I = NextToken();
5208 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5209 E->getLocStart() == D->getLocation() &&
5210 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005211 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005212 AdvanceToken();
5213 }
5214 }
5215 }
5216
5217 // Before recursing into the children keep some state that we are going
5218 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5219 // extra work after the child nodes are visited.
5220 // Note that we don't call VisitChildren here to avoid traversing statements
5221 // code-recursively which can blow the stack.
5222
5223 PostChildrenInfo Info;
5224 Info.Cursor = cursor;
5225 Info.CursorRange = cursorRange;
5226 Info.BeforeChildrenTokenIdx = NextToken();
5227 PostChildrenInfos.push_back(Info);
5228
5229 return CXChildVisit_Recurse;
5230}
5231
5232bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5233 if (PostChildrenInfos.empty())
5234 return false;
5235 const PostChildrenInfo &Info = PostChildrenInfos.back();
5236 if (!clang_equalCursors(Info.Cursor, cursor))
5237 return false;
5238
5239 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5240 const unsigned AfterChildren = NextToken();
5241 SourceRange cursorRange = Info.CursorRange;
5242
5243 // Scan the tokens that are at the end of the cursor, but are not captured
5244 // but the child cursors.
5245 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5246
5247 // Scan the tokens that are at the beginning of the cursor, but are not
5248 // capture by the child cursors.
5249 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5250 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5251 break;
5252
5253 Cursors[I] = cursor;
5254 }
5255
5256 PostChildrenInfos.pop_back();
5257 return false;
5258}
5259
5260static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5261 CXCursor parent,
5262 CXClientData client_data) {
5263 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5264}
5265
5266static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5267 CXClientData client_data) {
5268 return static_cast<AnnotateTokensWorker*>(client_data)->
5269 postVisitChildren(cursor);
5270}
5271
5272namespace {
5273
5274/// \brief Uses the macro expansions in the preprocessing record to find
5275/// and mark tokens that are macro arguments. This info is used by the
5276/// AnnotateTokensWorker.
5277class MarkMacroArgTokensVisitor {
5278 SourceManager &SM;
5279 CXToken *Tokens;
5280 unsigned NumTokens;
5281 unsigned CurIdx;
5282
5283public:
5284 MarkMacroArgTokensVisitor(SourceManager &SM,
5285 CXToken *tokens, unsigned numTokens)
5286 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5287
5288 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5289 if (cursor.kind != CXCursor_MacroExpansion)
5290 return CXChildVisit_Continue;
5291
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005292 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005293 if (macroRange.getBegin() == macroRange.getEnd())
5294 return CXChildVisit_Continue; // it's not a function macro.
5295
5296 for (; CurIdx < NumTokens; ++CurIdx) {
5297 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5298 macroRange.getBegin()))
5299 break;
5300 }
5301
5302 if (CurIdx == NumTokens)
5303 return CXChildVisit_Break;
5304
5305 for (; CurIdx < NumTokens; ++CurIdx) {
5306 SourceLocation tokLoc = getTokenLoc(CurIdx);
5307 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5308 break;
5309
5310 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5311 }
5312
5313 if (CurIdx == NumTokens)
5314 return CXChildVisit_Break;
5315
5316 return CXChildVisit_Continue;
5317 }
5318
5319private:
5320 SourceLocation getTokenLoc(unsigned tokI) {
5321 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5322 }
5323
5324 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5325 // The third field is reserved and currently not used. Use it here
5326 // to mark macro arg expanded tokens with their expanded locations.
5327 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5328 }
5329};
5330
5331} // end anonymous namespace
5332
5333static CXChildVisitResult
5334MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5335 CXClientData client_data) {
5336 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5337 parent);
5338}
5339
5340namespace {
5341 struct clang_annotateTokens_Data {
5342 CXTranslationUnit TU;
5343 ASTUnit *CXXUnit;
5344 CXToken *Tokens;
5345 unsigned NumTokens;
5346 CXCursor *Cursors;
5347 };
5348}
5349
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005350/// \brief Used by \c annotatePreprocessorTokens.
5351/// \returns true if lexing was finished, false otherwise.
5352static bool lexNext(Lexer &Lex, Token &Tok,
5353 unsigned &NextIdx, unsigned NumTokens) {
5354 if (NextIdx >= NumTokens)
5355 return true;
5356
5357 ++NextIdx;
5358 Lex.LexFromRawLexer(Tok);
5359 if (Tok.is(tok::eof))
5360 return true;
5361
5362 return false;
5363}
5364
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005365static void annotatePreprocessorTokens(CXTranslationUnit TU,
5366 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005367 CXCursor *Cursors,
5368 CXToken *Tokens,
5369 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005370 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005371
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005372 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005373 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5374 std::pair<FileID, unsigned> BeginLocInfo
5375 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
5376 std::pair<FileID, unsigned> EndLocInfo
5377 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
5378
5379 if (BeginLocInfo.first != EndLocInfo.first)
5380 return;
5381
5382 StringRef Buffer;
5383 bool Invalid = false;
5384 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5385 if (Buffer.empty() || Invalid)
5386 return;
5387
5388 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5389 CXXUnit->getASTContext().getLangOpts(),
5390 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5391 Buffer.end());
5392 Lex.SetCommentRetentionState(true);
5393
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005394 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005395 // Lex tokens in raw mode until we hit the end of the range, to avoid
5396 // entering #includes or expanding macros.
5397 while (true) {
5398 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005399 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5400 break;
5401 unsigned TokIdx = NextIdx-1;
5402 assert(Tok.getLocation() ==
5403 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005404
5405 reprocess:
5406 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005407 // We have found a preprocessing directive. Annotate the tokens
5408 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005409 //
5410 // FIXME: Some simple tests here could identify macro definitions and
5411 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005412
5413 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005414 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5415 break;
5416
5417 MacroInfo *MI = 0;
5418 if (Tok.is(tok::raw_identifier) &&
5419 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5420 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5421 break;
5422
5423 if (Tok.is(tok::raw_identifier)) {
5424 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5425 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5426 SourceLocation MappedTokLoc =
5427 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5428 MI = getMacroInfo(II, MappedTokLoc, TU);
5429 }
5430 }
5431
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005432 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005433 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005434 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5435 finished = true;
5436 break;
5437 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005438 // If we are in a macro definition, check if the token was ever a
5439 // macro name and annotate it if that's the case.
5440 if (MI) {
5441 SourceLocation SaveLoc = Tok.getLocation();
5442 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5443 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5444 Tok.setLocation(SaveLoc);
5445 if (MacroDef)
5446 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5447 Tok.getLocation(), TU);
5448 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005449 } while (!Tok.isAtStartOfLine());
5450
5451 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5452 assert(TokIdx <= LastIdx);
5453 SourceLocation EndLoc =
5454 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5455 CXCursor Cursor =
5456 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5457
5458 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005459 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005460
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005461 if (finished)
5462 break;
5463 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005464 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005465 }
5466}
5467
5468// This gets run a separate thread to avoid stack blowout.
5469static void clang_annotateTokensImpl(void *UserData) {
5470 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5471 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5472 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5473 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5474 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5475
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005476 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005477 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5478 setThreadBackgroundPriority();
5479
5480 // Determine the region of interest, which contains all of the tokens.
5481 SourceRange RegionOfInterest;
5482 RegionOfInterest.setBegin(
5483 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5484 RegionOfInterest.setEnd(
5485 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5486 Tokens[NumTokens-1])));
5487
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005488 // Relex the tokens within the source range to look for preprocessing
5489 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005490 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005491
5492 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5493 // Search and mark tokens that are macro argument expansions.
5494 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5495 Tokens, NumTokens);
5496 CursorVisitor MacroArgMarker(TU,
5497 MarkMacroArgTokensVisitorDelegate, &Visitor,
5498 /*VisitPreprocessorLast=*/true,
5499 /*VisitIncludedEntities=*/false,
5500 RegionOfInterest);
5501 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5502 }
5503
5504 // Annotate all of the source locations in the region of interest that map to
5505 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005506 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005507
5508 // FIXME: We use a ridiculous stack size here because the data-recursion
5509 // algorithm uses a large stack frame than the non-data recursive version,
5510 // and AnnotationTokensWorker currently transforms the data-recursion
5511 // algorithm back into a traditional recursion by explicitly calling
5512 // VisitChildren(). We will need to remove this explicit recursive call.
5513 W.AnnotateTokens();
5514
5515 // If we ran into any entities that involve context-sensitive keywords,
5516 // take another pass through the tokens to mark them as such.
5517 if (W.hasContextSensitiveKeywords()) {
5518 for (unsigned I = 0; I != NumTokens; ++I) {
5519 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5520 continue;
5521
5522 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5523 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005524 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005525 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5526 if (Property->getPropertyAttributesAsWritten() != 0 &&
5527 llvm::StringSwitch<bool>(II->getName())
5528 .Case("readonly", true)
5529 .Case("assign", true)
5530 .Case("unsafe_unretained", true)
5531 .Case("readwrite", true)
5532 .Case("retain", true)
5533 .Case("copy", true)
5534 .Case("nonatomic", true)
5535 .Case("atomic", true)
5536 .Case("getter", true)
5537 .Case("setter", true)
5538 .Case("strong", true)
5539 .Case("weak", true)
5540 .Default(false))
5541 Tokens[I].int_data[0] = CXToken_Keyword;
5542 }
5543 continue;
5544 }
5545
5546 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5547 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5548 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5549 if (llvm::StringSwitch<bool>(II->getName())
5550 .Case("in", true)
5551 .Case("out", true)
5552 .Case("inout", true)
5553 .Case("oneway", true)
5554 .Case("bycopy", true)
5555 .Case("byref", true)
5556 .Default(false))
5557 Tokens[I].int_data[0] = CXToken_Keyword;
5558 continue;
5559 }
5560
5561 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5562 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5563 Tokens[I].int_data[0] = CXToken_Keyword;
5564 continue;
5565 }
5566 }
5567 }
5568}
5569
5570extern "C" {
5571
5572void clang_annotateTokens(CXTranslationUnit TU,
5573 CXToken *Tokens, unsigned NumTokens,
5574 CXCursor *Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005575 if (NumTokens == 0 || !Tokens || !Cursors) {
5576 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005577 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005578 }
5579
5580 LOG_FUNC_SECTION {
5581 *Log << TU << ' ';
5582 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5583 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5584 *Log << clang_getRange(bloc, eloc);
5585 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005586
5587 // Any token we don't specifically annotate will have a NULL cursor.
5588 CXCursor C = clang_getNullCursor();
5589 for (unsigned I = 0; I != NumTokens; ++I)
5590 Cursors[I] = C;
5591
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005592 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005593 if (!CXXUnit)
5594 return;
5595
5596 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5597
5598 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5599 llvm::CrashRecoveryContext CRC;
5600 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5601 GetSafetyThreadStackSize() * 2)) {
5602 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5603 }
5604}
5605
5606} // end: extern "C"
5607
5608//===----------------------------------------------------------------------===//
5609// Operations for querying linkage of a cursor.
5610//===----------------------------------------------------------------------===//
5611
5612extern "C" {
5613CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5614 if (!clang_isDeclaration(cursor.kind))
5615 return CXLinkage_Invalid;
5616
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005617 const Decl *D = cxcursor::getCursorDecl(cursor);
5618 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005619 switch (ND->getLinkage()) {
5620 case NoLinkage: return CXLinkage_NoLinkage;
5621 case InternalLinkage: return CXLinkage_Internal;
5622 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5623 case ExternalLinkage: return CXLinkage_External;
5624 };
5625
5626 return CXLinkage_Invalid;
5627}
5628} // end: extern "C"
5629
5630//===----------------------------------------------------------------------===//
5631// Operations for querying language of a cursor.
5632//===----------------------------------------------------------------------===//
5633
5634static CXLanguageKind getDeclLanguage(const Decl *D) {
5635 if (!D)
5636 return CXLanguage_C;
5637
5638 switch (D->getKind()) {
5639 default:
5640 break;
5641 case Decl::ImplicitParam:
5642 case Decl::ObjCAtDefsField:
5643 case Decl::ObjCCategory:
5644 case Decl::ObjCCategoryImpl:
5645 case Decl::ObjCCompatibleAlias:
5646 case Decl::ObjCImplementation:
5647 case Decl::ObjCInterface:
5648 case Decl::ObjCIvar:
5649 case Decl::ObjCMethod:
5650 case Decl::ObjCProperty:
5651 case Decl::ObjCPropertyImpl:
5652 case Decl::ObjCProtocol:
5653 return CXLanguage_ObjC;
5654 case Decl::CXXConstructor:
5655 case Decl::CXXConversion:
5656 case Decl::CXXDestructor:
5657 case Decl::CXXMethod:
5658 case Decl::CXXRecord:
5659 case Decl::ClassTemplate:
5660 case Decl::ClassTemplatePartialSpecialization:
5661 case Decl::ClassTemplateSpecialization:
5662 case Decl::Friend:
5663 case Decl::FriendTemplate:
5664 case Decl::FunctionTemplate:
5665 case Decl::LinkageSpec:
5666 case Decl::Namespace:
5667 case Decl::NamespaceAlias:
5668 case Decl::NonTypeTemplateParm:
5669 case Decl::StaticAssert:
5670 case Decl::TemplateTemplateParm:
5671 case Decl::TemplateTypeParm:
5672 case Decl::UnresolvedUsingTypename:
5673 case Decl::UnresolvedUsingValue:
5674 case Decl::Using:
5675 case Decl::UsingDirective:
5676 case Decl::UsingShadow:
5677 return CXLanguage_CPlusPlus;
5678 }
5679
5680 return CXLanguage_C;
5681}
5682
5683extern "C" {
5684
5685enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5686 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005687 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005688 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5689 return CXAvailability_Available;
5690
5691 switch (D->getAvailability()) {
5692 case AR_Available:
5693 case AR_NotYetIntroduced:
5694 return CXAvailability_Available;
5695
5696 case AR_Deprecated:
5697 return CXAvailability_Deprecated;
5698
5699 case AR_Unavailable:
5700 return CXAvailability_NotAvailable;
5701 }
5702 }
5703
5704 return CXAvailability_Available;
5705}
5706
5707static CXVersion convertVersion(VersionTuple In) {
5708 CXVersion Out = { -1, -1, -1 };
5709 if (In.empty())
5710 return Out;
5711
5712 Out.Major = In.getMajor();
5713
5714 if (llvm::Optional<unsigned> Minor = In.getMinor())
5715 Out.Minor = *Minor;
5716 else
5717 return Out;
5718
5719 if (llvm::Optional<unsigned> Subminor = In.getSubminor())
5720 Out.Subminor = *Subminor;
5721
5722 return Out;
5723}
5724
5725int clang_getCursorPlatformAvailability(CXCursor cursor,
5726 int *always_deprecated,
5727 CXString *deprecated_message,
5728 int *always_unavailable,
5729 CXString *unavailable_message,
5730 CXPlatformAvailability *availability,
5731 int availability_size) {
5732 if (always_deprecated)
5733 *always_deprecated = 0;
5734 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005735 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005736 if (always_unavailable)
5737 *always_unavailable = 0;
5738 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005739 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005740
5741 if (!clang_isDeclaration(cursor.kind))
5742 return 0;
5743
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005744 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005745 if (!D)
5746 return 0;
5747
5748 int N = 0;
5749 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5750 ++A) {
5751 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5752 if (always_deprecated)
5753 *always_deprecated = 1;
5754 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005755 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005756 continue;
5757 }
5758
5759 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5760 if (always_unavailable)
5761 *always_unavailable = 1;
5762 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005763 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005764 }
5765 continue;
5766 }
5767
5768 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5769 if (N < availability_size) {
5770 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005771 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005772 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5773 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5774 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5775 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005776 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005777 }
5778 ++N;
5779 }
5780 }
5781
5782 return N;
5783}
5784
5785void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5786 clang_disposeString(availability->Platform);
5787 clang_disposeString(availability->Message);
5788}
5789
5790CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5791 if (clang_isDeclaration(cursor.kind))
5792 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5793
5794 return CXLanguage_Invalid;
5795}
5796
5797 /// \brief If the given cursor is the "templated" declaration
5798 /// descibing a class or function template, return the class or
5799 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005800static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005801 if (!D)
5802 return 0;
5803
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005804 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005805 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5806 return FunTmpl;
5807
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005808 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005809 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5810 return ClassTmpl;
5811
5812 return D;
5813}
5814
5815CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5816 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005817 if (const Decl *D = getCursorDecl(cursor)) {
5818 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005819 if (!DC)
5820 return clang_getNullCursor();
5821
5822 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5823 getCursorTU(cursor));
5824 }
5825 }
5826
5827 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005828 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005829 return MakeCXCursor(D, getCursorTU(cursor));
5830 }
5831
5832 return clang_getNullCursor();
5833}
5834
5835CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5836 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005837 if (const Decl *D = getCursorDecl(cursor)) {
5838 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005839 if (!DC)
5840 return clang_getNullCursor();
5841
5842 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5843 getCursorTU(cursor));
5844 }
5845 }
5846
5847 // FIXME: Note that we can't easily compute the lexical context of a
5848 // statement or expression, so we return nothing.
5849 return clang_getNullCursor();
5850}
5851
5852CXFile clang_getIncludedFile(CXCursor cursor) {
5853 if (cursor.kind != CXCursor_InclusionDirective)
5854 return 0;
5855
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005856 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005857 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005858}
5859
5860CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5861 if (!clang_isDeclaration(C.kind))
5862 return clang_getNullRange();
5863
5864 const Decl *D = getCursorDecl(C);
5865 ASTContext &Context = getCursorContext(C);
5866 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5867 if (!RC)
5868 return clang_getNullRange();
5869
5870 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5871}
5872
5873CXString clang_Cursor_getRawCommentText(CXCursor C) {
5874 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005875 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005876
5877 const Decl *D = getCursorDecl(C);
5878 ASTContext &Context = getCursorContext(C);
5879 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5880 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5881 StringRef();
5882
5883 // Don't duplicate the string because RawText points directly into source
5884 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005885 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005886}
5887
5888CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5889 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005890 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005891
5892 const Decl *D = getCursorDecl(C);
5893 const ASTContext &Context = getCursorContext(C);
5894 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5895
5896 if (RC) {
5897 StringRef BriefText = RC->getBriefText(Context);
5898
5899 // Don't duplicate the string because RawComment ensures that this memory
5900 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005901 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005902 }
5903
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005904 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005905}
5906
5907CXComment clang_Cursor_getParsedComment(CXCursor C) {
5908 if (!clang_isDeclaration(C.kind))
5909 return cxcomment::createCXComment(NULL, NULL);
5910
5911 const Decl *D = getCursorDecl(C);
5912 const ASTContext &Context = getCursorContext(C);
5913 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5914
5915 return cxcomment::createCXComment(FC, getCursorTU(C));
5916}
5917
5918CXModule clang_Cursor_getModule(CXCursor C) {
5919 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005920 if (const ImportDecl *ImportD =
5921 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005922 return ImportD->getImportedModule();
5923 }
5924
5925 return 0;
5926}
5927
5928CXModule clang_Module_getParent(CXModule CXMod) {
5929 if (!CXMod)
5930 return 0;
5931 Module *Mod = static_cast<Module*>(CXMod);
5932 return Mod->Parent;
5933}
5934
5935CXString clang_Module_getName(CXModule CXMod) {
5936 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005937 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005938 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005939 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005940}
5941
5942CXString clang_Module_getFullName(CXModule CXMod) {
5943 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005944 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005945 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005946 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005947}
5948
5949unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
5950 if (!CXMod)
5951 return 0;
5952 Module *Mod = static_cast<Module*>(CXMod);
5953 return Mod->TopHeaders.size();
5954}
5955
5956CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
5957 if (!CXMod)
5958 return 0;
5959 Module *Mod = static_cast<Module*>(CXMod);
5960
5961 if (Index < Mod->TopHeaders.size())
5962 return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
5963
5964 return 0;
5965}
5966
5967} // end: extern "C"
5968
5969//===----------------------------------------------------------------------===//
5970// C++ AST instrospection.
5971//===----------------------------------------------------------------------===//
5972
5973extern "C" {
5974unsigned clang_CXXMethod_isStatic(CXCursor C) {
5975 if (!clang_isDeclaration(C.kind))
5976 return 0;
5977
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005978 const CXXMethodDecl *Method = 0;
5979 const Decl *D = cxcursor::getCursorDecl(C);
5980 if (const FunctionTemplateDecl *FunTmpl =
5981 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005982 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5983 else
5984 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5985 return (Method && Method->isStatic()) ? 1 : 0;
5986}
5987
5988unsigned clang_CXXMethod_isVirtual(CXCursor C) {
5989 if (!clang_isDeclaration(C.kind))
5990 return 0;
5991
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005992 const CXXMethodDecl *Method = 0;
5993 const Decl *D = cxcursor::getCursorDecl(C);
5994 if (const FunctionTemplateDecl *FunTmpl =
5995 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005996 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5997 else
5998 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5999 return (Method && Method->isVirtual()) ? 1 : 0;
6000}
6001} // end: extern "C"
6002
6003//===----------------------------------------------------------------------===//
6004// Attribute introspection.
6005//===----------------------------------------------------------------------===//
6006
6007extern "C" {
6008CXType clang_getIBOutletCollectionType(CXCursor C) {
6009 if (C.kind != CXCursor_IBOutletCollectionAttr)
6010 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6011
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006012 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006013 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6014
6015 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6016}
6017} // end: extern "C"
6018
6019//===----------------------------------------------------------------------===//
6020// Inspecting memory usage.
6021//===----------------------------------------------------------------------===//
6022
6023typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6024
6025static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6026 enum CXTUResourceUsageKind k,
6027 unsigned long amount) {
6028 CXTUResourceUsageEntry entry = { k, amount };
6029 entries.push_back(entry);
6030}
6031
6032extern "C" {
6033
6034const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6035 const char *str = "";
6036 switch (kind) {
6037 case CXTUResourceUsage_AST:
6038 str = "ASTContext: expressions, declarations, and types";
6039 break;
6040 case CXTUResourceUsage_Identifiers:
6041 str = "ASTContext: identifiers";
6042 break;
6043 case CXTUResourceUsage_Selectors:
6044 str = "ASTContext: selectors";
6045 break;
6046 case CXTUResourceUsage_GlobalCompletionResults:
6047 str = "Code completion: cached global results";
6048 break;
6049 case CXTUResourceUsage_SourceManagerContentCache:
6050 str = "SourceManager: content cache allocator";
6051 break;
6052 case CXTUResourceUsage_AST_SideTables:
6053 str = "ASTContext: side tables";
6054 break;
6055 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6056 str = "SourceManager: malloc'ed memory buffers";
6057 break;
6058 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6059 str = "SourceManager: mmap'ed memory buffers";
6060 break;
6061 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6062 str = "ExternalASTSource: malloc'ed memory buffers";
6063 break;
6064 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6065 str = "ExternalASTSource: mmap'ed memory buffers";
6066 break;
6067 case CXTUResourceUsage_Preprocessor:
6068 str = "Preprocessor: malloc'ed memory";
6069 break;
6070 case CXTUResourceUsage_PreprocessingRecord:
6071 str = "Preprocessor: PreprocessingRecord";
6072 break;
6073 case CXTUResourceUsage_SourceManager_DataStructures:
6074 str = "SourceManager: data structures and tables";
6075 break;
6076 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6077 str = "Preprocessor: header search tables";
6078 break;
6079 }
6080 return str;
6081}
6082
6083CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6084 if (!TU) {
6085 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6086 return usage;
6087 }
6088
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006089 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006090 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6091 ASTContext &astContext = astUnit->getASTContext();
6092
6093 // How much memory is used by AST nodes and types?
6094 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6095 (unsigned long) astContext.getASTAllocatedMemory());
6096
6097 // How much memory is used by identifiers?
6098 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6099 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6100
6101 // How much memory is used for selectors?
6102 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6103 (unsigned long) astContext.Selectors.getTotalMemory());
6104
6105 // How much memory is used by ASTContext's side tables?
6106 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6107 (unsigned long) astContext.getSideTableAllocatedMemory());
6108
6109 // How much memory is used for caching global code completion results?
6110 unsigned long completionBytes = 0;
6111 if (GlobalCodeCompletionAllocator *completionAllocator =
6112 astUnit->getCachedCompletionAllocator().getPtr()) {
6113 completionBytes = completionAllocator->getTotalMemory();
6114 }
6115 createCXTUResourceUsageEntry(*entries,
6116 CXTUResourceUsage_GlobalCompletionResults,
6117 completionBytes);
6118
6119 // How much memory is being used by SourceManager's content cache?
6120 createCXTUResourceUsageEntry(*entries,
6121 CXTUResourceUsage_SourceManagerContentCache,
6122 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6123
6124 // How much memory is being used by the MemoryBuffer's in SourceManager?
6125 const SourceManager::MemoryBufferSizes &srcBufs =
6126 astUnit->getSourceManager().getMemoryBufferSizes();
6127
6128 createCXTUResourceUsageEntry(*entries,
6129 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6130 (unsigned long) srcBufs.malloc_bytes);
6131 createCXTUResourceUsageEntry(*entries,
6132 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6133 (unsigned long) srcBufs.mmap_bytes);
6134 createCXTUResourceUsageEntry(*entries,
6135 CXTUResourceUsage_SourceManager_DataStructures,
6136 (unsigned long) astContext.getSourceManager()
6137 .getDataStructureSizes());
6138
6139 // How much memory is being used by the ExternalASTSource?
6140 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6141 const ExternalASTSource::MemoryBufferSizes &sizes =
6142 esrc->getMemoryBufferSizes();
6143
6144 createCXTUResourceUsageEntry(*entries,
6145 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6146 (unsigned long) sizes.malloc_bytes);
6147 createCXTUResourceUsageEntry(*entries,
6148 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6149 (unsigned long) sizes.mmap_bytes);
6150 }
6151
6152 // How much memory is being used by the Preprocessor?
6153 Preprocessor &pp = astUnit->getPreprocessor();
6154 createCXTUResourceUsageEntry(*entries,
6155 CXTUResourceUsage_Preprocessor,
6156 pp.getTotalMemory());
6157
6158 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6159 createCXTUResourceUsageEntry(*entries,
6160 CXTUResourceUsage_PreprocessingRecord,
6161 pRec->getTotalMemory());
6162 }
6163
6164 createCXTUResourceUsageEntry(*entries,
6165 CXTUResourceUsage_Preprocessor_HeaderSearch,
6166 pp.getHeaderSearchInfo().getTotalMemory());
6167
6168 CXTUResourceUsage usage = { (void*) entries.get(),
6169 (unsigned) entries->size(),
6170 entries->size() ? &(*entries)[0] : 0 };
6171 entries.take();
6172 return usage;
6173}
6174
6175void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6176 if (usage.data)
6177 delete (MemUsageEntries*) usage.data;
6178}
6179
6180} // end extern "C"
6181
6182void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6183 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6184 for (unsigned I = 0; I != Usage.numEntries; ++I)
6185 fprintf(stderr, " %s: %lu\n",
6186 clang_getTUResourceUsageName(Usage.entries[I].kind),
6187 Usage.entries[I].amount);
6188
6189 clang_disposeCXTUResourceUsage(Usage);
6190}
6191
6192//===----------------------------------------------------------------------===//
6193// Misc. utility functions.
6194//===----------------------------------------------------------------------===//
6195
6196/// Default to using an 8 MB stack size on "safety" threads.
6197static unsigned SafetyStackThreadSize = 8 << 20;
6198
6199namespace clang {
6200
6201bool RunSafely(llvm::CrashRecoveryContext &CRC,
6202 void (*Fn)(void*), void *UserData,
6203 unsigned Size) {
6204 if (!Size)
6205 Size = GetSafetyThreadStackSize();
6206 if (Size)
6207 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6208 return CRC.RunSafely(Fn, UserData);
6209}
6210
6211unsigned GetSafetyThreadStackSize() {
6212 return SafetyStackThreadSize;
6213}
6214
6215void SetSafetyThreadStackSize(unsigned Value) {
6216 SafetyStackThreadSize = Value;
6217}
6218
6219}
6220
6221void clang::setThreadBackgroundPriority() {
6222 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6223 return;
6224
6225 // FIXME: Move to llvm/Support and make it cross-platform.
6226#ifdef __APPLE__
6227 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6228#endif
6229}
6230
6231void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6232 if (!Unit)
6233 return;
6234
6235 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6236 DEnd = Unit->stored_diag_end();
6237 D != DEnd; ++D) {
6238 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6239 CXString Msg = clang_formatDiagnostic(&Diag,
6240 clang_defaultDiagnosticDisplayOptions());
6241 fprintf(stderr, "%s\n", clang_getCString(Msg));
6242 clang_disposeString(Msg);
6243 }
6244#ifdef LLVM_ON_WIN32
6245 // On Windows, force a flush, since there may be multiple copies of
6246 // stderr and stdout in the file system, all with different buffers
6247 // but writing to the same device.
6248 fflush(stderr);
6249#endif
6250}
6251
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006252MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6253 SourceLocation MacroDefLoc,
6254 CXTranslationUnit TU){
6255 if (MacroDefLoc.isInvalid() || !TU)
6256 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006257 if (!II.hadMacroDefinition())
6258 return 0;
6259
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006260 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006261 Preprocessor &PP = Unit->getPreprocessor();
Dmitri Gribenkob3958472013-01-14 00:36:42 +00006262 MacroInfo *MI = PP.getMacroInfoHistory(&II);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006263 while (MI) {
6264 if (MacroDefLoc == MI->getDefinitionLoc())
6265 return MI;
6266 MI = MI->getPreviousDefinition();
6267 }
6268
6269 return 0;
6270}
6271
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006272const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6273 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006274 if (!MacroDef || !TU)
6275 return 0;
6276 const IdentifierInfo *II = MacroDef->getName();
6277 if (!II)
6278 return 0;
6279
6280 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6281}
6282
6283MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6284 const Token &Tok,
6285 CXTranslationUnit TU) {
6286 if (!MI || !TU)
6287 return 0;
6288 if (Tok.isNot(tok::raw_identifier))
6289 return 0;
6290
6291 if (MI->getNumTokens() == 0)
6292 return 0;
6293 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6294 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006295 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006296
6297 // Check that the token is inside the definition and not its argument list.
6298 SourceManager &SM = Unit->getSourceManager();
6299 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6300 return 0;
6301 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6302 return 0;
6303
6304 Preprocessor &PP = Unit->getPreprocessor();
6305 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6306 if (!PPRec)
6307 return 0;
6308
6309 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6310 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6311 if (!II.hadMacroDefinition())
6312 return 0;
6313
6314 // Check that the identifier is not one of the macro arguments.
6315 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6316 return 0;
6317
6318 MacroInfo *InnerMI = PP.getMacroInfoHistory(&II);
6319 if (!InnerMI)
6320 return 0;
6321
6322 return PPRec->findMacroDefinition(InnerMI);
6323}
6324
6325MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6326 SourceLocation Loc,
6327 CXTranslationUnit TU) {
6328 if (Loc.isInvalid() || !MI || !TU)
6329 return 0;
6330
6331 if (MI->getNumTokens() == 0)
6332 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006333 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006334 Preprocessor &PP = Unit->getPreprocessor();
6335 if (!PP.getPreprocessingRecord())
6336 return 0;
6337 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6338 Token Tok;
6339 if (PP.getRawToken(Loc, Tok))
6340 return 0;
6341
6342 return checkForMacroInMacroDefinition(MI, Tok, TU);
6343}
6344
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006345extern "C" {
6346
6347CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006348 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006349}
6350
6351} // end: extern "C"
6352
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006353Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6354 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006355 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006356 LogOS << '<' << Unit->getMainFileName() << '>';
6357 return *this;
6358 }
6359 }
6360
6361 LogOS << "<NULL TU>";
6362 return *this;
6363}
6364
6365Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6366 CXFile File;
6367 unsigned Line, Column;
6368 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6369 CXString FileName = clang_getFileName(File);
6370 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6371 clang_disposeString(FileName);
6372 return *this;
6373}
6374
6375Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6376 CXSourceLocation BLoc = clang_getRangeStart(range);
6377 CXSourceLocation ELoc = clang_getRangeEnd(range);
6378
6379 CXFile BFile;
6380 unsigned BLine, BColumn;
6381 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6382
6383 CXFile EFile;
6384 unsigned ELine, EColumn;
6385 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6386
6387 CXString BFileName = clang_getFileName(BFile);
6388 if (BFile == EFile) {
6389 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6390 BLine, BColumn, ELine, EColumn);
6391 } else {
6392 CXString EFileName = clang_getFileName(EFile);
6393 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6394 BLine, BColumn)
6395 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6396 ELine, EColumn);
6397 clang_disposeString(EFileName);
6398 }
6399 clang_disposeString(BFileName);
6400 return *this;
6401}
6402
6403Logger &cxindex::Logger::operator<<(CXString Str) {
6404 *this << clang_getCString(Str);
6405 return *this;
6406}
6407
6408Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6409 LogOS << Fmt;
6410 return *this;
6411}
6412
6413cxindex::Logger::~Logger() {
6414 LogOS.flush();
6415
6416 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6417
6418 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6419
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006420 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006421 OS << "[libclang:" << Name << ':';
6422
6423 // FIXME: Portability.
6424#if HAVE_PTHREAD_H && __APPLE__
6425 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6426 OS << tid << ':';
6427#endif
6428
6429 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6430 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6431 OS << Msg.str() << '\n';
6432
6433 if (Trace) {
6434 llvm::sys::PrintStackTrace(stderr);
6435 OS << "--------------------------------------------------\n";
6436 }
6437}