blob: 0fc36b2f02c6fd53aad420d2db5d0e7b1085abbe [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"
David Blaikie0b5ca512013-09-13 18:32:52 +000026#include "clang/AST/Attr.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000027#include "clang/AST/StmtVisitor.h"
28#include "clang/Basic/Diagnostic.h"
29#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
33#include "clang/Lex/HeaderSearch.h"
34#include "clang/Lex/Lexer.h"
35#include "clang/Lex/PreprocessingRecord.h"
36#include "clang/Lex/Preprocessor.h"
37#include "llvm/ADT/Optional.h"
38#include "llvm/ADT/STLExtras.h"
39#include "llvm/ADT/StringSwitch.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000040#include "llvm/Config/config.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000041#include "llvm/Support/Compiler.h"
42#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000043#include "llvm/Support/Format.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000044#include "llvm/Support/MemoryBuffer.h"
45#include "llvm/Support/Mutex.h"
46#include "llvm/Support/PrettyStackTrace.h"
47#include "llvm/Support/Program.h"
48#include "llvm/Support/SaveAndRestore.h"
49#include "llvm/Support/Signals.h"
50#include "llvm/Support/Threading.h"
51#include "llvm/Support/Timer.h"
52#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +000053
54#if HAVE_PTHREAD_H
55#include <pthread.h>
56#endif
Guy Benyei7f92f2d2012-12-18 14:30:41 +000057
58using namespace clang;
59using namespace clang::cxcursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000060using 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 Gribenkoaca3e562013-02-03 13:52:47 +000069 D->StringPool = new cxstring::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
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000227bool CursorVisitor::visitFileRegion() {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000228 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000229 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000230
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)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000247 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000248
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())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000255 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000256
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000257 if (visitDeclsFromFileRegion(File, Offset, Length))
258 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000259
260 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000261 return visitPreprocessedEntitiesInRegion();
262
263 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000264}
265
266static bool isInLexicalContext(Decl *D, DeclContext *DC) {
267 if (!DC)
268 return false;
269
270 for (DeclContext *DeclDC = D->getLexicalDeclContext();
271 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
272 if (DeclDC == DC)
273 return true;
274 }
275 return false;
276}
277
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000278bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000279 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000280 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000281 SourceManager &SM = Unit->getSourceManager();
282 SourceRange Range = RegionOfInterest;
283
284 SmallVector<Decl *, 16> Decls;
285 Unit->findFileRegionDecls(File, Offset, Length, Decls);
286
287 // If we didn't find any file level decls for the file, try looking at the
288 // file that it was included from.
289 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
290 bool Invalid = false;
291 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
292 if (Invalid)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000293 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000294
295 SourceLocation Outer;
296 if (SLEntry.isFile())
297 Outer = SLEntry.getFile().getIncludeLoc();
298 else
299 Outer = SLEntry.getExpansion().getExpansionLocStart();
300 if (Outer.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000301 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000302
303 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
304 Length = 0;
305 Unit->findFileRegionDecls(File, Offset, Length, Decls);
306 }
307
308 assert(!Decls.empty());
309
310 bool VisitedAtLeastOnce = false;
311 DeclContext *CurDC = 0;
Craig Topper09d19ef2013-07-04 03:08:24 +0000312 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
313 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000314 Decl *D = *DIt;
315 if (D->getSourceRange().isInvalid())
316 continue;
317
318 if (isInLexicalContext(D, CurDC))
319 continue;
320
321 CurDC = dyn_cast<DeclContext>(D);
322
323 if (TagDecl *TD = dyn_cast<TagDecl>(D))
324 if (!TD->isFreeStanding())
325 continue;
326
327 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
328 if (CompRes == RangeBefore)
329 continue;
330 if (CompRes == RangeAfter)
331 break;
332
333 assert(CompRes == RangeOverlap);
334 VisitedAtLeastOnce = true;
335
336 if (isa<ObjCContainerDecl>(D)) {
337 FileDI_current = &DIt;
338 FileDE_current = DE;
339 } else {
340 FileDI_current = 0;
341 }
342
343 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000344 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000345 }
346
347 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000348 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000349
350 // No Decls overlapped with the range. Move up the lexical context until there
351 // is a context that contains the range or we reach the translation unit
352 // level.
353 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
354 : (*(DIt-1))->getLexicalDeclContext();
355
356 while (DC && !DC->isTranslationUnit()) {
357 Decl *D = cast<Decl>(DC);
358 SourceRange CurDeclRange = D->getSourceRange();
359 if (CurDeclRange.isInvalid())
360 break;
361
362 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000363 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
364 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000365 }
366
367 DC = D->getLexicalDeclContext();
368 }
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000369
370 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000371}
372
373bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
374 if (!AU->getPreprocessor().getPreprocessingRecord())
375 return false;
376
377 PreprocessingRecord &PPRec
378 = *AU->getPreprocessor().getPreprocessingRecord();
379 SourceManager &SM = AU->getSourceManager();
380
381 if (RegionOfInterest.isValid()) {
382 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
383 SourceLocation B = MappedRange.getBegin();
384 SourceLocation E = MappedRange.getEnd();
385
386 if (AU->isInPreambleFileID(B)) {
387 if (SM.isLoadedSourceLocation(E))
388 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
389 PPRec, *this);
390
391 // Beginning of range lies in the preamble but it also extends beyond
392 // it into the main file. Split the range into 2 parts, one covering
393 // the preamble and another covering the main file. This allows subsequent
394 // calls to visitPreprocessedEntitiesInRange to accept a source range that
395 // lies in the same FileID, allowing it to skip preprocessed entities that
396 // do not come from the same FileID.
397 bool breaked =
398 visitPreprocessedEntitiesInRange(
399 SourceRange(B, AU->getEndOfPreambleFileID()),
400 PPRec, *this);
401 if (breaked) return true;
402 return visitPreprocessedEntitiesInRange(
403 SourceRange(AU->getStartOfMainFileID(), E),
404 PPRec, *this);
405 }
406
407 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
408 }
409
410 bool OnlyLocalDecls
411 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
412
413 if (OnlyLocalDecls)
414 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
415 PPRec);
416
417 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
418}
419
420template<typename InputIterator>
421bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
422 InputIterator Last,
423 PreprocessingRecord &PPRec,
424 FileID FID) {
425 for (; First != Last; ++First) {
426 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
427 continue;
428
429 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis333e44c2013-05-07 20:37:17 +0000430 if (!PPE)
431 continue;
432
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000433 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
434 if (Visit(MakeMacroExpansionCursor(ME, TU)))
435 return true;
436
437 continue;
438 }
439
440 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
441 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
442 return true;
443
444 continue;
445 }
446
447 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
448 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
449 return true;
450
451 continue;
452 }
453 }
454
455 return false;
456}
457
458/// \brief Visit the children of the given cursor.
459///
460/// \returns true if the visitation should be aborted, false if it
461/// should continue.
462bool CursorVisitor::VisitChildren(CXCursor Cursor) {
463 if (clang_isReference(Cursor.kind) &&
464 Cursor.kind != CXCursor_CXXBaseSpecifier) {
465 // By definition, references have no children.
466 return false;
467 }
468
469 // Set the Parent field to Cursor, then back to its old value once we're
470 // done.
471 SetParentRAII SetParent(Parent, StmtParent, Cursor);
472
473 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000474 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000475 if (!D)
476 return false;
477
478 return VisitAttributes(D) || Visit(D);
479 }
480
481 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000482 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000483 return Visit(S);
484
485 return false;
486 }
487
488 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000489 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000490 return Visit(E);
491
492 return false;
493 }
494
495 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000496 CXTranslationUnit TU = getCursorTU(Cursor);
497 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000498
499 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
500 for (unsigned I = 0; I != 2; ++I) {
501 if (VisitOrder[I]) {
502 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
503 RegionOfInterest.isInvalid()) {
504 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
505 TLEnd = CXXUnit->top_level_end();
506 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000507 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000508 return true;
509 }
510 } else if (VisitDeclContext(
511 CXXUnit->getASTContext().getTranslationUnitDecl()))
512 return true;
513 continue;
514 }
515
516 // Walk the preprocessing record.
517 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
518 visitPreprocessedEntitiesInRegion();
519 }
520
521 return false;
522 }
523
524 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000525 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000526 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
527 return Visit(BaseTSInfo->getTypeLoc());
528 }
529 }
530 }
531
532 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000533 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000534 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
535 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
536 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
537 A->getInterfaceLoc(), TU));
538 }
539
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000540 // If pointing inside a macro definition, check if the token is an identifier
541 // that was ever defined as a macro. In such a case, create a "pseudo" macro
542 // expansion cursor for that token.
543 SourceLocation BeginLoc = RegionOfInterest.getBegin();
544 if (Cursor.kind == CXCursor_MacroDefinition &&
545 BeginLoc == RegionOfInterest.getEnd()) {
546 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000547 const MacroInfo *MI =
548 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000549 if (MacroDefinition *MacroDef =
550 checkForMacroInMacroDefinition(MI, Loc, TU))
551 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
552 }
553
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000554 // Nothing to visit at the moment.
555 return false;
556}
557
558bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
559 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
560 if (Visit(TSInfo->getTypeLoc()))
561 return true;
562
563 if (Stmt *Body = B->getBody())
564 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
565
566 return false;
567}
568
Ted Kremenek943f9092013-02-21 01:29:01 +0000569Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000570 if (RegionOfInterest.isValid()) {
571 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
572 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000573 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000574
575 switch (CompareRegionOfInterest(Range)) {
576 case RangeBefore:
577 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000578 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000579
580 case RangeAfter:
581 // This declaration comes after the region of interest; we're done.
582 return false;
583
584 case RangeOverlap:
585 // This declaration overlaps the region of interest; visit it.
586 break;
587 }
588 }
589 return true;
590}
591
592bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
593 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
594
595 // FIXME: Eventually remove. This part of a hack to support proper
596 // iteration over all Decls contained lexically within an ObjC container.
597 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
598 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
599
600 for ( ; I != E; ++I) {
601 Decl *D = *I;
602 if (D->getLexicalDeclContext() != DC)
603 continue;
604 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
605
606 // Ignore synthesized ivars here, otherwise if we have something like:
607 // @synthesize prop = _prop;
608 // and '_prop' is not declared, we will encounter a '_prop' ivar before
609 // encountering the 'prop' synthesize declaration and we will think that
610 // we passed the region-of-interest.
611 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
612 if (ivarD->getSynthesize())
613 continue;
614 }
615
616 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
617 // declarations is a mismatch with the compiler semantics.
618 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
619 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
620 if (!ID->isThisDeclarationADefinition())
621 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
622
623 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
624 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
625 if (!PD->isThisDeclarationADefinition())
626 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
627 }
628
Ted Kremenek943f9092013-02-21 01:29:01 +0000629 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000630 if (!V.hasValue())
631 continue;
632 if (!V.getValue())
633 return false;
634 if (Visit(Cursor, true))
635 return true;
636 }
637 return false;
638}
639
640bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
641 llvm_unreachable("Translation units are visited directly by Visit()");
642}
643
644bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
645 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
646 return Visit(TSInfo->getTypeLoc());
647
648 return false;
649}
650
651bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
652 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
653 return Visit(TSInfo->getTypeLoc());
654
655 return false;
656}
657
658bool CursorVisitor::VisitTagDecl(TagDecl *D) {
659 return VisitDeclContext(D);
660}
661
662bool CursorVisitor::VisitClassTemplateSpecializationDecl(
663 ClassTemplateSpecializationDecl *D) {
664 bool ShouldVisitBody = false;
665 switch (D->getSpecializationKind()) {
666 case TSK_Undeclared:
667 case TSK_ImplicitInstantiation:
668 // Nothing to visit
669 return false;
670
671 case TSK_ExplicitInstantiationDeclaration:
672 case TSK_ExplicitInstantiationDefinition:
673 break;
674
675 case TSK_ExplicitSpecialization:
676 ShouldVisitBody = true;
677 break;
678 }
679
680 // Visit the template arguments used in the specialization.
681 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
682 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000683 if (TemplateSpecializationTypeLoc TSTLoc =
684 TL.getAs<TemplateSpecializationTypeLoc>()) {
685 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
686 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000687 return true;
688 }
689 }
690
691 if (ShouldVisitBody && VisitCXXRecordDecl(D))
692 return true;
693
694 return false;
695}
696
697bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
698 ClassTemplatePartialSpecializationDecl *D) {
699 // FIXME: Visit the "outer" template parameter lists on the TagDecl
700 // before visiting these template parameters.
701 if (VisitTemplateParameters(D->getTemplateParameters()))
702 return true;
703
704 // Visit the partial specialization arguments.
Enea Zaffanellac1cef082013-08-10 07:24:53 +0000705 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
706 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
707 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000708 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
709 return true;
710
711 return VisitCXXRecordDecl(D);
712}
713
714bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
715 // Visit the default argument.
716 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
717 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
718 if (Visit(DefArg->getTypeLoc()))
719 return true;
720
721 return false;
722}
723
724bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
725 if (Expr *Init = D->getInitExpr())
726 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
727 return false;
728}
729
730bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000731 unsigned NumParamList = DD->getNumTemplateParameterLists();
732 for (unsigned i = 0; i < NumParamList; i++) {
733 TemplateParameterList* Params = DD->getTemplateParameterList(i);
734 if (VisitTemplateParameters(Params))
735 return true;
736 }
737
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000738 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
739 if (Visit(TSInfo->getTypeLoc()))
740 return true;
741
742 // Visit the nested-name-specifier, if present.
743 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
744 if (VisitNestedNameSpecifierLoc(QualifierLoc))
745 return true;
746
747 return false;
748}
749
750/// \brief Compare two base or member initializers based on their source order.
751static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
752 CXXCtorInitializer const * const *X
753 = static_cast<CXXCtorInitializer const * const *>(Xp);
754 CXXCtorInitializer const * const *Y
755 = static_cast<CXXCtorInitializer const * const *>(Yp);
756
757 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
758 return -1;
759 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
760 return 1;
761 else
762 return 0;
763}
764
765bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000766 unsigned NumParamList = ND->getNumTemplateParameterLists();
767 for (unsigned i = 0; i < NumParamList; i++) {
768 TemplateParameterList* Params = ND->getTemplateParameterList(i);
769 if (VisitTemplateParameters(Params))
770 return true;
771 }
772
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000773 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
774 // Visit the function declaration's syntactic components in the order
775 // written. This requires a bit of work.
776 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000777 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000778
779 // If we have a function declared directly (without the use of a typedef),
780 // visit just the return type. Otherwise, just visit the function's type
781 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000782 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000783 (!FTL && Visit(TL)))
784 return true;
785
786 // Visit the nested-name-specifier, if present.
787 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
788 if (VisitNestedNameSpecifierLoc(QualifierLoc))
789 return true;
790
791 // Visit the declaration name.
792 if (VisitDeclarationNameInfo(ND->getNameInfo()))
793 return true;
794
795 // FIXME: Visit explicitly-specified template arguments!
796
797 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000798 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000799 return true;
800
Bill Wendlingad017fa2012-12-20 19:22:21 +0000801 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000802 }
803
804 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
805 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
806 // Find the initializers that were written in the source.
807 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
808 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
809 IEnd = Constructor->init_end();
810 I != IEnd; ++I) {
811 if (!(*I)->isWritten())
812 continue;
813
814 WrittenInits.push_back(*I);
815 }
816
817 // Sort the initializers in source order
818 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
819 &CompareCXXCtorInitializers);
820
821 // Visit the initializers in source order
822 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
823 CXXCtorInitializer *Init = WrittenInits[I];
824 if (Init->isAnyMemberInitializer()) {
825 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
826 Init->getMemberLocation(), TU)))
827 return true;
828 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
829 if (Visit(TInfo->getTypeLoc()))
830 return true;
831 }
832
833 // Visit the initializer value.
834 if (Expr *Initializer = Init->getInit())
835 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
836 return true;
837 }
838 }
839
840 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
841 return true;
842 }
843
844 return false;
845}
846
847bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
848 if (VisitDeclaratorDecl(D))
849 return true;
850
851 if (Expr *BitWidth = D->getBitWidth())
852 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
853
854 return false;
855}
856
857bool CursorVisitor::VisitVarDecl(VarDecl *D) {
858 if (VisitDeclaratorDecl(D))
859 return true;
860
861 if (Expr *Init = D->getInit())
862 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
863
864 return false;
865}
866
867bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
872 if (Expr *DefArg = D->getDefaultArgument())
873 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
874
875 return false;
876}
877
878bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
879 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
880 // before visiting these template parameters.
881 if (VisitTemplateParameters(D->getTemplateParameters()))
882 return true;
883
884 return VisitFunctionDecl(D->getTemplatedDecl());
885}
886
887bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the TagDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitCXXRecordDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
901 VisitTemplateArgumentLoc(D->getDefaultArgument()))
902 return true;
903
904 return false;
905}
906
907bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
908 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
909 if (Visit(TSInfo->getTypeLoc()))
910 return true;
911
912 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
913 PEnd = ND->param_end();
914 P != PEnd; ++P) {
915 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
916 return true;
917 }
918
919 if (ND->isThisDeclarationADefinition() &&
920 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
921 return true;
922
923 return false;
924}
925
926template <typename DeclIt>
927static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
928 SourceManager &SM, SourceLocation EndLoc,
929 SmallVectorImpl<Decl *> &Decls) {
930 DeclIt next = *DI_current;
931 while (++next != DE_current) {
932 Decl *D_next = *next;
933 if (!D_next)
934 break;
935 SourceLocation L = D_next->getLocStart();
936 if (!L.isValid())
937 break;
938 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
939 *DI_current = next;
940 Decls.push_back(D_next);
941 continue;
942 }
943 break;
944 }
945}
946
947namespace {
948 struct ContainerDeclsSort {
949 SourceManager &SM;
950 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
951 bool operator()(Decl *A, Decl *B) {
952 SourceLocation L_A = A->getLocStart();
953 SourceLocation L_B = B->getLocStart();
954 assert(L_A.isValid() && L_B.isValid());
955 return SM.isBeforeInTranslationUnit(L_A, L_B);
956 }
957 };
958}
959
960bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
961 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
962 // an @implementation can lexically contain Decls that are not properly
963 // nested in the AST. When we identify such cases, we need to retrofit
964 // this nesting here.
965 if (!DI_current && !FileDI_current)
966 return VisitDeclContext(D);
967
968 // Scan the Decls that immediately come after the container
969 // in the current DeclContext. If any fall within the
970 // container's lexical region, stash them into a vector
971 // for later processing.
972 SmallVector<Decl *, 24> DeclsInContainer;
973 SourceLocation EndLoc = D->getSourceRange().getEnd();
974 SourceManager &SM = AU->getSourceManager();
975 if (EndLoc.isValid()) {
976 if (DI_current) {
977 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
978 DeclsInContainer);
979 } else {
980 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
981 DeclsInContainer);
982 }
983 }
984
985 // The common case.
986 if (DeclsInContainer.empty())
987 return VisitDeclContext(D);
988
989 // Get all the Decls in the DeclContext, and sort them with the
990 // additional ones we've collected. Then visit them.
991 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
992 I!=E; ++I) {
993 Decl *subDecl = *I;
994 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
995 subDecl->getLocStart().isInvalid())
996 continue;
997 DeclsInContainer.push_back(subDecl);
998 }
999
1000 // Now sort the Decls so that they appear in lexical order.
1001 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1002 ContainerDeclsSort(SM));
1003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *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->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
1262 break;
1263 }
1264
1265 return false;
1266}
1267
1268bool
1269CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1270 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1271 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1272 Qualifiers.push_back(Qualifier);
1273
1274 while (!Qualifiers.empty()) {
1275 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1276 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1277 switch (NNS->getKind()) {
1278 case NestedNameSpecifier::Namespace:
1279 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1280 Q.getLocalBeginLoc(),
1281 TU)))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::NamespaceAlias:
1287 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1288 Q.getLocalBeginLoc(),
1289 TU)))
1290 return true;
1291
1292 break;
1293
1294 case NestedNameSpecifier::TypeSpec:
1295 case NestedNameSpecifier::TypeSpecWithTemplate:
1296 if (Visit(Q.getTypeLoc()))
1297 return true;
1298
1299 break;
1300
1301 case NestedNameSpecifier::Global:
1302 case NestedNameSpecifier::Identifier:
1303 break;
1304 }
1305 }
1306
1307 return false;
1308}
1309
1310bool CursorVisitor::VisitTemplateParameters(
1311 const TemplateParameterList *Params) {
1312 if (!Params)
1313 return false;
1314
1315 for (TemplateParameterList::const_iterator P = Params->begin(),
1316 PEnd = Params->end();
1317 P != PEnd; ++P) {
1318 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1319 return true;
1320 }
1321
1322 return false;
1323}
1324
1325bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1326 switch (Name.getKind()) {
1327 case TemplateName::Template:
1328 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1329
1330 case TemplateName::OverloadedTemplate:
1331 // Visit the overloaded template set.
1332 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1333 return true;
1334
1335 return false;
1336
1337 case TemplateName::DependentTemplate:
1338 // FIXME: Visit nested-name-specifier.
1339 return false;
1340
1341 case TemplateName::QualifiedTemplate:
1342 // FIXME: Visit nested-name-specifier.
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsQualifiedTemplateName()->getDecl(),
1345 Loc, TU));
1346
1347 case TemplateName::SubstTemplateTemplateParm:
1348 return Visit(MakeCursorTemplateRef(
1349 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1350 Loc, TU));
1351
1352 case TemplateName::SubstTemplateTemplateParmPack:
1353 return Visit(MakeCursorTemplateRef(
1354 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1355 Loc, TU));
1356 }
1357
1358 llvm_unreachable("Invalid TemplateName::Kind!");
1359}
1360
1361bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1362 switch (TAL.getArgument().getKind()) {
1363 case TemplateArgument::Null:
1364 case TemplateArgument::Integral:
1365 case TemplateArgument::Pack:
1366 return false;
1367
1368 case TemplateArgument::Type:
1369 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1370 return Visit(TSInfo->getTypeLoc());
1371 return false;
1372
1373 case TemplateArgument::Declaration:
1374 if (Expr *E = TAL.getSourceDeclExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::NullPtr:
1379 if (Expr *E = TAL.getSourceNullPtrExpression())
1380 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1381 return false;
1382
1383 case TemplateArgument::Expression:
1384 if (Expr *E = TAL.getSourceExpression())
1385 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1386 return false;
1387
1388 case TemplateArgument::Template:
1389 case TemplateArgument::TemplateExpansion:
1390 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1391 return true;
1392
1393 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1394 TAL.getTemplateNameLoc());
1395 }
1396
1397 llvm_unreachable("Invalid TemplateArgument::Kind!");
1398}
1399
1400bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1401 return VisitDeclContext(D);
1402}
1403
1404bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1405 return Visit(TL.getUnqualifiedLoc());
1406}
1407
1408bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1409 ASTContext &Context = AU->getASTContext();
1410
1411 // Some builtin types (such as Objective-C's "id", "sel", and
1412 // "Class") have associated declarations. Create cursors for those.
1413 QualType VisitType;
1414 switch (TL.getTypePtr()->getKind()) {
1415
1416 case BuiltinType::Void:
1417 case BuiltinType::NullPtr:
1418 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001419 case BuiltinType::OCLImage1d:
1420 case BuiltinType::OCLImage1dArray:
1421 case BuiltinType::OCLImage1dBuffer:
1422 case BuiltinType::OCLImage2d:
1423 case BuiltinType::OCLImage2dArray:
1424 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001425 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001426 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001427#define BUILTIN_TYPE(Id, SingletonId)
1428#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#include "clang/AST/BuiltinTypes.def"
1433 break;
1434
1435 case BuiltinType::ObjCId:
1436 VisitType = Context.getObjCIdType();
1437 break;
1438
1439 case BuiltinType::ObjCClass:
1440 VisitType = Context.getObjCClassType();
1441 break;
1442
1443 case BuiltinType::ObjCSel:
1444 VisitType = Context.getObjCSelType();
1445 break;
1446 }
1447
1448 if (!VisitType.isNull()) {
1449 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1450 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1451 TU));
1452 }
1453
1454 return false;
1455}
1456
1457bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1458 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1459}
1460
1461bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1462 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1463}
1464
1465bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1466 if (TL.isDefinition())
1467 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1468
1469 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1470}
1471
1472bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1473 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1474}
1475
1476bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1477 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1478 return true;
1479
1480 return false;
1481}
1482
1483bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1484 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1485 return true;
1486
1487 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1488 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1489 TU)))
1490 return true;
1491 }
1492
1493 return false;
1494}
1495
1496bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1501 return Visit(TL.getInnerLoc());
1502}
1503
1504bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1505 return Visit(TL.getPointeeLoc());
1506}
1507
1508bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1509 return Visit(TL.getPointeeLoc());
1510}
1511
1512bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1513 return Visit(TL.getPointeeLoc());
1514}
1515
1516bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1517 return Visit(TL.getPointeeLoc());
1518}
1519
1520bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1521 return Visit(TL.getPointeeLoc());
1522}
1523
1524bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1525 return Visit(TL.getModifiedLoc());
1526}
1527
1528bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1529 bool SkipResultType) {
1530 if (!SkipResultType && Visit(TL.getResultLoc()))
1531 return true;
1532
1533 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1534 if (Decl *D = TL.getArg(I))
1535 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1536 return true;
1537
1538 return false;
1539}
1540
1541bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1542 if (Visit(TL.getElementLoc()))
1543 return true;
1544
1545 if (Expr *Size = TL.getSizeExpr())
1546 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1547
1548 return false;
1549}
1550
Reid Kleckner12df2462013-06-24 17:51:48 +00001551bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1552 return Visit(TL.getOriginalLoc());
1553}
1554
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001555bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1556 TemplateSpecializationTypeLoc TL) {
1557 // Visit the template name.
1558 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1559 TL.getTemplateNameLoc()))
1560 return true;
1561
1562 // Visit the template arguments.
1563 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1564 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1565 return true;
1566
1567 return false;
1568}
1569
1570bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1571 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1572}
1573
1574bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1575 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1576 return Visit(TSInfo->getTypeLoc());
1577
1578 return false;
1579}
1580
1581bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1582 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1583 return Visit(TSInfo->getTypeLoc());
1584
1585 return false;
1586}
1587
1588bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1589 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1590 return true;
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1596 DependentTemplateSpecializationTypeLoc TL) {
1597 // Visit the nested-name-specifier, if there is one.
1598 if (TL.getQualifierLoc() &&
1599 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1600 return true;
1601
1602 // Visit the template arguments.
1603 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1604 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1605 return true;
1606
1607 return false;
1608}
1609
1610bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1611 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1612 return true;
1613
1614 return Visit(TL.getNamedTypeLoc());
1615}
1616
1617bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1618 return Visit(TL.getPatternLoc());
1619}
1620
1621bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1622 if (Expr *E = TL.getUnderlyingExpr())
1623 return Visit(MakeCXCursor(E, StmtParent, TU));
1624
1625 return false;
1626}
1627
1628bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1629 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1630}
1631
1632bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1633 return Visit(TL.getValueLoc());
1634}
1635
1636#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1637bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1638 return Visit##PARENT##Loc(TL); \
1639}
1640
1641DEFAULT_TYPELOC_IMPL(Complex, Type)
1642DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1647DEFAULT_TYPELOC_IMPL(Vector, Type)
1648DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1649DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1650DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(Record, TagType)
1652DEFAULT_TYPELOC_IMPL(Enum, TagType)
1653DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1655DEFAULT_TYPELOC_IMPL(Auto, Type)
1656
1657bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1658 // Visit the nested-name-specifier, if present.
1659 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1660 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1661 return true;
1662
1663 if (D->isCompleteDefinition()) {
1664 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1665 E = D->bases_end(); I != E; ++I) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
1675 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1676 i != e; ++i)
1677 if (Visit(MakeCXCursor(*i, D, TU)))
1678 return true;
1679
1680 return false;
1681}
1682
1683//===----------------------------------------------------------------------===//
1684// Data-recursive visitor methods.
1685//===----------------------------------------------------------------------===//
1686
1687namespace {
1688#define DEF_JOB(NAME, DATA, KIND)\
1689class NAME : public VisitorJob {\
1690public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001691 NAME(const DATA *d, CXCursor parent) : \
1692 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001693 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001694 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001695};
1696
1697DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1698DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1699DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1700DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1701DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1702 ExplicitTemplateArgsVisitKind)
1703DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1704DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1705DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1706#undef DEF_JOB
1707
1708class DeclVisit : public VisitorJob {
1709public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001710 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001711 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001712 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001713 static bool classof(const VisitorJob *VJ) {
1714 return VJ->getKind() == DeclVisitKind;
1715 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001716 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001717 bool isFirst() const { return data[1] ? true : false; }
1718};
1719class TypeLocVisit : public VisitorJob {
1720public:
1721 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1722 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1723 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1724
1725 static bool classof(const VisitorJob *VJ) {
1726 return VJ->getKind() == TypeLocVisitKind;
1727 }
1728
1729 TypeLoc get() const {
1730 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001731 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001732 }
1733};
1734
1735class LabelRefVisit : public VisitorJob {
1736public:
1737 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1738 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1739 labelLoc.getPtrEncoding()) {}
1740
1741 static bool classof(const VisitorJob *VJ) {
1742 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1743 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001744 const LabelDecl *get() const {
1745 return static_cast<const LabelDecl *>(data[0]);
1746 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001747 SourceLocation getLoc() const {
1748 return SourceLocation::getFromPtrEncoding(data[1]); }
1749};
1750
1751class NestedNameSpecifierLocVisit : public VisitorJob {
1752public:
1753 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1754 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1755 Qualifier.getNestedNameSpecifier(),
1756 Qualifier.getOpaqueData()) { }
1757
1758 static bool classof(const VisitorJob *VJ) {
1759 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1760 }
1761
1762 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001763 return NestedNameSpecifierLoc(
1764 const_cast<NestedNameSpecifier *>(
1765 static_cast<const NestedNameSpecifier *>(data[0])),
1766 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001767 }
1768};
1769
1770class DeclarationNameInfoVisit : public VisitorJob {
1771public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001772 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001773 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001774 static bool classof(const VisitorJob *VJ) {
1775 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1776 }
1777 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001778 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001779 switch (S->getStmtClass()) {
1780 default:
1781 llvm_unreachable("Unhandled Stmt");
1782 case clang::Stmt::MSDependentExistsStmtClass:
1783 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1784 case Stmt::CXXDependentScopeMemberExprClass:
1785 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1786 case Stmt::DependentScopeDeclRefExprClass:
1787 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1788 }
1789 }
1790};
1791class MemberRefVisit : public VisitorJob {
1792public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001793 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001794 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1795 L.getPtrEncoding()) {}
1796 static bool classof(const VisitorJob *VJ) {
1797 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1798 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001799 const FieldDecl *get() const {
1800 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001801 }
1802 SourceLocation getLoc() const {
1803 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1804 }
1805};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001806class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001807 friend class OMPClauseEnqueue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001808 VisitorWorkList &WL;
1809 CXCursor Parent;
1810public:
1811 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1812 : WL(wl), Parent(parent) {}
1813
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001814 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1815 void VisitBlockExpr(const BlockExpr *B);
1816 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1817 void VisitCompoundStmt(const CompoundStmt *S);
1818 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1819 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1820 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1821 void VisitCXXNewExpr(const CXXNewExpr *E);
1822 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1823 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1824 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1825 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1826 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1827 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1828 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1829 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1830 void VisitDeclRefExpr(const DeclRefExpr *D);
1831 void VisitDeclStmt(const DeclStmt *S);
1832 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1833 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1834 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1835 void VisitForStmt(const ForStmt *FS);
1836 void VisitGotoStmt(const GotoStmt *GS);
1837 void VisitIfStmt(const IfStmt *If);
1838 void VisitInitListExpr(const InitListExpr *IE);
1839 void VisitMemberExpr(const MemberExpr *M);
1840 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1841 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1842 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1843 void VisitOverloadExpr(const OverloadExpr *E);
1844 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1845 void VisitStmt(const Stmt *S);
1846 void VisitSwitchStmt(const SwitchStmt *S);
1847 void VisitWhileStmt(const WhileStmt *W);
1848 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1849 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1850 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1851 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1852 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1853 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1854 void VisitVAArgExpr(const VAArgExpr *E);
1855 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1856 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1857 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1858 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001859 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1860 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001861
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001862private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001863 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001864 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1865 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001866 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1867 void AddStmt(const Stmt *S);
1868 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001869 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001870 void EnqueueChildren(const Stmt *S);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001871 void EnqueueChildren(const OMPClause *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001872};
1873} // end anonyous namespace
1874
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001875void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001876 // 'S' should always be non-null, since it comes from the
1877 // statement we are visiting.
1878 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1879}
1880
1881void
1882EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1883 if (Qualifier)
1884 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1885}
1886
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001887void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001888 if (S)
1889 WL.push_back(StmtVisit(S, Parent));
1890}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001891void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001892 if (D)
1893 WL.push_back(DeclVisit(D, Parent, isFirst));
1894}
1895void EnqueueVisitor::
1896 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1897 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001898 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001899}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001900void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001901 if (D)
1902 WL.push_back(MemberRefVisit(D, L, Parent));
1903}
1904void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1905 if (TI)
1906 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1907 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001908void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001909 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001910 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001911 AddStmt(*Child);
1912 }
1913 if (size == WL.size())
1914 return;
1915 // Now reverse the entries we just added. This will match the DFS
1916 // ordering performed by the worklist.
1917 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1918 std::reverse(I, E);
1919}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001920namespace {
1921class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1922 EnqueueVisitor *Visitor;
1923public:
1924 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1925#define OPENMP_CLAUSE(Name, Class) \
1926 void Visit##Class(const Class *C);
1927#include "clang/Basic/OpenMPKinds.def"
1928};
1929
1930void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
1931#define PROCESS_OMP_CLAUSE_LIST(Class, Node) \
1932 for (OMPVarList<Class>::varlist_const_iterator I = Node->varlist_begin(), \
1933 E = Node->varlist_end(); \
1934 I != E; ++I) \
1935 Visitor->AddStmt(*I);
1936
1937void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
1938 PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
1939}
Alexey Bataev0c018352013-09-06 18:03:48 +00001940void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
1941 PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
1942}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001943#undef PROCESS_OMP_CLAUSE_LIST
1944}
1945void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1946 unsigned size = WL.size();
1947 OMPClauseEnqueue Visitor(this);
1948 Visitor.Visit(S);
1949 if (size == WL.size())
1950 return;
1951 // Now reverse the entries we just added. This will match the DFS
1952 // ordering performed by the worklist.
1953 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1954 std::reverse(I, E);
1955}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001956void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001957 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1958}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001959void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001960 AddDecl(B->getBlockDecl());
1961}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001962void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001963 EnqueueChildren(E);
1964 AddTypeLoc(E->getTypeSourceInfo());
1965}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001966void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1967 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001968 E = S->body_rend(); I != E; ++I) {
1969 AddStmt(*I);
1970 }
1971}
1972void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001973VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001974 AddStmt(S->getSubStmt());
1975 AddDeclarationNameInfo(S);
1976 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1977 AddNestedNameSpecifierLoc(QualifierLoc);
1978}
1979
1980void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001981VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001982 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1983 AddDeclarationNameInfo(E);
1984 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1985 AddNestedNameSpecifierLoc(QualifierLoc);
1986 if (!E->isImplicitAccess())
1987 AddStmt(E->getBase());
1988}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001989void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001990 // Enqueue the initializer , if any.
1991 AddStmt(E->getInitializer());
1992 // Enqueue the array size, if any.
1993 AddStmt(E->getArraySize());
1994 // Enqueue the allocated type.
1995 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1996 // Enqueue the placement arguments.
1997 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1998 AddStmt(E->getPlacementArg(I-1));
1999}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002000void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002001 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2002 AddStmt(CE->getArg(I-1));
2003 AddStmt(CE->getCallee());
2004 AddStmt(CE->getArg(0));
2005}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002006void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2007 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002008 // Visit the name of the type being destroyed.
2009 AddTypeLoc(E->getDestroyedTypeInfo());
2010 // Visit the scope type that looks disturbingly like the nested-name-specifier
2011 // but isn't.
2012 AddTypeLoc(E->getScopeTypeInfo());
2013 // Visit the nested-name-specifier.
2014 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2015 AddNestedNameSpecifierLoc(QualifierLoc);
2016 // Visit base expression.
2017 AddStmt(E->getBase());
2018}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2020 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002021 AddTypeLoc(E->getTypeSourceInfo());
2022}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2024 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002025 EnqueueChildren(E);
2026 AddTypeLoc(E->getTypeSourceInfo());
2027}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002029 EnqueueChildren(E);
2030 if (E->isTypeOperand())
2031 AddTypeLoc(E->getTypeOperandSourceInfo());
2032}
2033
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2035 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002036 EnqueueChildren(E);
2037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002040 EnqueueChildren(E);
2041 if (E->isTypeOperand())
2042 AddTypeLoc(E->getTypeOperandSourceInfo());
2043}
2044
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002046 EnqueueChildren(S);
2047 AddDecl(S->getExceptionDecl());
2048}
2049
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002051 if (DR->hasExplicitTemplateArgs()) {
2052 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2053 }
2054 WL.push_back(DeclRefExprParts(DR, Parent));
2055}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2057 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002058 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2059 AddDeclarationNameInfo(E);
2060 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2061}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002063 unsigned size = WL.size();
2064 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002065 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002066 D != DEnd; ++D) {
2067 AddDecl(*D, isFirst);
2068 isFirst = false;
2069 }
2070 if (size == WL.size())
2071 return;
2072 // Now reverse the entries we just added. This will match the DFS
2073 // ordering performed by the worklist.
2074 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2075 std::reverse(I, E);
2076}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002078 AddStmt(E->getInit());
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002079 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002080 D = E->designators_rbegin(), DEnd = E->designators_rend();
2081 D != DEnd; ++D) {
2082 if (D->isFieldDesignator()) {
2083 if (FieldDecl *Field = D->getField())
2084 AddMemberRef(Field, D->getFieldLoc());
2085 continue;
2086 }
2087 if (D->isArrayDesignator()) {
2088 AddStmt(E->getArrayIndex(*D));
2089 continue;
2090 }
2091 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2092 AddStmt(E->getArrayRangeEnd(*D));
2093 AddStmt(E->getArrayRangeStart(*D));
2094 }
2095}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 AddTypeLoc(E->getTypeInfoAsWritten());
2099}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002101 AddStmt(FS->getBody());
2102 AddStmt(FS->getInc());
2103 AddStmt(FS->getCond());
2104 AddDecl(FS->getConditionVariable());
2105 AddStmt(FS->getInit());
2106}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002108 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2109}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002111 AddStmt(If->getElse());
2112 AddStmt(If->getThen());
2113 AddStmt(If->getCond());
2114 AddDecl(If->getConditionVariable());
2115}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002117 // We care about the syntactic form of the initializer list, only.
2118 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2119 IE = Syntactic;
2120 EnqueueChildren(IE);
2121}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002123 WL.push_back(MemberExprParts(M, Parent));
2124
2125 // If the base of the member access expression is an implicit 'this', don't
2126 // visit it.
2127 // FIXME: If we ever want to show these implicit accesses, this will be
2128 // unfortunate. However, clang_getCursor() relies on this behavior.
2129 if (!M->isImplicitAccess())
2130 AddStmt(M->getBase());
2131}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002133 AddTypeLoc(E->getEncodedTypeSourceInfo());
2134}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002136 EnqueueChildren(M);
2137 AddTypeLoc(M->getClassReceiverTypeInfo());
2138}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002140 // Visit the components of the offsetof expression.
2141 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2142 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2143 const OffsetOfNode &Node = E->getComponent(I-1);
2144 switch (Node.getKind()) {
2145 case OffsetOfNode::Array:
2146 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2147 break;
2148 case OffsetOfNode::Field:
2149 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2150 break;
2151 case OffsetOfNode::Identifier:
2152 case OffsetOfNode::Base:
2153 continue;
2154 }
2155 }
2156 // Visit the type into which we're computing the offset.
2157 AddTypeLoc(E->getTypeSourceInfo());
2158}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002160 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2161 WL.push_back(OverloadExprParts(E, Parent));
2162}
2163void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002164 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002165 EnqueueChildren(E);
2166 if (E->isArgumentType())
2167 AddTypeLoc(E->getArgumentTypeInfo());
2168}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002170 EnqueueChildren(S);
2171}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002173 AddStmt(S->getBody());
2174 AddStmt(S->getCond());
2175 AddDecl(S->getConditionVariable());
2176}
2177
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002179 AddStmt(W->getBody());
2180 AddStmt(W->getCond());
2181 AddDecl(W->getConditionVariable());
2182}
2183
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002185 AddTypeLoc(E->getQueriedTypeSourceInfo());
2186}
2187
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002189 AddTypeLoc(E->getRhsTypeSourceInfo());
2190 AddTypeLoc(E->getLhsTypeSourceInfo());
2191}
2192
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002194 for (unsigned I = E->getNumArgs(); I > 0; --I)
2195 AddTypeLoc(E->getArg(I-1));
2196}
2197
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002199 AddTypeLoc(E->getQueriedTypeSourceInfo());
2200}
2201
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002203 EnqueueChildren(E);
2204}
2205
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002207 VisitOverloadExpr(U);
2208 if (!U->isImplicitAccess())
2209 AddStmt(U->getBase());
2210}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002212 AddStmt(E->getSubExpr());
2213 AddTypeLoc(E->getWrittenTypeInfo());
2214}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002216 WL.push_back(SizeOfPackExprParts(E, Parent));
2217}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002219 // If the opaque value has a source expression, just transparently
2220 // visit that. This is useful for (e.g.) pseudo-object expressions.
2221 if (Expr *SourceExpr = E->getSourceExpr())
2222 return Visit(SourceExpr);
2223}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002225 AddStmt(E->getBody());
2226 WL.push_back(LambdaExprParts(E, Parent));
2227}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002229 // Treat the expression like its syntactic form.
2230 Visit(E->getSyntacticForm());
2231}
2232
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002233void EnqueueVisitor::VisitOMPExecutableDirective(
2234 const OMPExecutableDirective *D) {
2235 EnqueueChildren(D);
2236 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2237 E = D->clauses().end();
2238 I != E; ++I)
2239 EnqueueChildren(*I);
2240}
2241
2242void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2243 VisitOMPExecutableDirective(D);
2244}
2245
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002246void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002247 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2248}
2249
2250bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2251 if (RegionOfInterest.isValid()) {
2252 SourceRange Range = getRawCursorExtent(C);
2253 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2254 return false;
2255 }
2256 return true;
2257}
2258
2259bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2260 while (!WL.empty()) {
2261 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002262 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002263
2264 // Set the Parent field, then back to its old value once we're done.
2265 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2266
2267 switch (LI.getKind()) {
2268 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002269 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002270 if (!D)
2271 continue;
2272
2273 // For now, perform default visitation for Decls.
2274 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2275 cast<DeclVisit>(&LI)->isFirst())))
2276 return true;
2277
2278 continue;
2279 }
2280 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2281 const ASTTemplateArgumentListInfo *ArgList =
2282 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2283 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2284 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2285 Arg != ArgEnd; ++Arg) {
2286 if (VisitTemplateArgumentLoc(*Arg))
2287 return true;
2288 }
2289 continue;
2290 }
2291 case VisitorJob::TypeLocVisitKind: {
2292 // Perform default visitation for TypeLocs.
2293 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2294 return true;
2295 continue;
2296 }
2297 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002298 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002299 if (LabelStmt *stmt = LS->getStmt()) {
2300 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2301 TU))) {
2302 return true;
2303 }
2304 }
2305 continue;
2306 }
2307
2308 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2309 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2310 if (VisitNestedNameSpecifierLoc(V->get()))
2311 return true;
2312 continue;
2313 }
2314
2315 case VisitorJob::DeclarationNameInfoVisitKind: {
2316 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2317 ->get()))
2318 return true;
2319 continue;
2320 }
2321 case VisitorJob::MemberRefVisitKind: {
2322 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2323 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2324 return true;
2325 continue;
2326 }
2327 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002328 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002329 if (!S)
2330 continue;
2331
2332 // Update the current cursor.
2333 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2334 if (!IsInRegionOfInterest(Cursor))
2335 continue;
2336 switch (Visitor(Cursor, Parent, ClientData)) {
2337 case CXChildVisit_Break: return true;
2338 case CXChildVisit_Continue: break;
2339 case CXChildVisit_Recurse:
2340 if (PostChildrenVisitor)
2341 WL.push_back(PostChildrenVisit(0, Cursor));
2342 EnqueueWorkList(WL, S);
2343 break;
2344 }
2345 continue;
2346 }
2347 case VisitorJob::MemberExprPartsKind: {
2348 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002349 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002350
2351 // Visit the nested-name-specifier
2352 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2353 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2354 return true;
2355
2356 // Visit the declaration name.
2357 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2358 return true;
2359
2360 // Visit the explicitly-specified template arguments, if any.
2361 if (M->hasExplicitTemplateArgs()) {
2362 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2363 *ArgEnd = Arg + M->getNumTemplateArgs();
2364 Arg != ArgEnd; ++Arg) {
2365 if (VisitTemplateArgumentLoc(*Arg))
2366 return true;
2367 }
2368 }
2369 continue;
2370 }
2371 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002372 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002373 // Visit nested-name-specifier, if present.
2374 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2375 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2376 return true;
2377 // Visit declaration name.
2378 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2379 return true;
2380 continue;
2381 }
2382 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002383 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002384 // Visit the nested-name-specifier.
2385 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit the declaration name.
2389 if (VisitDeclarationNameInfo(O->getNameInfo()))
2390 return true;
2391 // Visit the overloaded declaration reference.
2392 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2393 return true;
2394 continue;
2395 }
2396 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002397 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002398 NamedDecl *Pack = E->getPack();
2399 if (isa<TemplateTypeParmDecl>(Pack)) {
2400 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2401 E->getPackLoc(), TU)))
2402 return true;
2403
2404 continue;
2405 }
2406
2407 if (isa<TemplateTemplateParmDecl>(Pack)) {
2408 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2409 E->getPackLoc(), TU)))
2410 return true;
2411
2412 continue;
2413 }
2414
2415 // Non-type template parameter packs and function parameter packs are
2416 // treated like DeclRefExpr cursors.
2417 continue;
2418 }
2419
2420 case VisitorJob::LambdaExprPartsKind: {
2421 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002422 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002423 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2424 CEnd = E->explicit_capture_end();
2425 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002426 // FIXME: Lambda init-captures.
2427 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002428 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002429
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002430 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2431 C->getLocation(),
2432 TU)))
2433 return true;
2434 }
2435
2436 // Visit parameters and return type, if present.
2437 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2438 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2439 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2440 // Visit the whole type.
2441 if (Visit(TL))
2442 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002443 } else if (FunctionProtoTypeLoc Proto =
2444 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002445 if (E->hasExplicitParameters()) {
2446 // Visit parameters.
2447 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2448 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2449 return true;
2450 } else {
2451 // Visit result type.
2452 if (Visit(Proto.getResultLoc()))
2453 return true;
2454 }
2455 }
2456 }
2457 break;
2458 }
2459
2460 case VisitorJob::PostChildrenVisitKind:
2461 if (PostChildrenVisitor(Parent, ClientData))
2462 return true;
2463 break;
2464 }
2465 }
2466 return false;
2467}
2468
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002469bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002470 VisitorWorkList *WL = 0;
2471 if (!WorkListFreeList.empty()) {
2472 WL = WorkListFreeList.back();
2473 WL->clear();
2474 WorkListFreeList.pop_back();
2475 }
2476 else {
2477 WL = new VisitorWorkList();
2478 WorkListCache.push_back(WL);
2479 }
2480 EnqueueWorkList(*WL, S);
2481 bool result = RunVisitorWorkList(*WL);
2482 WorkListFreeList.push_back(WL);
2483 return result;
2484}
2485
2486namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002487typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002488RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2489 const DeclarationNameInfo &NI,
2490 const SourceRange &QLoc,
2491 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2492 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2493 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2494 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2495
2496 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2497
2498 RefNamePieces Pieces;
2499
2500 if (WantQualifier && QLoc.isValid())
2501 Pieces.push_back(QLoc);
2502
2503 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2504 Pieces.push_back(NI.getLoc());
2505
2506 if (WantTemplateArgs && TemplateArgs)
2507 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2508 TemplateArgs->RAngleLoc));
2509
2510 if (Kind == DeclarationName::CXXOperatorName) {
2511 Pieces.push_back(SourceLocation::getFromRawEncoding(
2512 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2513 Pieces.push_back(SourceLocation::getFromRawEncoding(
2514 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2515 }
2516
2517 if (WantSinglePiece) {
2518 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2519 Pieces.clear();
2520 Pieces.push_back(R);
2521 }
2522
2523 return Pieces;
2524}
2525}
2526
2527//===----------------------------------------------------------------------===//
2528// Misc. API hooks.
2529//===----------------------------------------------------------------------===//
2530
2531static llvm::sys::Mutex EnableMultithreadingMutex;
2532static bool EnabledMultithreading;
2533
Chad Rosier90836282013-03-27 18:28:23 +00002534static void fatal_error_handler(void *user_data, const std::string& reason,
2535 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002536 // Write the result out to stderr avoiding errs() because raw_ostreams can
2537 // call report_fatal_error.
2538 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2539 ::abort();
2540}
2541
2542extern "C" {
2543CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2544 int displayDiagnostics) {
2545 // Disable pretty stack trace functionality, which will otherwise be a very
2546 // poor citizen of the world and set up all sorts of signal handlers.
2547 llvm::DisablePrettyStackTrace = true;
2548
2549 // We use crash recovery to make some of our APIs more reliable, implicitly
2550 // enable it.
2551 llvm::CrashRecoveryContext::Enable();
2552
2553 // Enable support for multithreading in LLVM.
2554 {
2555 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2556 if (!EnabledMultithreading) {
2557 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2558 llvm::llvm_start_multithreaded();
2559 EnabledMultithreading = true;
2560 }
2561 }
2562
2563 CIndexer *CIdxr = new CIndexer();
2564 if (excludeDeclarationsFromPCH)
2565 CIdxr->setOnlyLocalDecls();
2566 if (displayDiagnostics)
2567 CIdxr->setDisplayDiagnostics();
2568
2569 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2570 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2571 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2572 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2573 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2574 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2575
2576 return CIdxr;
2577}
2578
2579void clang_disposeIndex(CXIndex CIdx) {
2580 if (CIdx)
2581 delete static_cast<CIndexer *>(CIdx);
2582}
2583
2584void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2585 if (CIdx)
2586 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2587}
2588
2589unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2590 if (CIdx)
2591 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2592 return 0;
2593}
2594
2595void clang_toggleCrashRecovery(unsigned isEnabled) {
2596 if (isEnabled)
2597 llvm::CrashRecoveryContext::Enable();
2598 else
2599 llvm::CrashRecoveryContext::Disable();
2600}
2601
2602CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2603 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002604 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002605 return 0;
2606
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002607 LOG_FUNC_SECTION {
2608 *Log << ast_filename;
2609 }
2610
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002611 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2612 FileSystemOptions FileSystemOpts;
2613
2614 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2615 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2616 CXXIdx->getOnlyLocalDecls(),
2617 0, 0,
2618 /*CaptureDiagnostics=*/true,
2619 /*AllowPCHWithCompilerErrors=*/true,
2620 /*UserFilesAreVolatile=*/true);
2621 return MakeCXTranslationUnit(CXXIdx, TU);
2622}
2623
2624unsigned clang_defaultEditingTranslationUnitOptions() {
2625 return CXTranslationUnit_PrecompiledPreamble |
2626 CXTranslationUnit_CacheCompletionResults;
2627}
2628
2629CXTranslationUnit
2630clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2631 const char *source_filename,
2632 int num_command_line_args,
2633 const char * const *command_line_args,
2634 unsigned num_unsaved_files,
2635 struct CXUnsavedFile *unsaved_files) {
2636 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2637 return clang_parseTranslationUnit(CIdx, source_filename,
2638 command_line_args, num_command_line_args,
2639 unsaved_files, num_unsaved_files,
2640 Options);
2641}
2642
2643struct ParseTranslationUnitInfo {
2644 CXIndex CIdx;
2645 const char *source_filename;
2646 const char *const *command_line_args;
2647 int num_command_line_args;
2648 struct CXUnsavedFile *unsaved_files;
2649 unsigned num_unsaved_files;
2650 unsigned options;
2651 CXTranslationUnit result;
2652};
2653static void clang_parseTranslationUnit_Impl(void *UserData) {
2654 ParseTranslationUnitInfo *PTUI =
2655 static_cast<ParseTranslationUnitInfo*>(UserData);
2656 CXIndex CIdx = PTUI->CIdx;
2657 const char *source_filename = PTUI->source_filename;
2658 const char * const *command_line_args = PTUI->command_line_args;
2659 int num_command_line_args = PTUI->num_command_line_args;
2660 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2661 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2662 unsigned options = PTUI->options;
2663 PTUI->result = 0;
2664
2665 if (!CIdx)
2666 return;
2667
2668 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2669
2670 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2671 setThreadBackgroundPriority();
2672
2673 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2674 // FIXME: Add a flag for modules.
2675 TranslationUnitKind TUKind
2676 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2677 bool CacheCodeCompetionResults
2678 = options & CXTranslationUnit_CacheCompletionResults;
2679 bool IncludeBriefCommentsInCodeCompletion
2680 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2681 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2682 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2683
2684 // Configure the diagnostics.
2685 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002686 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002687
2688 // Recover resources if we crash before exiting this function.
2689 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2690 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2691 DiagCleanup(Diags.getPtr());
2692
2693 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2694 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2695
2696 // Recover resources if we crash before exiting this function.
2697 llvm::CrashRecoveryContextCleanupRegistrar<
2698 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2699
2700 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2701 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2702 const llvm::MemoryBuffer *Buffer
2703 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2704 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2705 Buffer));
2706 }
2707
2708 OwningPtr<std::vector<const char *> >
2709 Args(new std::vector<const char*>());
2710
2711 // Recover resources if we crash before exiting this method.
2712 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2713 ArgsCleanup(Args.get());
2714
2715 // Since the Clang C library is primarily used by batch tools dealing with
2716 // (often very broken) source code, where spell-checking can have a
2717 // significant negative impact on performance (particularly when
2718 // precompiled headers are involved), we disable it by default.
2719 // Only do this if we haven't found a spell-checking-related argument.
2720 bool FoundSpellCheckingArgument = false;
2721 for (int I = 0; I != num_command_line_args; ++I) {
2722 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2723 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2724 FoundSpellCheckingArgument = true;
2725 break;
2726 }
2727 }
2728 if (!FoundSpellCheckingArgument)
2729 Args->push_back("-fno-spell-checking");
2730
2731 Args->insert(Args->end(), command_line_args,
2732 command_line_args + num_command_line_args);
2733
2734 // The 'source_filename' argument is optional. If the caller does not
2735 // specify it then it is assumed that the source file is specified
2736 // in the actual argument list.
2737 // Put the source file after command_line_args otherwise if '-x' flag is
2738 // present it will be unused.
2739 if (source_filename)
2740 Args->push_back(source_filename);
2741
2742 // Do we need the detailed preprocessing record?
2743 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2744 Args->push_back("-Xclang");
2745 Args->push_back("-detailed-preprocessing-record");
2746 }
2747
2748 unsigned NumErrors = Diags->getClient()->getNumErrors();
2749 OwningPtr<ASTUnit> ErrUnit;
2750 OwningPtr<ASTUnit> Unit(
2751 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2752 /* vector::data() not portable */,
2753 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2754 Diags,
2755 CXXIdx->getClangResourcesPath(),
2756 CXXIdx->getOnlyLocalDecls(),
2757 /*CaptureDiagnostics=*/true,
2758 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2759 RemappedFiles->size(),
2760 /*RemappedFilesKeepOriginalName=*/true,
2761 PrecompilePreamble,
2762 TUKind,
2763 CacheCodeCompetionResults,
2764 IncludeBriefCommentsInCodeCompletion,
2765 /*AllowPCHWithCompilerErrors=*/true,
2766 SkipFunctionBodies,
2767 /*UserFilesAreVolatile=*/true,
2768 ForSerialization,
2769 &ErrUnit));
2770
2771 if (NumErrors != Diags->getClient()->getNumErrors()) {
2772 // Make sure to check that 'Unit' is non-NULL.
2773 if (CXXIdx->getDisplayDiagnostics())
2774 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2775 }
2776
2777 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2778}
2779CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2780 const char *source_filename,
2781 const char * const *command_line_args,
2782 int num_command_line_args,
2783 struct CXUnsavedFile *unsaved_files,
2784 unsigned num_unsaved_files,
2785 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002786 LOG_FUNC_SECTION {
2787 *Log << source_filename << ": ";
2788 for (int i = 0; i != num_command_line_args; ++i)
2789 *Log << command_line_args[i] << " ";
2790 }
2791
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002792 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2793 num_command_line_args, unsaved_files,
2794 num_unsaved_files, options, 0 };
2795 llvm::CrashRecoveryContext CRC;
2796
2797 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2798 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2799 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2800 fprintf(stderr, " 'command_line_args' : [");
2801 for (int i = 0; i != num_command_line_args; ++i) {
2802 if (i)
2803 fprintf(stderr, ", ");
2804 fprintf(stderr, "'%s'", command_line_args[i]);
2805 }
2806 fprintf(stderr, "],\n");
2807 fprintf(stderr, " 'unsaved_files' : [");
2808 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2809 if (i)
2810 fprintf(stderr, ", ");
2811 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2812 unsaved_files[i].Length);
2813 }
2814 fprintf(stderr, "],\n");
2815 fprintf(stderr, " 'options' : %d,\n", options);
2816 fprintf(stderr, "}\n");
2817
2818 return 0;
2819 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2820 PrintLibclangResourceUsage(PTUI.result);
2821 }
2822
2823 return PTUI.result;
2824}
2825
2826unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2827 return CXSaveTranslationUnit_None;
2828}
2829
2830namespace {
2831
2832struct SaveTranslationUnitInfo {
2833 CXTranslationUnit TU;
2834 const char *FileName;
2835 unsigned options;
2836 CXSaveError result;
2837};
2838
2839}
2840
2841static void clang_saveTranslationUnit_Impl(void *UserData) {
2842 SaveTranslationUnitInfo *STUI =
2843 static_cast<SaveTranslationUnitInfo*>(UserData);
2844
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002845 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002846 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2847 setThreadBackgroundPriority();
2848
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002849 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002850 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2851}
2852
2853int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2854 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002855 LOG_FUNC_SECTION {
2856 *Log << TU << ' ' << FileName;
2857 }
2858
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002859 if (!TU)
2860 return CXSaveError_InvalidTU;
2861
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002862 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002863 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2864 if (!CXXUnit->hasSema())
2865 return CXSaveError_InvalidTU;
2866
2867 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2868
2869 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2870 getenv("LIBCLANG_NOTHREADS")) {
2871 clang_saveTranslationUnit_Impl(&STUI);
2872
2873 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2874 PrintLibclangResourceUsage(TU);
2875
2876 return STUI.result;
2877 }
2878
2879 // We have an AST that has invalid nodes due to compiler errors.
2880 // Use a crash recovery thread for protection.
2881
2882 llvm::CrashRecoveryContext CRC;
2883
2884 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2885 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2886 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2887 fprintf(stderr, " 'options' : %d,\n", options);
2888 fprintf(stderr, "}\n");
2889
2890 return CXSaveError_Unknown;
2891
2892 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2893 PrintLibclangResourceUsage(TU);
2894 }
2895
2896 return STUI.result;
2897}
2898
2899void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2900 if (CTUnit) {
2901 // If the translation unit has been marked as unsafe to free, just discard
2902 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002903 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002904 return;
2905
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002906 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002907 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002908 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2909 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002910 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002911 delete CTUnit;
2912 }
2913}
2914
2915unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2916 return CXReparse_None;
2917}
2918
2919struct ReparseTranslationUnitInfo {
2920 CXTranslationUnit TU;
2921 unsigned num_unsaved_files;
2922 struct CXUnsavedFile *unsaved_files;
2923 unsigned options;
2924 int result;
2925};
2926
2927static void clang_reparseTranslationUnit_Impl(void *UserData) {
2928 ReparseTranslationUnitInfo *RTUI =
2929 static_cast<ReparseTranslationUnitInfo*>(UserData);
2930 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002931 if (!TU)
2932 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002933
2934 // Reset the associated diagnostics.
2935 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2936 TU->Diagnostics = 0;
2937
2938 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2939 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2940 unsigned options = RTUI->options;
2941 (void) options;
2942 RTUI->result = 1;
2943
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002944 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002945 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2946 setThreadBackgroundPriority();
2947
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002948 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002949 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2950
2951 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2952 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2953
2954 // Recover resources if we crash before exiting this function.
2955 llvm::CrashRecoveryContextCleanupRegistrar<
2956 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2957
2958 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2959 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2960 const llvm::MemoryBuffer *Buffer
2961 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2962 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2963 Buffer));
2964 }
2965
2966 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2967 RemappedFiles->size()))
2968 RTUI->result = 0;
2969}
2970
2971int clang_reparseTranslationUnit(CXTranslationUnit TU,
2972 unsigned num_unsaved_files,
2973 struct CXUnsavedFile *unsaved_files,
2974 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002975 LOG_FUNC_SECTION {
2976 *Log << TU;
2977 }
2978
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002979 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2980 options, 0 };
2981
2982 if (getenv("LIBCLANG_NOTHREADS")) {
2983 clang_reparseTranslationUnit_Impl(&RTUI);
2984 return RTUI.result;
2985 }
2986
2987 llvm::CrashRecoveryContext CRC;
2988
2989 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2990 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002991 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002992 return 1;
2993 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2994 PrintLibclangResourceUsage(TU);
2995
2996 return RTUI.result;
2997}
2998
2999
3000CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3001 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003002 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003003
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003004 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003005 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003006}
3007
3008CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003009 if (!TU)
3010 return clang_getNullCursor();
3011
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003012 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003013 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3014}
3015
3016} // end: extern "C"
3017
3018//===----------------------------------------------------------------------===//
3019// CXFile Operations.
3020//===----------------------------------------------------------------------===//
3021
3022extern "C" {
3023CXString clang_getFileName(CXFile SFile) {
3024 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00003025 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003026
3027 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003028 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003029}
3030
3031time_t clang_getFileTime(CXFile SFile) {
3032 if (!SFile)
3033 return 0;
3034
3035 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3036 return FEnt->getModificationTime();
3037}
3038
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003039CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3040 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003041 return 0;
3042
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003043 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003044
3045 FileManager &FMgr = CXXUnit->getFileManager();
3046 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3047}
3048
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003049unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3050 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return 0;
3052
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003053 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003054 FileEntry *FEnt = static_cast<FileEntry *>(file);
3055 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3056 .isFileMultipleIncludeGuarded(FEnt);
3057}
3058
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003059int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3060 if (!file || !outID)
3061 return 1;
3062
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003063 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-08-01 21:42:11 +00003064 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3065 outID->data[0] = ID.getDevice();
3066 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003067 outID->data[2] = FEnt->getModificationTime();
3068 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003069}
3070
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003071} // end: extern "C"
3072
3073//===----------------------------------------------------------------------===//
3074// CXCursor Operations.
3075//===----------------------------------------------------------------------===//
3076
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003077static const Decl *getDeclFromExpr(const Stmt *E) {
3078 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003079 return getDeclFromExpr(CE->getSubExpr());
3080
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003081 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003082 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003083 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003084 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003085 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003086 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003087 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003088 if (PRE->isExplicitProperty())
3089 return PRE->getExplicitProperty();
3090 // It could be messaging both getter and setter as in:
3091 // ++myobj.myprop;
3092 // in which case prefer to associate the setter since it is less obvious
3093 // from inspecting the source that the setter is going to get called.
3094 if (PRE->isMessagingSetter())
3095 return PRE->getImplicitPropertySetter();
3096 return PRE->getImplicitPropertyGetter();
3097 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003098 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003099 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003100 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003101 if (Expr *Src = OVE->getSourceExpr())
3102 return getDeclFromExpr(Src);
3103
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003104 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003105 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003106 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003107 if (!CE->isElidable())
3108 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003109 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003110 return OME->getMethodDecl();
3111
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003112 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003113 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003114 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003115 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3116 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003117 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003118 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3119 isa<ParmVarDecl>(SizeOfPack->getPack()))
3120 return SizeOfPack->getPack();
3121
3122 return 0;
3123}
3124
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003125static SourceLocation getLocationFromExpr(const Expr *E) {
3126 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003127 return getLocationFromExpr(CE->getSubExpr());
3128
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003129 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003130 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003131 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003132 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003133 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003134 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003135 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003136 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003137 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003138 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003139 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003140 return PropRef->getLocation();
3141
3142 return E->getLocStart();
3143}
3144
3145extern "C" {
3146
3147unsigned clang_visitChildren(CXCursor parent,
3148 CXCursorVisitor visitor,
3149 CXClientData client_data) {
3150 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3151 /*VisitPreprocessorLast=*/false);
3152 return CursorVis.VisitChildren(parent);
3153}
3154
3155#ifndef __has_feature
3156#define __has_feature(x) 0
3157#endif
3158#if __has_feature(blocks)
3159typedef enum CXChildVisitResult
3160 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3161
3162static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3163 CXClientData client_data) {
3164 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3165 return block(cursor, parent);
3166}
3167#else
3168// If we are compiled with a compiler that doesn't have native blocks support,
3169// define and call the block manually, so the
3170typedef struct _CXChildVisitResult
3171{
3172 void *isa;
3173 int flags;
3174 int reserved;
3175 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3176 CXCursor);
3177} *CXCursorVisitorBlock;
3178
3179static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3180 CXClientData client_data) {
3181 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3182 return block->invoke(block, cursor, parent);
3183}
3184#endif
3185
3186
3187unsigned clang_visitChildrenWithBlock(CXCursor parent,
3188 CXCursorVisitorBlock block) {
3189 return clang_visitChildren(parent, visitWithBlock, block);
3190}
3191
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003192static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003193 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003194 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003196 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003198 if (const ObjCPropertyImplDecl *PropImpl =
3199 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003200 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003201 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003202
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003203 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003204 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003205 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003206
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003207 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003208 }
3209
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003210 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003211 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003212
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003213 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003214 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3215 // and returns different names. NamedDecl returns the class name and
3216 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003217 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003218
3219 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003220 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003221
3222 SmallString<1024> S;
3223 llvm::raw_svector_ostream os(S);
3224 ND->printName(os);
3225
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003226 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003227}
3228
3229CXString clang_getCursorSpelling(CXCursor C) {
3230 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003231 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003232
3233 if (clang_isReference(C.kind)) {
3234 switch (C.kind) {
3235 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003236 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003237 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003238 }
3239 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003240 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003241 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 }
3243 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003244 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003245 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003246 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003247 }
3248 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003249 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003250 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003251 }
3252 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003253 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003254 assert(Type && "Missing type decl");
3255
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003256 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003257 getAsString());
3258 }
3259 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003260 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003261 assert(Template && "Missing template decl");
3262
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003263 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003264 }
3265
3266 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003267 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003268 assert(NS && "Missing namespace decl");
3269
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003270 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003271 }
3272
3273 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003274 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003275 assert(Field && "Missing member decl");
3276
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003277 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003278 }
3279
3280 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003281 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282 assert(Label && "Missing label");
3283
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003284 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003285 }
3286
3287 case CXCursor_OverloadedDeclRef: {
3288 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003289 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3290 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003291 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003292 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003294 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003295 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003296 OverloadedTemplateStorage *Ovl
3297 = Storage.get<OverloadedTemplateStorage*>();
3298 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003299 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003300 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003301 }
3302
3303 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003304 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003305 assert(Var && "Missing variable decl");
3306
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003307 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003308 }
3309
3310 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003311 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003312 }
3313 }
3314
3315 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003316 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003317 if (D)
3318 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003319 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003320 }
3321
3322 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003323 const Stmt *S = getCursorStmt(C);
3324 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003325 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003326
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003327 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003328 }
3329
3330 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003331 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003332 ->getNameStart());
3333
3334 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003335 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003336 ->getNameStart());
3337
3338 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003339 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003340
3341 if (clang_isDeclaration(C.kind))
3342 return getDeclSpelling(getCursorDecl(C));
3343
3344 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003345 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003346 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003347 }
3348
3349 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003350 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003351 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003352 }
3353
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003354 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003355}
3356
3357CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3358 unsigned pieceIndex,
3359 unsigned options) {
3360 if (clang_Cursor_isNull(C))
3361 return clang_getNullRange();
3362
3363 ASTContext &Ctx = getCursorContext(C);
3364
3365 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003366 const Stmt *S = getCursorStmt(C);
3367 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003368 if (pieceIndex > 0)
3369 return clang_getNullRange();
3370 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3371 }
3372
3373 return clang_getNullRange();
3374 }
3375
3376 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003377 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003378 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3379 if (pieceIndex >= ME->getNumSelectorLocs())
3380 return clang_getNullRange();
3381 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3382 }
3383 }
3384
3385 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3386 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003387 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003388 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3389 if (pieceIndex >= MD->getNumSelectorLocs())
3390 return clang_getNullRange();
3391 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3392 }
3393 }
3394
3395 if (C.kind == CXCursor_ObjCCategoryDecl ||
3396 C.kind == CXCursor_ObjCCategoryImplDecl) {
3397 if (pieceIndex > 0)
3398 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003399 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003400 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3401 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003402 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003403 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3404 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3405 }
3406
3407 if (C.kind == CXCursor_ModuleImportDecl) {
3408 if (pieceIndex > 0)
3409 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003410 if (const ImportDecl *ImportD =
3411 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003412 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3413 if (!Locs.empty())
3414 return cxloc::translateSourceRange(Ctx,
3415 SourceRange(Locs.front(), Locs.back()));
3416 }
3417 return clang_getNullRange();
3418 }
3419
3420 // FIXME: A CXCursor_InclusionDirective should give the location of the
3421 // filename, but we don't keep track of this.
3422
3423 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3424 // but we don't keep track of this.
3425
3426 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3427 // but we don't keep track of this.
3428
3429 // Default handling, give the location of the cursor.
3430
3431 if (pieceIndex > 0)
3432 return clang_getNullRange();
3433
3434 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3435 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3436 return cxloc::translateSourceRange(Ctx, Loc);
3437}
3438
3439CXString clang_getCursorDisplayName(CXCursor C) {
3440 if (!clang_isDeclaration(C.kind))
3441 return clang_getCursorSpelling(C);
3442
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003443 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003444 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003445 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003446
3447 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003448 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003449 D = FunTmpl->getTemplatedDecl();
3450
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003451 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003452 SmallString<64> Str;
3453 llvm::raw_svector_ostream OS(Str);
3454 OS << *Function;
3455 if (Function->getPrimaryTemplate())
3456 OS << "<>";
3457 OS << "(";
3458 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3459 if (I)
3460 OS << ", ";
3461 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3462 }
3463
3464 if (Function->isVariadic()) {
3465 if (Function->getNumParams())
3466 OS << ", ";
3467 OS << "...";
3468 }
3469 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003470 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 }
3472
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003473 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003474 SmallString<64> Str;
3475 llvm::raw_svector_ostream OS(Str);
3476 OS << *ClassTemplate;
3477 OS << "<";
3478 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3479 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3480 if (I)
3481 OS << ", ";
3482
3483 NamedDecl *Param = Params->getParam(I);
3484 if (Param->getIdentifier()) {
3485 OS << Param->getIdentifier()->getName();
3486 continue;
3487 }
3488
3489 // There is no parameter name, which makes this tricky. Try to come up
3490 // with something useful that isn't too long.
3491 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3492 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3493 else if (NonTypeTemplateParmDecl *NTTP
3494 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3495 OS << NTTP->getType().getAsString(Policy);
3496 else
3497 OS << "template<...> class";
3498 }
3499
3500 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003501 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003502 }
3503
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003504 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3506 // If the type was explicitly written, use that.
3507 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003508 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509
Benjamin Kramer5eada842013-02-22 15:46:01 +00003510 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 llvm::raw_svector_ostream OS(Str);
3512 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003513 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003514 ClassSpec->getTemplateArgs().data(),
3515 ClassSpec->getTemplateArgs().size(),
3516 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003517 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003518 }
3519
3520 return clang_getCursorSpelling(C);
3521}
3522
3523CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3524 switch (Kind) {
3525 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003653 case CXCursor_ObjCSelfExpr:
3654 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003742 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003743 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003744 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003745 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003746 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003747 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003748 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003749 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003750 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003751 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003752 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003753 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003754 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003755 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003757 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003758 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003759 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003760 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003761 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003762 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003763 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003764 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003765 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003766 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003767 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003768 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003769 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003770 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003771 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003772 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003773 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003774 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003775 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003776 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003777 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003778 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003779 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003780 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003781 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003782 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003783 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003784 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003785 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003787 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003789 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003791 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003792 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003793 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003794 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003795 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003796 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003797 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003798 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003799 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003800 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003801 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003802 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003803 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003804 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003805 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003806 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003807 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003808 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003809 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003810 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003811 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003813 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003815 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003816 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003817 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003818 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003819 case CXCursor_OMPParallelDirective:
3820 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003821 }
3822
3823 llvm_unreachable("Unhandled CXCursorKind");
3824}
3825
3826struct GetCursorData {
3827 SourceLocation TokenBeginLoc;
3828 bool PointsAtMacroArgExpansion;
3829 bool VisitedObjCPropertyImplDecl;
3830 SourceLocation VisitedDeclaratorDeclStartLoc;
3831 CXCursor &BestCursor;
3832
3833 GetCursorData(SourceManager &SM,
3834 SourceLocation tokenBegin, CXCursor &outputCursor)
3835 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3836 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3837 VisitedObjCPropertyImplDecl = false;
3838 }
3839};
3840
3841static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3842 CXCursor parent,
3843 CXClientData client_data) {
3844 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3845 CXCursor *BestCursor = &Data->BestCursor;
3846
3847 // If we point inside a macro argument we should provide info of what the
3848 // token is so use the actual cursor, don't replace it with a macro expansion
3849 // cursor.
3850 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3851 return CXChildVisit_Recurse;
3852
3853 if (clang_isDeclaration(cursor.kind)) {
3854 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003855 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003856 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3857 if (MD->isImplicit())
3858 return CXChildVisit_Break;
3859
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003860 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003861 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3862 // Check that when we have multiple @class references in the same line,
3863 // that later ones do not override the previous ones.
3864 // If we have:
3865 // @class Foo, Bar;
3866 // source ranges for both start at '@', so 'Bar' will end up overriding
3867 // 'Foo' even though the cursor location was at 'Foo'.
3868 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3869 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003870 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003871 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3872 if (PrevID != ID &&
3873 !PrevID->isThisDeclarationADefinition() &&
3874 !ID->isThisDeclarationADefinition())
3875 return CXChildVisit_Break;
3876 }
3877
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003878 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003879 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3880 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3881 // Check that when we have multiple declarators in the same line,
3882 // that later ones do not override the previous ones.
3883 // If we have:
3884 // int Foo, Bar;
3885 // source ranges for both start at 'int', so 'Bar' will end up overriding
3886 // 'Foo' even though the cursor location was at 'Foo'.
3887 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3888 return CXChildVisit_Break;
3889 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3890
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003891 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003892 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3893 (void)PropImp;
3894 // Check that when we have multiple @synthesize in the same line,
3895 // that later ones do not override the previous ones.
3896 // If we have:
3897 // @synthesize Foo, Bar;
3898 // source ranges for both start at '@', so 'Bar' will end up overriding
3899 // 'Foo' even though the cursor location was at 'Foo'.
3900 if (Data->VisitedObjCPropertyImplDecl)
3901 return CXChildVisit_Break;
3902 Data->VisitedObjCPropertyImplDecl = true;
3903 }
3904 }
3905
3906 if (clang_isExpression(cursor.kind) &&
3907 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003908 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003909 // Avoid having the cursor of an expression replace the declaration cursor
3910 // when the expression source range overlaps the declaration range.
3911 // This can happen for C++ constructor expressions whose range generally
3912 // include the variable declaration, e.g.:
3913 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3914 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3915 D->getLocation() == Data->TokenBeginLoc)
3916 return CXChildVisit_Break;
3917 }
3918 }
3919
3920 // If our current best cursor is the construction of a temporary object,
3921 // don't replace that cursor with a type reference, because we want
3922 // clang_getCursor() to point at the constructor.
3923 if (clang_isExpression(BestCursor->kind) &&
3924 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3925 cursor.kind == CXCursor_TypeRef) {
3926 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3927 // as having the actual point on the type reference.
3928 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3929 return CXChildVisit_Recurse;
3930 }
3931
3932 *BestCursor = cursor;
3933 return CXChildVisit_Recurse;
3934}
3935
3936CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3937 if (!TU)
3938 return clang_getNullCursor();
3939
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003940 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003941 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3942
3943 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3944 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3945
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003946 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003947 CXFile SearchFile;
3948 unsigned SearchLine, SearchColumn;
3949 CXFile ResultFile;
3950 unsigned ResultLine, ResultColumn;
3951 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3952 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3953 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3954
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003955 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3956 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003957 &ResultColumn, 0);
3958 SearchFileName = clang_getFileName(SearchFile);
3959 ResultFileName = clang_getFileName(ResultFile);
3960 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3961 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003962 *Log << llvm::format("(%s:%d:%d) = %s",
3963 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3964 clang_getCString(KindSpelling))
3965 << llvm::format("(%s:%d:%d):%s%s",
3966 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3967 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003968 clang_disposeString(SearchFileName);
3969 clang_disposeString(ResultFileName);
3970 clang_disposeString(KindSpelling);
3971 clang_disposeString(USR);
3972
3973 CXCursor Definition = clang_getCursorDefinition(Result);
3974 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3975 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3976 CXString DefinitionKindSpelling
3977 = clang_getCursorKindSpelling(Definition.kind);
3978 CXFile DefinitionFile;
3979 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003980 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003981 &DefinitionLine, &DefinitionColumn, 0);
3982 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003983 *Log << llvm::format(" -> %s(%s:%d:%d)",
3984 clang_getCString(DefinitionKindSpelling),
3985 clang_getCString(DefinitionFileName),
3986 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003987 clang_disposeString(DefinitionFileName);
3988 clang_disposeString(DefinitionKindSpelling);
3989 }
3990 }
3991
3992 return Result;
3993}
3994
3995CXCursor clang_getNullCursor(void) {
3996 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3997}
3998
3999unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00004000 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4001 // can't set consistently. For example, when visiting a DeclStmt we will set
4002 // it but we don't set it on the result of clang_getCursorDefinition for
4003 // a reference of the same declaration.
4004 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4005 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4006 // to provide that kind of info.
4007 if (clang_isDeclaration(X.kind))
4008 X.data[1] = 0;
4009 if (clang_isDeclaration(Y.kind))
4010 Y.data[1] = 0;
4011
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004012 return X == Y;
4013}
4014
4015unsigned clang_hashCursor(CXCursor C) {
4016 unsigned Index = 0;
4017 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4018 Index = 1;
4019
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004020 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004021 std::make_pair(C.kind, C.data[Index]));
4022}
4023
4024unsigned clang_isInvalid(enum CXCursorKind K) {
4025 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4026}
4027
4028unsigned clang_isDeclaration(enum CXCursorKind K) {
4029 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4030 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4031}
4032
4033unsigned clang_isReference(enum CXCursorKind K) {
4034 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4035}
4036
4037unsigned clang_isExpression(enum CXCursorKind K) {
4038 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4039}
4040
4041unsigned clang_isStatement(enum CXCursorKind K) {
4042 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4043}
4044
4045unsigned clang_isAttribute(enum CXCursorKind K) {
4046 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4047}
4048
4049unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4050 return K == CXCursor_TranslationUnit;
4051}
4052
4053unsigned clang_isPreprocessing(enum CXCursorKind K) {
4054 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4055}
4056
4057unsigned clang_isUnexposed(enum CXCursorKind K) {
4058 switch (K) {
4059 case CXCursor_UnexposedDecl:
4060 case CXCursor_UnexposedExpr:
4061 case CXCursor_UnexposedStmt:
4062 case CXCursor_UnexposedAttr:
4063 return true;
4064 default:
4065 return false;
4066 }
4067}
4068
4069CXCursorKind clang_getCursorKind(CXCursor C) {
4070 return C.kind;
4071}
4072
4073CXSourceLocation clang_getCursorLocation(CXCursor C) {
4074 if (clang_isReference(C.kind)) {
4075 switch (C.kind) {
4076 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004077 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004078 = getCursorObjCSuperClassRef(C);
4079 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4080 }
4081
4082 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004083 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004084 = getCursorObjCProtocolRef(C);
4085 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4086 }
4087
4088 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004089 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004090 = getCursorObjCClassRef(C);
4091 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4092 }
4093
4094 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004095 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004096 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4097 }
4098
4099 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004100 std::pair<const TemplateDecl *, SourceLocation> P =
4101 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004102 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4103 }
4104
4105 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004106 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004107 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4108 }
4109
4110 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004111 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004112 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4113 }
4114
4115 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004116 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004117 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4118 }
4119
4120 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004121 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004122 if (!BaseSpec)
4123 return clang_getNullLocation();
4124
4125 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4126 return cxloc::translateSourceLocation(getCursorContext(C),
4127 TSInfo->getTypeLoc().getBeginLoc());
4128
4129 return cxloc::translateSourceLocation(getCursorContext(C),
4130 BaseSpec->getLocStart());
4131 }
4132
4133 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004134 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004135 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4136 }
4137
4138 case CXCursor_OverloadedDeclRef:
4139 return cxloc::translateSourceLocation(getCursorContext(C),
4140 getCursorOverloadedDeclRef(C).second);
4141
4142 default:
4143 // FIXME: Need a way to enumerate all non-reference cases.
4144 llvm_unreachable("Missed a reference kind");
4145 }
4146 }
4147
4148 if (clang_isExpression(C.kind))
4149 return cxloc::translateSourceLocation(getCursorContext(C),
4150 getLocationFromExpr(getCursorExpr(C)));
4151
4152 if (clang_isStatement(C.kind))
4153 return cxloc::translateSourceLocation(getCursorContext(C),
4154 getCursorStmt(C)->getLocStart());
4155
4156 if (C.kind == CXCursor_PreprocessingDirective) {
4157 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4158 return cxloc::translateSourceLocation(getCursorContext(C), L);
4159 }
4160
4161 if (C.kind == CXCursor_MacroExpansion) {
4162 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004163 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004164 return cxloc::translateSourceLocation(getCursorContext(C), L);
4165 }
4166
4167 if (C.kind == CXCursor_MacroDefinition) {
4168 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4169 return cxloc::translateSourceLocation(getCursorContext(C), L);
4170 }
4171
4172 if (C.kind == CXCursor_InclusionDirective) {
4173 SourceLocation L
4174 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4175 return cxloc::translateSourceLocation(getCursorContext(C), L);
4176 }
4177
4178 if (!clang_isDeclaration(C.kind))
4179 return clang_getNullLocation();
4180
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004181 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004182 if (!D)
4183 return clang_getNullLocation();
4184
4185 SourceLocation Loc = D->getLocation();
4186 // FIXME: Multiple variables declared in a single declaration
4187 // currently lack the information needed to correctly determine their
4188 // ranges when accounting for the type-specifier. We use context
4189 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4190 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004191 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004192 if (!cxcursor::isFirstInDeclGroup(C))
4193 Loc = VD->getLocation();
4194 }
4195
4196 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004197 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004198 Loc = MD->getSelectorStartLoc();
4199
4200 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4201}
4202
4203} // end extern "C"
4204
4205CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4206 assert(TU);
4207
4208 // Guard against an invalid SourceLocation, or we may assert in one
4209 // of the following calls.
4210 if (SLoc.isInvalid())
4211 return clang_getNullCursor();
4212
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004213 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004214
4215 // Translate the given source location to make it point at the beginning of
4216 // the token under the cursor.
4217 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4218 CXXUnit->getASTContext().getLangOpts());
4219
4220 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4221 if (SLoc.isValid()) {
4222 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4223 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4224 /*VisitPreprocessorLast=*/true,
4225 /*VisitIncludedEntities=*/false,
4226 SourceLocation(SLoc));
4227 CursorVis.visitFileRegion();
4228 }
4229
4230 return Result;
4231}
4232
4233static SourceRange getRawCursorExtent(CXCursor C) {
4234 if (clang_isReference(C.kind)) {
4235 switch (C.kind) {
4236 case CXCursor_ObjCSuperClassRef:
4237 return getCursorObjCSuperClassRef(C).second;
4238
4239 case CXCursor_ObjCProtocolRef:
4240 return getCursorObjCProtocolRef(C).second;
4241
4242 case CXCursor_ObjCClassRef:
4243 return getCursorObjCClassRef(C).second;
4244
4245 case CXCursor_TypeRef:
4246 return getCursorTypeRef(C).second;
4247
4248 case CXCursor_TemplateRef:
4249 return getCursorTemplateRef(C).second;
4250
4251 case CXCursor_NamespaceRef:
4252 return getCursorNamespaceRef(C).second;
4253
4254 case CXCursor_MemberRef:
4255 return getCursorMemberRef(C).second;
4256
4257 case CXCursor_CXXBaseSpecifier:
4258 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4259
4260 case CXCursor_LabelRef:
4261 return getCursorLabelRef(C).second;
4262
4263 case CXCursor_OverloadedDeclRef:
4264 return getCursorOverloadedDeclRef(C).second;
4265
4266 case CXCursor_VariableRef:
4267 return getCursorVariableRef(C).second;
4268
4269 default:
4270 // FIXME: Need a way to enumerate all non-reference cases.
4271 llvm_unreachable("Missed a reference kind");
4272 }
4273 }
4274
4275 if (clang_isExpression(C.kind))
4276 return getCursorExpr(C)->getSourceRange();
4277
4278 if (clang_isStatement(C.kind))
4279 return getCursorStmt(C)->getSourceRange();
4280
4281 if (clang_isAttribute(C.kind))
4282 return getCursorAttr(C)->getRange();
4283
4284 if (C.kind == CXCursor_PreprocessingDirective)
4285 return cxcursor::getCursorPreprocessingDirective(C);
4286
4287 if (C.kind == CXCursor_MacroExpansion) {
4288 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004289 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004290 return TU->mapRangeFromPreamble(Range);
4291 }
4292
4293 if (C.kind == CXCursor_MacroDefinition) {
4294 ASTUnit *TU = getCursorASTUnit(C);
4295 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4296 return TU->mapRangeFromPreamble(Range);
4297 }
4298
4299 if (C.kind == CXCursor_InclusionDirective) {
4300 ASTUnit *TU = getCursorASTUnit(C);
4301 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4302 return TU->mapRangeFromPreamble(Range);
4303 }
4304
4305 if (C.kind == CXCursor_TranslationUnit) {
4306 ASTUnit *TU = getCursorASTUnit(C);
4307 FileID MainID = TU->getSourceManager().getMainFileID();
4308 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4309 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4310 return SourceRange(Start, End);
4311 }
4312
4313 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004314 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004315 if (!D)
4316 return SourceRange();
4317
4318 SourceRange R = D->getSourceRange();
4319 // FIXME: Multiple variables declared in a single declaration
4320 // currently lack the information needed to correctly determine their
4321 // ranges when accounting for the type-specifier. We use context
4322 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4323 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004324 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004325 if (!cxcursor::isFirstInDeclGroup(C))
4326 R.setBegin(VD->getLocation());
4327 }
4328 return R;
4329 }
4330 return SourceRange();
4331}
4332
4333/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4334/// the decl-specifier-seq for declarations.
4335static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4336 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004337 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004338 if (!D)
4339 return SourceRange();
4340
4341 SourceRange R = D->getSourceRange();
4342
4343 // Adjust the start of the location for declarations preceded by
4344 // declaration specifiers.
4345 SourceLocation StartLoc;
4346 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4347 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4348 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004349 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004350 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4351 StartLoc = TI->getTypeLoc().getLocStart();
4352 }
4353
4354 if (StartLoc.isValid() && R.getBegin().isValid() &&
4355 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4356 R.setBegin(StartLoc);
4357
4358 // FIXME: Multiple variables declared in a single declaration
4359 // currently lack the information needed to correctly determine their
4360 // ranges when accounting for the type-specifier. We use context
4361 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4362 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004363 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004364 if (!cxcursor::isFirstInDeclGroup(C))
4365 R.setBegin(VD->getLocation());
4366 }
4367
4368 return R;
4369 }
4370
4371 return getRawCursorExtent(C);
4372}
4373
4374extern "C" {
4375
4376CXSourceRange clang_getCursorExtent(CXCursor C) {
4377 SourceRange R = getRawCursorExtent(C);
4378 if (R.isInvalid())
4379 return clang_getNullRange();
4380
4381 return cxloc::translateSourceRange(getCursorContext(C), R);
4382}
4383
4384CXCursor clang_getCursorReferenced(CXCursor C) {
4385 if (clang_isInvalid(C.kind))
4386 return clang_getNullCursor();
4387
4388 CXTranslationUnit tu = getCursorTU(C);
4389 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004390 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004391 if (!D)
4392 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004393 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004394 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004395 if (const ObjCPropertyImplDecl *PropImpl =
4396 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004397 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4398 return MakeCXCursor(Property, tu);
4399
4400 return C;
4401 }
4402
4403 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004404 const Expr *E = getCursorExpr(C);
4405 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004406 if (D) {
4407 CXCursor declCursor = MakeCXCursor(D, tu);
4408 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4409 declCursor);
4410 return declCursor;
4411 }
4412
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004413 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004414 return MakeCursorOverloadedDeclRef(Ovl, tu);
4415
4416 return clang_getNullCursor();
4417 }
4418
4419 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004420 const Stmt *S = getCursorStmt(C);
4421 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004422 if (LabelDecl *label = Goto->getLabel())
4423 if (LabelStmt *labelS = label->getStmt())
4424 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4425
4426 return clang_getNullCursor();
4427 }
4428
4429 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004430 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004431 return MakeMacroDefinitionCursor(Def, tu);
4432 }
4433
4434 if (!clang_isReference(C.kind))
4435 return clang_getNullCursor();
4436
4437 switch (C.kind) {
4438 case CXCursor_ObjCSuperClassRef:
4439 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4440
4441 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004442 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4443 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004444 return MakeCXCursor(Def, tu);
4445
4446 return MakeCXCursor(Prot, tu);
4447 }
4448
4449 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004450 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4451 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004452 return MakeCXCursor(Def, tu);
4453
4454 return MakeCXCursor(Class, tu);
4455 }
4456
4457 case CXCursor_TypeRef:
4458 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4459
4460 case CXCursor_TemplateRef:
4461 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4462
4463 case CXCursor_NamespaceRef:
4464 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4465
4466 case CXCursor_MemberRef:
4467 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4468
4469 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004470 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004471 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4472 tu ));
4473 }
4474
4475 case CXCursor_LabelRef:
4476 // FIXME: We end up faking the "parent" declaration here because we
4477 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004478 return MakeCXCursor(getCursorLabelRef(C).first,
4479 cxtu::getASTUnit(tu)->getASTContext()
4480 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004481 tu);
4482
4483 case CXCursor_OverloadedDeclRef:
4484 return C;
4485
4486 case CXCursor_VariableRef:
4487 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4488
4489 default:
4490 // We would prefer to enumerate all non-reference cursor kinds here.
4491 llvm_unreachable("Unhandled reference cursor kind");
4492 }
4493}
4494
4495CXCursor clang_getCursorDefinition(CXCursor C) {
4496 if (clang_isInvalid(C.kind))
4497 return clang_getNullCursor();
4498
4499 CXTranslationUnit TU = getCursorTU(C);
4500
4501 bool WasReference = false;
4502 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4503 C = clang_getCursorReferenced(C);
4504 WasReference = true;
4505 }
4506
4507 if (C.kind == CXCursor_MacroExpansion)
4508 return clang_getCursorReferenced(C);
4509
4510 if (!clang_isDeclaration(C.kind))
4511 return clang_getNullCursor();
4512
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004513 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004514 if (!D)
4515 return clang_getNullCursor();
4516
4517 switch (D->getKind()) {
4518 // Declaration kinds that don't really separate the notions of
4519 // declaration and definition.
4520 case Decl::Namespace:
4521 case Decl::Typedef:
4522 case Decl::TypeAlias:
4523 case Decl::TypeAliasTemplate:
4524 case Decl::TemplateTypeParm:
4525 case Decl::EnumConstant:
4526 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004527 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004528 case Decl::IndirectField:
4529 case Decl::ObjCIvar:
4530 case Decl::ObjCAtDefsField:
4531 case Decl::ImplicitParam:
4532 case Decl::ParmVar:
4533 case Decl::NonTypeTemplateParm:
4534 case Decl::TemplateTemplateParm:
4535 case Decl::ObjCCategoryImpl:
4536 case Decl::ObjCImplementation:
4537 case Decl::AccessSpec:
4538 case Decl::LinkageSpec:
4539 case Decl::ObjCPropertyImpl:
4540 case Decl::FileScopeAsm:
4541 case Decl::StaticAssert:
4542 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004543 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004544 case Decl::Label: // FIXME: Is this right??
4545 case Decl::ClassScopeFunctionSpecialization:
4546 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004547 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004548 return C;
4549
4550 // Declaration kinds that don't make any sense here, but are
4551 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004552 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004553 case Decl::TranslationUnit:
4554 break;
4555
4556 // Declaration kinds for which the definition is not resolvable.
4557 case Decl::UnresolvedUsingTypename:
4558 case Decl::UnresolvedUsingValue:
4559 break;
4560
4561 case Decl::UsingDirective:
4562 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4563 TU);
4564
4565 case Decl::NamespaceAlias:
4566 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4567
4568 case Decl::Enum:
4569 case Decl::Record:
4570 case Decl::CXXRecord:
4571 case Decl::ClassTemplateSpecialization:
4572 case Decl::ClassTemplatePartialSpecialization:
4573 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4574 return MakeCXCursor(Def, TU);
4575 return clang_getNullCursor();
4576
4577 case Decl::Function:
4578 case Decl::CXXMethod:
4579 case Decl::CXXConstructor:
4580 case Decl::CXXDestructor:
4581 case Decl::CXXConversion: {
4582 const FunctionDecl *Def = 0;
4583 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004584 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004585 return clang_getNullCursor();
4586 }
4587
Larisse Voufoef4579c2013-08-06 01:03:05 +00004588 case Decl::Var:
4589 case Decl::VarTemplateSpecialization:
4590 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004591 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004592 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004593 return MakeCXCursor(Def, TU);
4594 return clang_getNullCursor();
4595 }
4596
4597 case Decl::FunctionTemplate: {
4598 const FunctionDecl *Def = 0;
4599 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4600 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4601 return clang_getNullCursor();
4602 }
4603
4604 case Decl::ClassTemplate: {
4605 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4606 ->getDefinition())
4607 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4608 TU);
4609 return clang_getNullCursor();
4610 }
4611
Larisse Voufoef4579c2013-08-06 01:03:05 +00004612 case Decl::VarTemplate: {
4613 if (VarDecl *Def =
4614 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4615 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4616 return clang_getNullCursor();
4617 }
4618
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004619 case Decl::Using:
4620 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4621 D->getLocation(), TU);
4622
4623 case Decl::UsingShadow:
4624 return clang_getCursorDefinition(
4625 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4626 TU));
4627
4628 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004629 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004630 if (Method->isThisDeclarationADefinition())
4631 return C;
4632
4633 // Dig out the method definition in the associated
4634 // @implementation, if we have it.
4635 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004636 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004637 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4638 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4639 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4640 Method->isInstanceMethod()))
4641 if (Def->isThisDeclarationADefinition())
4642 return MakeCXCursor(Def, TU);
4643
4644 return clang_getNullCursor();
4645 }
4646
4647 case Decl::ObjCCategory:
4648 if (ObjCCategoryImplDecl *Impl
4649 = cast<ObjCCategoryDecl>(D)->getImplementation())
4650 return MakeCXCursor(Impl, TU);
4651 return clang_getNullCursor();
4652
4653 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004654 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004655 return MakeCXCursor(Def, TU);
4656 return clang_getNullCursor();
4657
4658 case Decl::ObjCInterface: {
4659 // There are two notions of a "definition" for an Objective-C
4660 // class: the interface and its implementation. When we resolved a
4661 // reference to an Objective-C class, produce the @interface as
4662 // the definition; when we were provided with the interface,
4663 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004664 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004665 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004666 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004667 return MakeCXCursor(Def, TU);
4668 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4669 return MakeCXCursor(Impl, TU);
4670 return clang_getNullCursor();
4671 }
4672
4673 case Decl::ObjCProperty:
4674 // FIXME: We don't really know where to find the
4675 // ObjCPropertyImplDecls that implement this property.
4676 return clang_getNullCursor();
4677
4678 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004679 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004680 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004681 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004682 return MakeCXCursor(Def, TU);
4683
4684 return clang_getNullCursor();
4685
4686 case Decl::Friend:
4687 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4688 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4689 return clang_getNullCursor();
4690
4691 case Decl::FriendTemplate:
4692 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4693 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4694 return clang_getNullCursor();
4695 }
4696
4697 return clang_getNullCursor();
4698}
4699
4700unsigned clang_isCursorDefinition(CXCursor C) {
4701 if (!clang_isDeclaration(C.kind))
4702 return 0;
4703
4704 return clang_getCursorDefinition(C) == C;
4705}
4706
4707CXCursor clang_getCanonicalCursor(CXCursor C) {
4708 if (!clang_isDeclaration(C.kind))
4709 return C;
4710
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004711 if (const Decl *D = getCursorDecl(C)) {
4712 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004713 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4714 return MakeCXCursor(CatD, getCursorTU(C));
4715
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004716 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4717 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004718 return MakeCXCursor(IFD, getCursorTU(C));
4719
4720 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4721 }
4722
4723 return C;
4724}
4725
4726int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4727 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4728}
4729
4730unsigned clang_getNumOverloadedDecls(CXCursor C) {
4731 if (C.kind != CXCursor_OverloadedDeclRef)
4732 return 0;
4733
4734 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004735 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004736 return E->getNumDecls();
4737
4738 if (OverloadedTemplateStorage *S
4739 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4740 return S->size();
4741
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004742 const Decl *D = Storage.get<const Decl *>();
4743 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004744 return Using->shadow_size();
4745
4746 return 0;
4747}
4748
4749CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4750 if (cursor.kind != CXCursor_OverloadedDeclRef)
4751 return clang_getNullCursor();
4752
4753 if (index >= clang_getNumOverloadedDecls(cursor))
4754 return clang_getNullCursor();
4755
4756 CXTranslationUnit TU = getCursorTU(cursor);
4757 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004758 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004759 return MakeCXCursor(E->decls_begin()[index], TU);
4760
4761 if (OverloadedTemplateStorage *S
4762 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4763 return MakeCXCursor(S->begin()[index], TU);
4764
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004765 const Decl *D = Storage.get<const Decl *>();
4766 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004767 // FIXME: This is, unfortunately, linear time.
4768 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4769 std::advance(Pos, index);
4770 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4771 }
4772
4773 return clang_getNullCursor();
4774}
4775
4776void clang_getDefinitionSpellingAndExtent(CXCursor C,
4777 const char **startBuf,
4778 const char **endBuf,
4779 unsigned *startLine,
4780 unsigned *startColumn,
4781 unsigned *endLine,
4782 unsigned *endColumn) {
4783 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004784 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004785 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4786
4787 SourceManager &SM = FD->getASTContext().getSourceManager();
4788 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4789 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4790 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4791 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4792 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4793 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4794}
4795
4796
4797CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4798 unsigned PieceIndex) {
4799 RefNamePieces Pieces;
4800
4801 switch (C.kind) {
4802 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004803 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004804 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4805 E->getQualifierLoc().getSourceRange());
4806 break;
4807
4808 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004809 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004810 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4811 E->getQualifierLoc().getSourceRange(),
4812 E->getOptionalExplicitTemplateArgs());
4813 break;
4814
4815 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004816 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004817 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004818 const Expr *Callee = OCE->getCallee();
4819 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004820 Callee = ICE->getSubExpr();
4821
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004822 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004823 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4824 DRE->getQualifierLoc().getSourceRange());
4825 }
4826 break;
4827
4828 default:
4829 break;
4830 }
4831
4832 if (Pieces.empty()) {
4833 if (PieceIndex == 0)
4834 return clang_getCursorExtent(C);
4835 } else if (PieceIndex < Pieces.size()) {
4836 SourceRange R = Pieces[PieceIndex];
4837 if (R.isValid())
4838 return cxloc::translateSourceRange(getCursorContext(C), R);
4839 }
4840
4841 return clang_getNullRange();
4842}
4843
4844void clang_enableStackTraces(void) {
4845 llvm::sys::PrintStackTraceOnErrorSignal();
4846}
4847
4848void clang_executeOnThread(void (*fn)(void*), void *user_data,
4849 unsigned stack_size) {
4850 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4851}
4852
4853} // end: extern "C"
4854
4855//===----------------------------------------------------------------------===//
4856// Token-based Operations.
4857//===----------------------------------------------------------------------===//
4858
4859/* CXToken layout:
4860 * int_data[0]: a CXTokenKind
4861 * int_data[1]: starting token location
4862 * int_data[2]: token length
4863 * int_data[3]: reserved
4864 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4865 * otherwise unused.
4866 */
4867extern "C" {
4868
4869CXTokenKind clang_getTokenKind(CXToken CXTok) {
4870 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4871}
4872
4873CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4874 switch (clang_getTokenKind(CXTok)) {
4875 case CXToken_Identifier:
4876 case CXToken_Keyword:
4877 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004878 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004879 ->getNameStart());
4880
4881 case CXToken_Literal: {
4882 // We have stashed the starting pointer in the ptr_data field. Use it.
4883 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004884 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004885 }
4886
4887 case CXToken_Punctuation:
4888 case CXToken_Comment:
4889 break;
4890 }
4891
4892 // We have to find the starting buffer pointer the hard way, by
4893 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004894 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004895 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004896 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004897
4898 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4899 std::pair<FileID, unsigned> LocInfo
4900 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4901 bool Invalid = false;
4902 StringRef Buffer
4903 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4904 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004905 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004906
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004907 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004908}
4909
4910CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004911 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004912 if (!CXXUnit)
4913 return clang_getNullLocation();
4914
4915 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4916 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4917}
4918
4919CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004920 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004921 if (!CXXUnit)
4922 return clang_getNullRange();
4923
4924 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4925 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4926}
4927
4928static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4929 SmallVectorImpl<CXToken> &CXTokens) {
4930 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4931 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004932 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004933 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004934 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004935
4936 // Cannot tokenize across files.
4937 if (BeginLocInfo.first != EndLocInfo.first)
4938 return;
4939
4940 // Create a lexer
4941 bool Invalid = false;
4942 StringRef Buffer
4943 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4944 if (Invalid)
4945 return;
4946
4947 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4948 CXXUnit->getASTContext().getLangOpts(),
4949 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4950 Lex.SetCommentRetentionState(true);
4951
4952 // Lex tokens until we hit the end of the range.
4953 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4954 Token Tok;
4955 bool previousWasAt = false;
4956 do {
4957 // Lex the next token
4958 Lex.LexFromRawLexer(Tok);
4959 if (Tok.is(tok::eof))
4960 break;
4961
4962 // Initialize the CXToken.
4963 CXToken CXTok;
4964
4965 // - Common fields
4966 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4967 CXTok.int_data[2] = Tok.getLength();
4968 CXTok.int_data[3] = 0;
4969
4970 // - Kind-specific fields
4971 if (Tok.isLiteral()) {
4972 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004973 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004974 } else if (Tok.is(tok::raw_identifier)) {
4975 // Lookup the identifier to determine whether we have a keyword.
4976 IdentifierInfo *II
4977 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4978
4979 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4980 CXTok.int_data[0] = CXToken_Keyword;
4981 }
4982 else {
4983 CXTok.int_data[0] = Tok.is(tok::identifier)
4984 ? CXToken_Identifier
4985 : CXToken_Keyword;
4986 }
4987 CXTok.ptr_data = II;
4988 } else if (Tok.is(tok::comment)) {
4989 CXTok.int_data[0] = CXToken_Comment;
4990 CXTok.ptr_data = 0;
4991 } else {
4992 CXTok.int_data[0] = CXToken_Punctuation;
4993 CXTok.ptr_data = 0;
4994 }
4995 CXTokens.push_back(CXTok);
4996 previousWasAt = Tok.is(tok::at);
4997 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4998}
4999
5000void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5001 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005002 LOG_FUNC_SECTION {
5003 *Log << TU << ' ' << Range;
5004 }
5005
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005006 if (Tokens)
5007 *Tokens = 0;
5008 if (NumTokens)
5009 *NumTokens = 0;
5010
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005011 if (!TU)
5012 return;
5013
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005015 if (!CXXUnit || !Tokens || !NumTokens)
5016 return;
5017
5018 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5019
5020 SourceRange R = cxloc::translateCXSourceRange(Range);
5021 if (R.isInvalid())
5022 return;
5023
5024 SmallVector<CXToken, 32> CXTokens;
5025 getTokens(CXXUnit, R, CXTokens);
5026
5027 if (CXTokens.empty())
5028 return;
5029
5030 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5031 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5032 *NumTokens = CXTokens.size();
5033}
5034
5035void clang_disposeTokens(CXTranslationUnit TU,
5036 CXToken *Tokens, unsigned NumTokens) {
5037 free(Tokens);
5038}
5039
5040} // end: extern "C"
5041
5042//===----------------------------------------------------------------------===//
5043// Token annotation APIs.
5044//===----------------------------------------------------------------------===//
5045
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005046static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5047 CXCursor parent,
5048 CXClientData client_data);
5049static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5050 CXClientData client_data);
5051
5052namespace {
5053class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005054 CXToken *Tokens;
5055 CXCursor *Cursors;
5056 unsigned NumTokens;
5057 unsigned TokIdx;
5058 unsigned PreprocessingTokIdx;
5059 CursorVisitor AnnotateVis;
5060 SourceManager &SrcMgr;
5061 bool HasContextSensitiveKeywords;
5062
5063 struct PostChildrenInfo {
5064 CXCursor Cursor;
5065 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005066 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005067 unsigned BeforeChildrenTokenIdx;
5068 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005069 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005070
5071 bool MoreTokens() const { return TokIdx < NumTokens; }
5072 unsigned NextToken() const { return TokIdx; }
5073 void AdvanceToken() { ++TokIdx; }
5074 SourceLocation GetTokenLoc(unsigned tokI) {
5075 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5076 }
5077 bool isFunctionMacroToken(unsigned tokI) const {
5078 return Tokens[tokI].int_data[3] != 0;
5079 }
5080 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5081 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5082 }
5083
5084 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005085 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005086 SourceRange);
5087
5088public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005089 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005090 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005091 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005092 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005093 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005094 AnnotateTokensVisitor, this,
5095 /*VisitPreprocessorLast=*/true,
5096 /*VisitIncludedEntities=*/false,
5097 RegionOfInterest,
5098 /*VisitDeclsOnly=*/false,
5099 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005100 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005101 HasContextSensitiveKeywords(false) { }
5102
5103 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5104 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5105 bool postVisitChildren(CXCursor cursor);
5106 void AnnotateTokens();
5107
5108 /// \brief Determine whether the annotator saw any cursors that have
5109 /// context-sensitive keywords.
5110 bool hasContextSensitiveKeywords() const {
5111 return HasContextSensitiveKeywords;
5112 }
5113
5114 ~AnnotateTokensWorker() {
5115 assert(PostChildrenInfos.empty());
5116 }
5117};
5118}
5119
5120void AnnotateTokensWorker::AnnotateTokens() {
5121 // Walk the AST within the region of interest, annotating tokens
5122 // along the way.
5123 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005124}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005125
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005126static inline void updateCursorAnnotation(CXCursor &Cursor,
5127 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005128 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005129 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005130 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005131}
5132
5133/// \brief It annotates and advances tokens with a cursor until the comparison
5134//// between the cursor location and the source range is the same as
5135/// \arg compResult.
5136///
5137/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5138/// Pass RangeOverlap to annotate tokens inside a range.
5139void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5140 RangeComparisonResult compResult,
5141 SourceRange range) {
5142 while (MoreTokens()) {
5143 const unsigned I = NextToken();
5144 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005145 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5146 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005147
5148 SourceLocation TokLoc = GetTokenLoc(I);
5149 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005150 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005151 AdvanceToken();
5152 continue;
5153 }
5154 break;
5155 }
5156}
5157
5158/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005159/// \returns true if it advanced beyond all macro tokens, false otherwise.
5160bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005161 CXCursor updateC,
5162 RangeComparisonResult compResult,
5163 SourceRange range) {
5164 assert(MoreTokens());
5165 assert(isFunctionMacroToken(NextToken()) &&
5166 "Should be called only for macro arg tokens");
5167
5168 // This works differently than annotateAndAdvanceTokens; because expanded
5169 // macro arguments can have arbitrary translation-unit source order, we do not
5170 // advance the token index one by one until a token fails the range test.
5171 // We only advance once past all of the macro arg tokens if all of them
5172 // pass the range test. If one of them fails we keep the token index pointing
5173 // at the start of the macro arg tokens so that the failing token will be
5174 // annotated by a subsequent annotation try.
5175
5176 bool atLeastOneCompFail = false;
5177
5178 unsigned I = NextToken();
5179 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5180 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5181 if (TokLoc.isFileID())
5182 continue; // not macro arg token, it's parens or comma.
5183 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5184 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5185 Cursors[I] = updateC;
5186 } else
5187 atLeastOneCompFail = true;
5188 }
5189
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005190 if (atLeastOneCompFail)
5191 return false;
5192
5193 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5194 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005195}
5196
5197enum CXChildVisitResult
5198AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005199 SourceRange cursorRange = getRawCursorExtent(cursor);
5200 if (cursorRange.isInvalid())
5201 return CXChildVisit_Recurse;
5202
5203 if (!HasContextSensitiveKeywords) {
5204 // Objective-C properties can have context-sensitive keywords.
5205 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005206 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005207 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5208 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5209 }
5210 // Objective-C methods can have context-sensitive keywords.
5211 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5212 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005213 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005214 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5215 if (Method->getObjCDeclQualifier())
5216 HasContextSensitiveKeywords = true;
5217 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005218 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5219 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005220 P != PEnd; ++P) {
5221 if ((*P)->getObjCDeclQualifier()) {
5222 HasContextSensitiveKeywords = true;
5223 break;
5224 }
5225 }
5226 }
5227 }
5228 }
5229 // C++ methods can have context-sensitive keywords.
5230 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005231 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005232 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5233 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5234 HasContextSensitiveKeywords = true;
5235 }
5236 }
5237 // C++ classes can have context-sensitive keywords.
5238 else if (cursor.kind == CXCursor_StructDecl ||
5239 cursor.kind == CXCursor_ClassDecl ||
5240 cursor.kind == CXCursor_ClassTemplate ||
5241 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005242 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005243 if (D->hasAttr<FinalAttr>())
5244 HasContextSensitiveKeywords = true;
5245 }
5246 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005247
5248 // Don't override a property annotation with its getter/setter method.
5249 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5250 parent.kind == CXCursor_ObjCPropertyDecl)
5251 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005252
5253 if (clang_isPreprocessing(cursor.kind)) {
5254 // Items in the preprocessing record are kept separate from items in
5255 // declarations, so we keep a separate token index.
5256 unsigned SavedTokIdx = TokIdx;
5257 TokIdx = PreprocessingTokIdx;
5258
5259 // Skip tokens up until we catch up to the beginning of the preprocessing
5260 // entry.
5261 while (MoreTokens()) {
5262 const unsigned I = NextToken();
5263 SourceLocation TokLoc = GetTokenLoc(I);
5264 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5265 case RangeBefore:
5266 AdvanceToken();
5267 continue;
5268 case RangeAfter:
5269 case RangeOverlap:
5270 break;
5271 }
5272 break;
5273 }
5274
5275 // Look at all of the tokens within this range.
5276 while (MoreTokens()) {
5277 const unsigned I = NextToken();
5278 SourceLocation TokLoc = GetTokenLoc(I);
5279 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5280 case RangeBefore:
5281 llvm_unreachable("Infeasible");
5282 case RangeAfter:
5283 break;
5284 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005285 // For macro expansions, just note where the beginning of the macro
5286 // expansion occurs.
5287 if (cursor.kind == CXCursor_MacroExpansion) {
5288 if (TokLoc == cursorRange.getBegin())
5289 Cursors[I] = cursor;
5290 AdvanceToken();
5291 break;
5292 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005293 // We may have already annotated macro names inside macro definitions.
5294 if (Cursors[I].kind != CXCursor_MacroExpansion)
5295 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005296 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005297 continue;
5298 }
5299 break;
5300 }
5301
5302 // Save the preprocessing token index; restore the non-preprocessing
5303 // token index.
5304 PreprocessingTokIdx = TokIdx;
5305 TokIdx = SavedTokIdx;
5306 return CXChildVisit_Recurse;
5307 }
5308
5309 if (cursorRange.isInvalid())
5310 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005311
5312 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005313 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005314 const enum CXCursorKind K = clang_getCursorKind(parent);
5315 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005316 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5317 // Attributes are annotated out-of-order, skip tokens until we reach it.
5318 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005319 ? clang_getNullCursor() : parent;
5320
5321 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5322
5323 // Avoid having the cursor of an expression "overwrite" the annotation of the
5324 // variable declaration that it belongs to.
5325 // This can happen for C++ constructor expressions whose range generally
5326 // include the variable declaration, e.g.:
5327 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5328 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005329 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005330 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005331 const unsigned I = NextToken();
5332 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5333 E->getLocStart() == D->getLocation() &&
5334 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005335 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005336 AdvanceToken();
5337 }
5338 }
5339 }
5340
5341 // Before recursing into the children keep some state that we are going
5342 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5343 // extra work after the child nodes are visited.
5344 // Note that we don't call VisitChildren here to avoid traversing statements
5345 // code-recursively which can blow the stack.
5346
5347 PostChildrenInfo Info;
5348 Info.Cursor = cursor;
5349 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005350 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005351 Info.BeforeChildrenTokenIdx = NextToken();
5352 PostChildrenInfos.push_back(Info);
5353
5354 return CXChildVisit_Recurse;
5355}
5356
5357bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5358 if (PostChildrenInfos.empty())
5359 return false;
5360 const PostChildrenInfo &Info = PostChildrenInfos.back();
5361 if (!clang_equalCursors(Info.Cursor, cursor))
5362 return false;
5363
5364 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5365 const unsigned AfterChildren = NextToken();
5366 SourceRange cursorRange = Info.CursorRange;
5367
5368 // Scan the tokens that are at the end of the cursor, but are not captured
5369 // but the child cursors.
5370 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5371
5372 // Scan the tokens that are at the beginning of the cursor, but are not
5373 // capture by the child cursors.
5374 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5375 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5376 break;
5377
5378 Cursors[I] = cursor;
5379 }
5380
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005381 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5382 // encountered the attribute cursor.
5383 if (clang_isAttribute(cursor.kind))
5384 TokIdx = Info.BeforeReachingCursorIdx;
5385
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005386 PostChildrenInfos.pop_back();
5387 return false;
5388}
5389
5390static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5391 CXCursor parent,
5392 CXClientData client_data) {
5393 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5394}
5395
5396static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5397 CXClientData client_data) {
5398 return static_cast<AnnotateTokensWorker*>(client_data)->
5399 postVisitChildren(cursor);
5400}
5401
5402namespace {
5403
5404/// \brief Uses the macro expansions in the preprocessing record to find
5405/// and mark tokens that are macro arguments. This info is used by the
5406/// AnnotateTokensWorker.
5407class MarkMacroArgTokensVisitor {
5408 SourceManager &SM;
5409 CXToken *Tokens;
5410 unsigned NumTokens;
5411 unsigned CurIdx;
5412
5413public:
5414 MarkMacroArgTokensVisitor(SourceManager &SM,
5415 CXToken *tokens, unsigned numTokens)
5416 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5417
5418 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5419 if (cursor.kind != CXCursor_MacroExpansion)
5420 return CXChildVisit_Continue;
5421
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005422 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005423 if (macroRange.getBegin() == macroRange.getEnd())
5424 return CXChildVisit_Continue; // it's not a function macro.
5425
5426 for (; CurIdx < NumTokens; ++CurIdx) {
5427 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5428 macroRange.getBegin()))
5429 break;
5430 }
5431
5432 if (CurIdx == NumTokens)
5433 return CXChildVisit_Break;
5434
5435 for (; CurIdx < NumTokens; ++CurIdx) {
5436 SourceLocation tokLoc = getTokenLoc(CurIdx);
5437 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5438 break;
5439
5440 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5441 }
5442
5443 if (CurIdx == NumTokens)
5444 return CXChildVisit_Break;
5445
5446 return CXChildVisit_Continue;
5447 }
5448
5449private:
5450 SourceLocation getTokenLoc(unsigned tokI) {
5451 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5452 }
5453
5454 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5455 // The third field is reserved and currently not used. Use it here
5456 // to mark macro arg expanded tokens with their expanded locations.
5457 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5458 }
5459};
5460
5461} // end anonymous namespace
5462
5463static CXChildVisitResult
5464MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5465 CXClientData client_data) {
5466 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5467 parent);
5468}
5469
5470namespace {
5471 struct clang_annotateTokens_Data {
5472 CXTranslationUnit TU;
5473 ASTUnit *CXXUnit;
5474 CXToken *Tokens;
5475 unsigned NumTokens;
5476 CXCursor *Cursors;
5477 };
5478}
5479
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005480/// \brief Used by \c annotatePreprocessorTokens.
5481/// \returns true if lexing was finished, false otherwise.
5482static bool lexNext(Lexer &Lex, Token &Tok,
5483 unsigned &NextIdx, unsigned NumTokens) {
5484 if (NextIdx >= NumTokens)
5485 return true;
5486
5487 ++NextIdx;
5488 Lex.LexFromRawLexer(Tok);
5489 if (Tok.is(tok::eof))
5490 return true;
5491
5492 return false;
5493}
5494
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005495static void annotatePreprocessorTokens(CXTranslationUnit TU,
5496 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005497 CXCursor *Cursors,
5498 CXToken *Tokens,
5499 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005500 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005501
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005502 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005503 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5504 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005505 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005506 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005507 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005508
5509 if (BeginLocInfo.first != EndLocInfo.first)
5510 return;
5511
5512 StringRef Buffer;
5513 bool Invalid = false;
5514 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5515 if (Buffer.empty() || Invalid)
5516 return;
5517
5518 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5519 CXXUnit->getASTContext().getLangOpts(),
5520 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5521 Buffer.end());
5522 Lex.SetCommentRetentionState(true);
5523
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005524 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005525 // Lex tokens in raw mode until we hit the end of the range, to avoid
5526 // entering #includes or expanding macros.
5527 while (true) {
5528 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005529 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5530 break;
5531 unsigned TokIdx = NextIdx-1;
5532 assert(Tok.getLocation() ==
5533 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005534
5535 reprocess:
5536 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005537 // We have found a preprocessing directive. Annotate the tokens
5538 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005539 //
5540 // FIXME: Some simple tests here could identify macro definitions and
5541 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005542
5543 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005544 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5545 break;
5546
5547 MacroInfo *MI = 0;
5548 if (Tok.is(tok::raw_identifier) &&
5549 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5550 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5551 break;
5552
5553 if (Tok.is(tok::raw_identifier)) {
5554 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5555 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5556 SourceLocation MappedTokLoc =
5557 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5558 MI = getMacroInfo(II, MappedTokLoc, TU);
5559 }
5560 }
5561
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005562 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005563 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005564 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5565 finished = true;
5566 break;
5567 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005568 // If we are in a macro definition, check if the token was ever a
5569 // macro name and annotate it if that's the case.
5570 if (MI) {
5571 SourceLocation SaveLoc = Tok.getLocation();
5572 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5573 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5574 Tok.setLocation(SaveLoc);
5575 if (MacroDef)
5576 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5577 Tok.getLocation(), TU);
5578 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005579 } while (!Tok.isAtStartOfLine());
5580
5581 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5582 assert(TokIdx <= LastIdx);
5583 SourceLocation EndLoc =
5584 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5585 CXCursor Cursor =
5586 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5587
5588 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005589 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005590
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005591 if (finished)
5592 break;
5593 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005594 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005595 }
5596}
5597
5598// This gets run a separate thread to avoid stack blowout.
5599static void clang_annotateTokensImpl(void *UserData) {
5600 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5601 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5602 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5603 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5604 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5605
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005606 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005607 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5608 setThreadBackgroundPriority();
5609
5610 // Determine the region of interest, which contains all of the tokens.
5611 SourceRange RegionOfInterest;
5612 RegionOfInterest.setBegin(
5613 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5614 RegionOfInterest.setEnd(
5615 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5616 Tokens[NumTokens-1])));
5617
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005618 // Relex the tokens within the source range to look for preprocessing
5619 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005620 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005621
5622 // If begin location points inside a macro argument, set it to the expansion
5623 // location so we can have the full context when annotating semantically.
5624 {
5625 SourceManager &SM = CXXUnit->getSourceManager();
5626 SourceLocation Loc =
5627 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5628 if (Loc.isMacroID())
5629 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5630 }
5631
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005632 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5633 // Search and mark tokens that are macro argument expansions.
5634 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5635 Tokens, NumTokens);
5636 CursorVisitor MacroArgMarker(TU,
5637 MarkMacroArgTokensVisitorDelegate, &Visitor,
5638 /*VisitPreprocessorLast=*/true,
5639 /*VisitIncludedEntities=*/false,
5640 RegionOfInterest);
5641 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5642 }
5643
5644 // Annotate all of the source locations in the region of interest that map to
5645 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005646 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005647
5648 // FIXME: We use a ridiculous stack size here because the data-recursion
5649 // algorithm uses a large stack frame than the non-data recursive version,
5650 // and AnnotationTokensWorker currently transforms the data-recursion
5651 // algorithm back into a traditional recursion by explicitly calling
5652 // VisitChildren(). We will need to remove this explicit recursive call.
5653 W.AnnotateTokens();
5654
5655 // If we ran into any entities that involve context-sensitive keywords,
5656 // take another pass through the tokens to mark them as such.
5657 if (W.hasContextSensitiveKeywords()) {
5658 for (unsigned I = 0; I != NumTokens; ++I) {
5659 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5660 continue;
5661
5662 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5663 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005664 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005665 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5666 if (Property->getPropertyAttributesAsWritten() != 0 &&
5667 llvm::StringSwitch<bool>(II->getName())
5668 .Case("readonly", true)
5669 .Case("assign", true)
5670 .Case("unsafe_unretained", true)
5671 .Case("readwrite", true)
5672 .Case("retain", true)
5673 .Case("copy", true)
5674 .Case("nonatomic", true)
5675 .Case("atomic", true)
5676 .Case("getter", true)
5677 .Case("setter", true)
5678 .Case("strong", true)
5679 .Case("weak", true)
5680 .Default(false))
5681 Tokens[I].int_data[0] = CXToken_Keyword;
5682 }
5683 continue;
5684 }
5685
5686 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5687 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5688 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5689 if (llvm::StringSwitch<bool>(II->getName())
5690 .Case("in", true)
5691 .Case("out", true)
5692 .Case("inout", true)
5693 .Case("oneway", true)
5694 .Case("bycopy", true)
5695 .Case("byref", true)
5696 .Default(false))
5697 Tokens[I].int_data[0] = CXToken_Keyword;
5698 continue;
5699 }
5700
5701 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5702 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5703 Tokens[I].int_data[0] = CXToken_Keyword;
5704 continue;
5705 }
5706 }
5707 }
5708}
5709
5710extern "C" {
5711
5712void clang_annotateTokens(CXTranslationUnit TU,
5713 CXToken *Tokens, unsigned NumTokens,
5714 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005715 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005716 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005717 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005718 }
5719
5720 LOG_FUNC_SECTION {
5721 *Log << TU << ' ';
5722 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5723 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5724 *Log << clang_getRange(bloc, eloc);
5725 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005726
5727 // Any token we don't specifically annotate will have a NULL cursor.
5728 CXCursor C = clang_getNullCursor();
5729 for (unsigned I = 0; I != NumTokens; ++I)
5730 Cursors[I] = C;
5731
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005732 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005733 if (!CXXUnit)
5734 return;
5735
5736 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5737
5738 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5739 llvm::CrashRecoveryContext CRC;
5740 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5741 GetSafetyThreadStackSize() * 2)) {
5742 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5743 }
5744}
5745
5746} // end: extern "C"
5747
5748//===----------------------------------------------------------------------===//
5749// Operations for querying linkage of a cursor.
5750//===----------------------------------------------------------------------===//
5751
5752extern "C" {
5753CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5754 if (!clang_isDeclaration(cursor.kind))
5755 return CXLinkage_Invalid;
5756
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005757 const Decl *D = cxcursor::getCursorDecl(cursor);
5758 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005759 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005760 case NoLinkage:
5761 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005762 case InternalLinkage: return CXLinkage_Internal;
5763 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5764 case ExternalLinkage: return CXLinkage_External;
5765 };
5766
5767 return CXLinkage_Invalid;
5768}
5769} // end: extern "C"
5770
5771//===----------------------------------------------------------------------===//
5772// Operations for querying language of a cursor.
5773//===----------------------------------------------------------------------===//
5774
5775static CXLanguageKind getDeclLanguage(const Decl *D) {
5776 if (!D)
5777 return CXLanguage_C;
5778
5779 switch (D->getKind()) {
5780 default:
5781 break;
5782 case Decl::ImplicitParam:
5783 case Decl::ObjCAtDefsField:
5784 case Decl::ObjCCategory:
5785 case Decl::ObjCCategoryImpl:
5786 case Decl::ObjCCompatibleAlias:
5787 case Decl::ObjCImplementation:
5788 case Decl::ObjCInterface:
5789 case Decl::ObjCIvar:
5790 case Decl::ObjCMethod:
5791 case Decl::ObjCProperty:
5792 case Decl::ObjCPropertyImpl:
5793 case Decl::ObjCProtocol:
5794 return CXLanguage_ObjC;
5795 case Decl::CXXConstructor:
5796 case Decl::CXXConversion:
5797 case Decl::CXXDestructor:
5798 case Decl::CXXMethod:
5799 case Decl::CXXRecord:
5800 case Decl::ClassTemplate:
5801 case Decl::ClassTemplatePartialSpecialization:
5802 case Decl::ClassTemplateSpecialization:
5803 case Decl::Friend:
5804 case Decl::FriendTemplate:
5805 case Decl::FunctionTemplate:
5806 case Decl::LinkageSpec:
5807 case Decl::Namespace:
5808 case Decl::NamespaceAlias:
5809 case Decl::NonTypeTemplateParm:
5810 case Decl::StaticAssert:
5811 case Decl::TemplateTemplateParm:
5812 case Decl::TemplateTypeParm:
5813 case Decl::UnresolvedUsingTypename:
5814 case Decl::UnresolvedUsingValue:
5815 case Decl::Using:
5816 case Decl::UsingDirective:
5817 case Decl::UsingShadow:
5818 return CXLanguage_CPlusPlus;
5819 }
5820
5821 return CXLanguage_C;
5822}
5823
5824extern "C" {
5825
5826enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5827 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005828 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005829 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5830 return CXAvailability_Available;
5831
5832 switch (D->getAvailability()) {
5833 case AR_Available:
5834 case AR_NotYetIntroduced:
5835 return CXAvailability_Available;
5836
5837 case AR_Deprecated:
5838 return CXAvailability_Deprecated;
5839
5840 case AR_Unavailable:
5841 return CXAvailability_NotAvailable;
5842 }
5843 }
5844
5845 return CXAvailability_Available;
5846}
5847
5848static CXVersion convertVersion(VersionTuple In) {
5849 CXVersion Out = { -1, -1, -1 };
5850 if (In.empty())
5851 return Out;
5852
5853 Out.Major = In.getMajor();
5854
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005855 Optional<unsigned> Minor = In.getMinor();
5856 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005857 Out.Minor = *Minor;
5858 else
5859 return Out;
5860
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005861 Optional<unsigned> Subminor = In.getSubminor();
5862 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005863 Out.Subminor = *Subminor;
5864
5865 return Out;
5866}
5867
5868int clang_getCursorPlatformAvailability(CXCursor cursor,
5869 int *always_deprecated,
5870 CXString *deprecated_message,
5871 int *always_unavailable,
5872 CXString *unavailable_message,
5873 CXPlatformAvailability *availability,
5874 int availability_size) {
5875 if (always_deprecated)
5876 *always_deprecated = 0;
5877 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005878 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005879 if (always_unavailable)
5880 *always_unavailable = 0;
5881 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005882 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005883
5884 if (!clang_isDeclaration(cursor.kind))
5885 return 0;
5886
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005887 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005888 if (!D)
5889 return 0;
5890
5891 int N = 0;
5892 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5893 ++A) {
5894 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5895 if (always_deprecated)
5896 *always_deprecated = 1;
5897 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005898 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005899 continue;
5900 }
5901
5902 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5903 if (always_unavailable)
5904 *always_unavailable = 1;
5905 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005906 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005907 }
5908 continue;
5909 }
5910
5911 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5912 if (N < availability_size) {
5913 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005914 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005915 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5916 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5917 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5918 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005919 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005920 }
5921 ++N;
5922 }
5923 }
5924
5925 return N;
5926}
5927
5928void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5929 clang_disposeString(availability->Platform);
5930 clang_disposeString(availability->Message);
5931}
5932
5933CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5934 if (clang_isDeclaration(cursor.kind))
5935 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5936
5937 return CXLanguage_Invalid;
5938}
5939
5940 /// \brief If the given cursor is the "templated" declaration
5941 /// descibing a class or function template, return the class or
5942 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005943static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005944 if (!D)
5945 return 0;
5946
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005947 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005948 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5949 return FunTmpl;
5950
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005951 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005952 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5953 return ClassTmpl;
5954
5955 return D;
5956}
5957
5958CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5959 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005960 if (const Decl *D = getCursorDecl(cursor)) {
5961 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005962 if (!DC)
5963 return clang_getNullCursor();
5964
5965 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5966 getCursorTU(cursor));
5967 }
5968 }
5969
5970 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005971 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005972 return MakeCXCursor(D, getCursorTU(cursor));
5973 }
5974
5975 return clang_getNullCursor();
5976}
5977
5978CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5979 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005980 if (const Decl *D = getCursorDecl(cursor)) {
5981 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005982 if (!DC)
5983 return clang_getNullCursor();
5984
5985 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5986 getCursorTU(cursor));
5987 }
5988 }
5989
5990 // FIXME: Note that we can't easily compute the lexical context of a
5991 // statement or expression, so we return nothing.
5992 return clang_getNullCursor();
5993}
5994
5995CXFile clang_getIncludedFile(CXCursor cursor) {
5996 if (cursor.kind != CXCursor_InclusionDirective)
5997 return 0;
5998
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005999 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00006000 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006001}
6002
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00006003unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6004 if (C.kind != CXCursor_ObjCPropertyDecl)
6005 return CXObjCPropertyAttr_noattr;
6006
6007 unsigned Result = CXObjCPropertyAttr_noattr;
6008 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6009 ObjCPropertyDecl::PropertyAttributeKind Attr =
6010 PD->getPropertyAttributesAsWritten();
6011
6012#define SET_CXOBJCPROP_ATTR(A) \
6013 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6014 Result |= CXObjCPropertyAttr_##A
6015 SET_CXOBJCPROP_ATTR(readonly);
6016 SET_CXOBJCPROP_ATTR(getter);
6017 SET_CXOBJCPROP_ATTR(assign);
6018 SET_CXOBJCPROP_ATTR(readwrite);
6019 SET_CXOBJCPROP_ATTR(retain);
6020 SET_CXOBJCPROP_ATTR(copy);
6021 SET_CXOBJCPROP_ATTR(nonatomic);
6022 SET_CXOBJCPROP_ATTR(setter);
6023 SET_CXOBJCPROP_ATTR(atomic);
6024 SET_CXOBJCPROP_ATTR(weak);
6025 SET_CXOBJCPROP_ATTR(strong);
6026 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6027#undef SET_CXOBJCPROP_ATTR
6028
6029 return Result;
6030}
6031
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006032unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6033 if (!clang_isDeclaration(C.kind))
6034 return CXObjCDeclQualifier_None;
6035
6036 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6037 const Decl *D = getCursorDecl(C);
6038 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6039 QT = MD->getObjCDeclQualifier();
6040 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6041 QT = PD->getObjCDeclQualifier();
6042 if (QT == Decl::OBJC_TQ_None)
6043 return CXObjCDeclQualifier_None;
6044
6045 unsigned Result = CXObjCDeclQualifier_None;
6046 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6047 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6048 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6049 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6050 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6051 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6052
6053 return Result;
6054}
6055
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006056unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6057 if (!clang_isDeclaration(C.kind))
6058 return 0;
6059
6060 const Decl *D = getCursorDecl(C);
6061 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6062 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6063 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6064 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6065
6066 return 0;
6067}
6068
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006069unsigned clang_Cursor_isVariadic(CXCursor C) {
6070 if (!clang_isDeclaration(C.kind))
6071 return 0;
6072
6073 const Decl *D = getCursorDecl(C);
6074 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6075 return FD->isVariadic();
6076 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6077 return MD->isVariadic();
6078
6079 return 0;
6080}
6081
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006082CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6083 if (!clang_isDeclaration(C.kind))
6084 return clang_getNullRange();
6085
6086 const Decl *D = getCursorDecl(C);
6087 ASTContext &Context = getCursorContext(C);
6088 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6089 if (!RC)
6090 return clang_getNullRange();
6091
6092 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6093}
6094
6095CXString clang_Cursor_getRawCommentText(CXCursor C) {
6096 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006097 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006098
6099 const Decl *D = getCursorDecl(C);
6100 ASTContext &Context = getCursorContext(C);
6101 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6102 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6103 StringRef();
6104
6105 // Don't duplicate the string because RawText points directly into source
6106 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006107 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006108}
6109
6110CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6111 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006112 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006113
6114 const Decl *D = getCursorDecl(C);
6115 const ASTContext &Context = getCursorContext(C);
6116 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6117
6118 if (RC) {
6119 StringRef BriefText = RC->getBriefText(Context);
6120
6121 // Don't duplicate the string because RawComment ensures that this memory
6122 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006123 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006124 }
6125
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006126 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006127}
6128
6129CXComment clang_Cursor_getParsedComment(CXCursor C) {
6130 if (!clang_isDeclaration(C.kind))
6131 return cxcomment::createCXComment(NULL, NULL);
6132
6133 const Decl *D = getCursorDecl(C);
6134 const ASTContext &Context = getCursorContext(C);
6135 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6136
6137 return cxcomment::createCXComment(FC, getCursorTU(C));
6138}
6139
6140CXModule clang_Cursor_getModule(CXCursor C) {
6141 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006142 if (const ImportDecl *ImportD =
6143 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006144 return ImportD->getImportedModule();
6145 }
6146
6147 return 0;
6148}
6149
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006150CXFile clang_Module_getASTFile(CXModule CXMod) {
6151 if (!CXMod)
6152 return 0;
6153 Module *Mod = static_cast<Module*>(CXMod);
6154 return const_cast<FileEntry *>(Mod->getASTFile());
6155}
6156
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006157CXModule clang_Module_getParent(CXModule CXMod) {
6158 if (!CXMod)
6159 return 0;
6160 Module *Mod = static_cast<Module*>(CXMod);
6161 return Mod->Parent;
6162}
6163
6164CXString clang_Module_getName(CXModule CXMod) {
6165 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006166 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006167 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006168 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006169}
6170
6171CXString clang_Module_getFullName(CXModule CXMod) {
6172 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006173 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006174 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006175 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006176}
6177
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006178unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6179 CXModule CXMod) {
6180 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006181 return 0;
6182 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006183 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6184 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6185 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006186}
6187
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006188CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6189 CXModule CXMod, unsigned Index) {
6190 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006191 return 0;
6192 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006193 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006194
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006195 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6196 if (Index < TopHeaders.size())
6197 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006198
6199 return 0;
6200}
6201
6202} // end: extern "C"
6203
6204//===----------------------------------------------------------------------===//
6205// C++ AST instrospection.
6206//===----------------------------------------------------------------------===//
6207
6208extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006209unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6210 if (!clang_isDeclaration(C.kind))
6211 return 0;
6212
6213 const CXXMethodDecl *Method = 0;
6214 const Decl *D = cxcursor::getCursorDecl(C);
6215 if (const FunctionTemplateDecl *FunTmpl =
6216 dyn_cast_or_null<FunctionTemplateDecl>(D))
6217 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6218 else
6219 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6220 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6221}
6222
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006223unsigned clang_CXXMethod_isStatic(CXCursor C) {
6224 if (!clang_isDeclaration(C.kind))
6225 return 0;
6226
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006227 const CXXMethodDecl *Method = 0;
6228 const Decl *D = cxcursor::getCursorDecl(C);
6229 if (const FunctionTemplateDecl *FunTmpl =
6230 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006231 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6232 else
6233 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6234 return (Method && Method->isStatic()) ? 1 : 0;
6235}
6236
6237unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6238 if (!clang_isDeclaration(C.kind))
6239 return 0;
6240
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006241 const CXXMethodDecl *Method = 0;
6242 const Decl *D = cxcursor::getCursorDecl(C);
6243 if (const FunctionTemplateDecl *FunTmpl =
6244 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006245 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6246 else
6247 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6248 return (Method && Method->isVirtual()) ? 1 : 0;
6249}
6250} // end: extern "C"
6251
6252//===----------------------------------------------------------------------===//
6253// Attribute introspection.
6254//===----------------------------------------------------------------------===//
6255
6256extern "C" {
6257CXType clang_getIBOutletCollectionType(CXCursor C) {
6258 if (C.kind != CXCursor_IBOutletCollectionAttr)
6259 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6260
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006261 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006262 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6263
6264 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6265}
6266} // end: extern "C"
6267
6268//===----------------------------------------------------------------------===//
6269// Inspecting memory usage.
6270//===----------------------------------------------------------------------===//
6271
6272typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6273
6274static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6275 enum CXTUResourceUsageKind k,
6276 unsigned long amount) {
6277 CXTUResourceUsageEntry entry = { k, amount };
6278 entries.push_back(entry);
6279}
6280
6281extern "C" {
6282
6283const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6284 const char *str = "";
6285 switch (kind) {
6286 case CXTUResourceUsage_AST:
6287 str = "ASTContext: expressions, declarations, and types";
6288 break;
6289 case CXTUResourceUsage_Identifiers:
6290 str = "ASTContext: identifiers";
6291 break;
6292 case CXTUResourceUsage_Selectors:
6293 str = "ASTContext: selectors";
6294 break;
6295 case CXTUResourceUsage_GlobalCompletionResults:
6296 str = "Code completion: cached global results";
6297 break;
6298 case CXTUResourceUsage_SourceManagerContentCache:
6299 str = "SourceManager: content cache allocator";
6300 break;
6301 case CXTUResourceUsage_AST_SideTables:
6302 str = "ASTContext: side tables";
6303 break;
6304 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6305 str = "SourceManager: malloc'ed memory buffers";
6306 break;
6307 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6308 str = "SourceManager: mmap'ed memory buffers";
6309 break;
6310 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6311 str = "ExternalASTSource: malloc'ed memory buffers";
6312 break;
6313 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6314 str = "ExternalASTSource: mmap'ed memory buffers";
6315 break;
6316 case CXTUResourceUsage_Preprocessor:
6317 str = "Preprocessor: malloc'ed memory";
6318 break;
6319 case CXTUResourceUsage_PreprocessingRecord:
6320 str = "Preprocessor: PreprocessingRecord";
6321 break;
6322 case CXTUResourceUsage_SourceManager_DataStructures:
6323 str = "SourceManager: data structures and tables";
6324 break;
6325 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6326 str = "Preprocessor: header search tables";
6327 break;
6328 }
6329 return str;
6330}
6331
6332CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6333 if (!TU) {
6334 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6335 return usage;
6336 }
6337
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006338 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006339 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6340 ASTContext &astContext = astUnit->getASTContext();
6341
6342 // How much memory is used by AST nodes and types?
6343 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6344 (unsigned long) astContext.getASTAllocatedMemory());
6345
6346 // How much memory is used by identifiers?
6347 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6348 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6349
6350 // How much memory is used for selectors?
6351 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6352 (unsigned long) astContext.Selectors.getTotalMemory());
6353
6354 // How much memory is used by ASTContext's side tables?
6355 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6356 (unsigned long) astContext.getSideTableAllocatedMemory());
6357
6358 // How much memory is used for caching global code completion results?
6359 unsigned long completionBytes = 0;
6360 if (GlobalCodeCompletionAllocator *completionAllocator =
6361 astUnit->getCachedCompletionAllocator().getPtr()) {
6362 completionBytes = completionAllocator->getTotalMemory();
6363 }
6364 createCXTUResourceUsageEntry(*entries,
6365 CXTUResourceUsage_GlobalCompletionResults,
6366 completionBytes);
6367
6368 // How much memory is being used by SourceManager's content cache?
6369 createCXTUResourceUsageEntry(*entries,
6370 CXTUResourceUsage_SourceManagerContentCache,
6371 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6372
6373 // How much memory is being used by the MemoryBuffer's in SourceManager?
6374 const SourceManager::MemoryBufferSizes &srcBufs =
6375 astUnit->getSourceManager().getMemoryBufferSizes();
6376
6377 createCXTUResourceUsageEntry(*entries,
6378 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6379 (unsigned long) srcBufs.malloc_bytes);
6380 createCXTUResourceUsageEntry(*entries,
6381 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6382 (unsigned long) srcBufs.mmap_bytes);
6383 createCXTUResourceUsageEntry(*entries,
6384 CXTUResourceUsage_SourceManager_DataStructures,
6385 (unsigned long) astContext.getSourceManager()
6386 .getDataStructureSizes());
6387
6388 // How much memory is being used by the ExternalASTSource?
6389 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6390 const ExternalASTSource::MemoryBufferSizes &sizes =
6391 esrc->getMemoryBufferSizes();
6392
6393 createCXTUResourceUsageEntry(*entries,
6394 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6395 (unsigned long) sizes.malloc_bytes);
6396 createCXTUResourceUsageEntry(*entries,
6397 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6398 (unsigned long) sizes.mmap_bytes);
6399 }
6400
6401 // How much memory is being used by the Preprocessor?
6402 Preprocessor &pp = astUnit->getPreprocessor();
6403 createCXTUResourceUsageEntry(*entries,
6404 CXTUResourceUsage_Preprocessor,
6405 pp.getTotalMemory());
6406
6407 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6408 createCXTUResourceUsageEntry(*entries,
6409 CXTUResourceUsage_PreprocessingRecord,
6410 pRec->getTotalMemory());
6411 }
6412
6413 createCXTUResourceUsageEntry(*entries,
6414 CXTUResourceUsage_Preprocessor_HeaderSearch,
6415 pp.getHeaderSearchInfo().getTotalMemory());
6416
6417 CXTUResourceUsage usage = { (void*) entries.get(),
6418 (unsigned) entries->size(),
6419 entries->size() ? &(*entries)[0] : 0 };
6420 entries.take();
6421 return usage;
6422}
6423
6424void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6425 if (usage.data)
6426 delete (MemUsageEntries*) usage.data;
6427}
6428
6429} // end extern "C"
6430
6431void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6432 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6433 for (unsigned I = 0; I != Usage.numEntries; ++I)
6434 fprintf(stderr, " %s: %lu\n",
6435 clang_getTUResourceUsageName(Usage.entries[I].kind),
6436 Usage.entries[I].amount);
6437
6438 clang_disposeCXTUResourceUsage(Usage);
6439}
6440
6441//===----------------------------------------------------------------------===//
6442// Misc. utility functions.
6443//===----------------------------------------------------------------------===//
6444
6445/// Default to using an 8 MB stack size on "safety" threads.
6446static unsigned SafetyStackThreadSize = 8 << 20;
6447
6448namespace clang {
6449
6450bool RunSafely(llvm::CrashRecoveryContext &CRC,
6451 void (*Fn)(void*), void *UserData,
6452 unsigned Size) {
6453 if (!Size)
6454 Size = GetSafetyThreadStackSize();
6455 if (Size)
6456 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6457 return CRC.RunSafely(Fn, UserData);
6458}
6459
6460unsigned GetSafetyThreadStackSize() {
6461 return SafetyStackThreadSize;
6462}
6463
6464void SetSafetyThreadStackSize(unsigned Value) {
6465 SafetyStackThreadSize = Value;
6466}
6467
6468}
6469
6470void clang::setThreadBackgroundPriority() {
6471 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6472 return;
6473
6474 // FIXME: Move to llvm/Support and make it cross-platform.
6475#ifdef __APPLE__
6476 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6477#endif
6478}
6479
6480void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6481 if (!Unit)
6482 return;
6483
6484 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6485 DEnd = Unit->stored_diag_end();
6486 D != DEnd; ++D) {
6487 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6488 CXString Msg = clang_formatDiagnostic(&Diag,
6489 clang_defaultDiagnosticDisplayOptions());
6490 fprintf(stderr, "%s\n", clang_getCString(Msg));
6491 clang_disposeString(Msg);
6492 }
6493#ifdef LLVM_ON_WIN32
6494 // On Windows, force a flush, since there may be multiple copies of
6495 // stderr and stdout in the file system, all with different buffers
6496 // but writing to the same device.
6497 fflush(stderr);
6498#endif
6499}
6500
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006501MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6502 SourceLocation MacroDefLoc,
6503 CXTranslationUnit TU){
6504 if (MacroDefLoc.isInvalid() || !TU)
6505 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006506 if (!II.hadMacroDefinition())
6507 return 0;
6508
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006509 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006510 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006511 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006512 if (MD) {
6513 for (MacroDirective::DefInfo
6514 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6515 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6516 return Def.getMacroInfo();
6517 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006518 }
6519
6520 return 0;
6521}
6522
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006523const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6524 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006525 if (!MacroDef || !TU)
6526 return 0;
6527 const IdentifierInfo *II = MacroDef->getName();
6528 if (!II)
6529 return 0;
6530
6531 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6532}
6533
6534MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6535 const Token &Tok,
6536 CXTranslationUnit TU) {
6537 if (!MI || !TU)
6538 return 0;
6539 if (Tok.isNot(tok::raw_identifier))
6540 return 0;
6541
6542 if (MI->getNumTokens() == 0)
6543 return 0;
6544 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6545 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006546 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006547
6548 // Check that the token is inside the definition and not its argument list.
6549 SourceManager &SM = Unit->getSourceManager();
6550 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6551 return 0;
6552 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6553 return 0;
6554
6555 Preprocessor &PP = Unit->getPreprocessor();
6556 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6557 if (!PPRec)
6558 return 0;
6559
6560 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6561 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6562 if (!II.hadMacroDefinition())
6563 return 0;
6564
6565 // Check that the identifier is not one of the macro arguments.
6566 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6567 return 0;
6568
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006569 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6570 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006571 return 0;
6572
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006573 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006574}
6575
6576MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6577 SourceLocation Loc,
6578 CXTranslationUnit TU) {
6579 if (Loc.isInvalid() || !MI || !TU)
6580 return 0;
6581
6582 if (MI->getNumTokens() == 0)
6583 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006584 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006585 Preprocessor &PP = Unit->getPreprocessor();
6586 if (!PP.getPreprocessingRecord())
6587 return 0;
6588 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6589 Token Tok;
6590 if (PP.getRawToken(Loc, Tok))
6591 return 0;
6592
6593 return checkForMacroInMacroDefinition(MI, Tok, TU);
6594}
6595
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006596extern "C" {
6597
6598CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006599 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006600}
6601
6602} // end: extern "C"
6603
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006604Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6605 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006606 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006607 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006608 if (Unit->isMainFileAST())
6609 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006610 return *this;
6611 }
6612 }
6613
6614 LogOS << "<NULL TU>";
6615 return *this;
6616}
6617
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006618Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6619 *this << FE->getName();
6620 return *this;
6621}
6622
6623Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6624 CXString cursorName = clang_getCursorDisplayName(cursor);
6625 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6626 clang_disposeString(cursorName);
6627 return *this;
6628}
6629
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006630Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6631 CXFile File;
6632 unsigned Line, Column;
6633 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6634 CXString FileName = clang_getFileName(File);
6635 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6636 clang_disposeString(FileName);
6637 return *this;
6638}
6639
6640Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6641 CXSourceLocation BLoc = clang_getRangeStart(range);
6642 CXSourceLocation ELoc = clang_getRangeEnd(range);
6643
6644 CXFile BFile;
6645 unsigned BLine, BColumn;
6646 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6647
6648 CXFile EFile;
6649 unsigned ELine, EColumn;
6650 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6651
6652 CXString BFileName = clang_getFileName(BFile);
6653 if (BFile == EFile) {
6654 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6655 BLine, BColumn, ELine, EColumn);
6656 } else {
6657 CXString EFileName = clang_getFileName(EFile);
6658 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6659 BLine, BColumn)
6660 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6661 ELine, EColumn);
6662 clang_disposeString(EFileName);
6663 }
6664 clang_disposeString(BFileName);
6665 return *this;
6666}
6667
6668Logger &cxindex::Logger::operator<<(CXString Str) {
6669 *this << clang_getCString(Str);
6670 return *this;
6671}
6672
6673Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6674 LogOS << Fmt;
6675 return *this;
6676}
6677
6678cxindex::Logger::~Logger() {
6679 LogOS.flush();
6680
6681 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6682
6683 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6684
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006685 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006686 OS << "[libclang:" << Name << ':';
6687
6688 // FIXME: Portability.
6689#if HAVE_PTHREAD_H && __APPLE__
6690 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6691 OS << tid << ':';
6692#endif
6693
6694 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6695 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6696 OS << Msg.str() << '\n';
6697
6698 if (Trace) {
6699 llvm::sys::PrintStackTrace(stderr);
6700 OS << "--------------------------------------------------\n";
6701 }
6702}