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