blob: b40a9134816e07f382011a990e7ce8a1520ffaaa [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.
Benjamin Kramer767b3d22013-09-22 14:10:29 +0000751static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
752 CXXCtorInitializer *const *Y) {
753 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000754}
755
756bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000757 unsigned NumParamList = ND->getNumTemplateParameterLists();
758 for (unsigned i = 0; i < NumParamList; i++) {
759 TemplateParameterList* Params = ND->getTemplateParameterList(i);
760 if (VisitTemplateParameters(Params))
761 return true;
762 }
763
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000764 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
765 // Visit the function declaration's syntactic components in the order
766 // written. This requires a bit of work.
767 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000768 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000769
770 // If we have a function declared directly (without the use of a typedef),
771 // visit just the return type. Otherwise, just visit the function's type
772 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000773 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000774 (!FTL && Visit(TL)))
775 return true;
776
777 // Visit the nested-name-specifier, if present.
778 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
779 if (VisitNestedNameSpecifierLoc(QualifierLoc))
780 return true;
781
782 // Visit the declaration name.
783 if (VisitDeclarationNameInfo(ND->getNameInfo()))
784 return true;
785
786 // FIXME: Visit explicitly-specified template arguments!
787
788 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000789 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000790 return true;
791
Bill Wendlingad017fa2012-12-20 19:22:21 +0000792 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000793 }
794
795 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
796 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
797 // Find the initializers that were written in the source.
798 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
799 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
800 IEnd = Constructor->init_end();
801 I != IEnd; ++I) {
802 if (!(*I)->isWritten())
803 continue;
804
805 WrittenInits.push_back(*I);
806 }
807
808 // Sort the initializers in source order
809 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
810 &CompareCXXCtorInitializers);
811
812 // Visit the initializers in source order
813 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
814 CXXCtorInitializer *Init = WrittenInits[I];
815 if (Init->isAnyMemberInitializer()) {
816 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
817 Init->getMemberLocation(), TU)))
818 return true;
819 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
820 if (Visit(TInfo->getTypeLoc()))
821 return true;
822 }
823
824 // Visit the initializer value.
825 if (Expr *Initializer = Init->getInit())
826 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
827 return true;
828 }
829 }
830
831 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
832 return true;
833 }
834
835 return false;
836}
837
838bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
839 if (VisitDeclaratorDecl(D))
840 return true;
841
842 if (Expr *BitWidth = D->getBitWidth())
843 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
844
845 return false;
846}
847
848bool CursorVisitor::VisitVarDecl(VarDecl *D) {
849 if (VisitDeclaratorDecl(D))
850 return true;
851
852 if (Expr *Init = D->getInit())
853 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
854
855 return false;
856}
857
858bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
859 if (VisitDeclaratorDecl(D))
860 return true;
861
862 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
863 if (Expr *DefArg = D->getDefaultArgument())
864 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
870 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
871 // before visiting these template parameters.
872 if (VisitTemplateParameters(D->getTemplateParameters()))
873 return true;
874
875 return VisitFunctionDecl(D->getTemplatedDecl());
876}
877
878bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
879 // FIXME: Visit the "outer" template parameter lists on the TagDecl
880 // before visiting these template parameters.
881 if (VisitTemplateParameters(D->getTemplateParameters()))
882 return true;
883
884 return VisitCXXRecordDecl(D->getTemplatedDecl());
885}
886
887bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
892 VisitTemplateArgumentLoc(D->getDefaultArgument()))
893 return true;
894
895 return false;
896}
897
898bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
899 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
900 if (Visit(TSInfo->getTypeLoc()))
901 return true;
902
903 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
904 PEnd = ND->param_end();
905 P != PEnd; ++P) {
906 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
907 return true;
908 }
909
910 if (ND->isThisDeclarationADefinition() &&
911 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
912 return true;
913
914 return false;
915}
916
917template <typename DeclIt>
918static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
919 SourceManager &SM, SourceLocation EndLoc,
920 SmallVectorImpl<Decl *> &Decls) {
921 DeclIt next = *DI_current;
922 while (++next != DE_current) {
923 Decl *D_next = *next;
924 if (!D_next)
925 break;
926 SourceLocation L = D_next->getLocStart();
927 if (!L.isValid())
928 break;
929 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
930 *DI_current = next;
931 Decls.push_back(D_next);
932 continue;
933 }
934 break;
935 }
936}
937
938namespace {
939 struct ContainerDeclsSort {
940 SourceManager &SM;
941 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
942 bool operator()(Decl *A, Decl *B) {
943 SourceLocation L_A = A->getLocStart();
944 SourceLocation L_B = B->getLocStart();
945 assert(L_A.isValid() && L_B.isValid());
946 return SM.isBeforeInTranslationUnit(L_A, L_B);
947 }
948 };
949}
950
951bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
952 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
953 // an @implementation can lexically contain Decls that are not properly
954 // nested in the AST. When we identify such cases, we need to retrofit
955 // this nesting here.
956 if (!DI_current && !FileDI_current)
957 return VisitDeclContext(D);
958
959 // Scan the Decls that immediately come after the container
960 // in the current DeclContext. If any fall within the
961 // container's lexical region, stash them into a vector
962 // for later processing.
963 SmallVector<Decl *, 24> DeclsInContainer;
964 SourceLocation EndLoc = D->getSourceRange().getEnd();
965 SourceManager &SM = AU->getSourceManager();
966 if (EndLoc.isValid()) {
967 if (DI_current) {
968 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
969 DeclsInContainer);
970 } else {
971 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
972 DeclsInContainer);
973 }
974 }
975
976 // The common case.
977 if (DeclsInContainer.empty())
978 return VisitDeclContext(D);
979
980 // Get all the Decls in the DeclContext, and sort them with the
981 // additional ones we've collected. Then visit them.
982 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
983 I!=E; ++I) {
984 Decl *subDecl = *I;
985 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
986 subDecl->getLocStart().isInvalid())
987 continue;
988 DeclsInContainer.push_back(subDecl);
989 }
990
991 // Now sort the Decls so that they appear in lexical order.
992 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
993 ContainerDeclsSort(SM));
994
995 // Now visit the decls.
996 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
997 E = DeclsInContainer.end(); I != E; ++I) {
998 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +0000999 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001000 if (!V.hasValue())
1001 continue;
1002 if (!V.getValue())
1003 return false;
1004 if (Visit(Cursor, true))
1005 return true;
1006 }
1007 return false;
1008}
1009
1010bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1011 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1012 TU)))
1013 return true;
1014
1015 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1016 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1017 E = ND->protocol_end(); I != E; ++I, ++PL)
1018 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1019 return true;
1020
1021 return VisitObjCContainerDecl(ND);
1022}
1023
1024bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1025 if (!PID->isThisDeclarationADefinition())
1026 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1027
1028 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1029 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1030 E = PID->protocol_end(); I != E; ++I, ++PL)
1031 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1032 return true;
1033
1034 return VisitObjCContainerDecl(PID);
1035}
1036
1037bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1038 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1039 return true;
1040
1041 // FIXME: This implements a workaround with @property declarations also being
1042 // installed in the DeclContext for the @interface. Eventually this code
1043 // should be removed.
1044 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1045 if (!CDecl || !CDecl->IsClassExtension())
1046 return false;
1047
1048 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1049 if (!ID)
1050 return false;
1051
1052 IdentifierInfo *PropertyId = PD->getIdentifier();
1053 ObjCPropertyDecl *prevDecl =
1054 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1055
1056 if (!prevDecl)
1057 return false;
1058
1059 // Visit synthesized methods since they will be skipped when visiting
1060 // the @interface.
1061 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1062 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1063 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1064 return true;
1065
1066 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1067 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1068 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1069 return true;
1070
1071 return false;
1072}
1073
1074bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1075 if (!D->isThisDeclarationADefinition()) {
1076 // Forward declaration is treated like a reference.
1077 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1078 }
1079
1080 // Issue callbacks for super class.
1081 if (D->getSuperClass() &&
1082 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1083 D->getSuperClassLoc(),
1084 TU)))
1085 return true;
1086
1087 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1088 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1089 E = D->protocol_end(); I != E; ++I, ++PL)
1090 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1091 return true;
1092
1093 return VisitObjCContainerDecl(D);
1094}
1095
1096bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1101 // 'ID' could be null when dealing with invalid code.
1102 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1103 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1104 return true;
1105
1106 return VisitObjCImplDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1110#if 0
1111 // Issue callbacks for super class.
1112 // FIXME: No source location information!
1113 if (D->getSuperClass() &&
1114 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1115 D->getSuperClassLoc(),
1116 TU)))
1117 return true;
1118#endif
1119
1120 return VisitObjCImplDecl(D);
1121}
1122
1123bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1124 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1125 if (PD->isIvarNameSpecified())
1126 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1127
1128 return false;
1129}
1130
1131bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1132 return VisitDeclContext(D);
1133}
1134
1135bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1136 // Visit nested-name-specifier.
1137 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1138 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1139 return true;
1140
1141 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1142 D->getTargetNameLoc(), TU));
1143}
1144
1145bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150 }
1151
1152 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1153 return true;
1154
1155 return VisitDeclarationNameInfo(D->getNameInfo());
1156}
1157
1158bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1159 // Visit nested-name-specifier.
1160 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1161 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1162 return true;
1163
1164 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1165 D->getIdentLocation(), TU));
1166}
1167
1168bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173 }
1174
1175 return VisitDeclarationNameInfo(D->getNameInfo());
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1179 UnresolvedUsingTypenameDecl *D) {
1180 // Visit nested-name-specifier.
1181 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1182 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1183 return true;
1184
1185 return false;
1186}
1187
1188bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1189 switch (Name.getName().getNameKind()) {
1190 case clang::DeclarationName::Identifier:
1191 case clang::DeclarationName::CXXLiteralOperatorName:
1192 case clang::DeclarationName::CXXOperatorName:
1193 case clang::DeclarationName::CXXUsingDirective:
1194 return false;
1195
1196 case clang::DeclarationName::CXXConstructorName:
1197 case clang::DeclarationName::CXXDestructorName:
1198 case clang::DeclarationName::CXXConversionFunctionName:
1199 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1200 return Visit(TSInfo->getTypeLoc());
1201 return false;
1202
1203 case clang::DeclarationName::ObjCZeroArgSelector:
1204 case clang::DeclarationName::ObjCOneArgSelector:
1205 case clang::DeclarationName::ObjCMultiArgSelector:
1206 // FIXME: Per-identifier location info?
1207 return false;
1208 }
1209
1210 llvm_unreachable("Invalid DeclarationName::Kind!");
1211}
1212
1213bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1214 SourceRange Range) {
1215 // FIXME: This whole routine is a hack to work around the lack of proper
1216 // source information in nested-name-specifiers (PR5791). Since we do have
1217 // a beginning source location, we can visit the first component of the
1218 // nested-name-specifier, if it's a single-token component.
1219 if (!NNS)
1220 return false;
1221
1222 // Get the first component in the nested-name-specifier.
1223 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1224 NNS = Prefix;
1225
1226 switch (NNS->getKind()) {
1227 case NestedNameSpecifier::Namespace:
1228 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1229 TU));
1230
1231 case NestedNameSpecifier::NamespaceAlias:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1233 Range.getBegin(), TU));
1234
1235 case NestedNameSpecifier::TypeSpec: {
1236 // If the type has a form where we know that the beginning of the source
1237 // range matches up with a reference cursor. Visit the appropriate reference
1238 // cursor.
1239 const Type *T = NNS->getAsType();
1240 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1241 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1242 if (const TagType *Tag = dyn_cast<TagType>(T))
1243 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1244 if (const TemplateSpecializationType *TST
1245 = dyn_cast<TemplateSpecializationType>(T))
1246 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1247 break;
1248 }
1249
1250 case NestedNameSpecifier::TypeSpecWithTemplate:
1251 case NestedNameSpecifier::Global:
1252 case NestedNameSpecifier::Identifier:
1253 break;
1254 }
1255
1256 return false;
1257}
1258
1259bool
1260CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1261 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1262 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1263 Qualifiers.push_back(Qualifier);
1264
1265 while (!Qualifiers.empty()) {
1266 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1267 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1268 switch (NNS->getKind()) {
1269 case NestedNameSpecifier::Namespace:
1270 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1271 Q.getLocalBeginLoc(),
1272 TU)))
1273 return true;
1274
1275 break;
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::TypeSpec:
1286 case NestedNameSpecifier::TypeSpecWithTemplate:
1287 if (Visit(Q.getTypeLoc()))
1288 return true;
1289
1290 break;
1291
1292 case NestedNameSpecifier::Global:
1293 case NestedNameSpecifier::Identifier:
1294 break;
1295 }
1296 }
1297
1298 return false;
1299}
1300
1301bool CursorVisitor::VisitTemplateParameters(
1302 const TemplateParameterList *Params) {
1303 if (!Params)
1304 return false;
1305
1306 for (TemplateParameterList::const_iterator P = Params->begin(),
1307 PEnd = Params->end();
1308 P != PEnd; ++P) {
1309 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1310 return true;
1311 }
1312
1313 return false;
1314}
1315
1316bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1317 switch (Name.getKind()) {
1318 case TemplateName::Template:
1319 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1320
1321 case TemplateName::OverloadedTemplate:
1322 // Visit the overloaded template set.
1323 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1324 return true;
1325
1326 return false;
1327
1328 case TemplateName::DependentTemplate:
1329 // FIXME: Visit nested-name-specifier.
1330 return false;
1331
1332 case TemplateName::QualifiedTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return Visit(MakeCursorTemplateRef(
1335 Name.getAsQualifiedTemplateName()->getDecl(),
1336 Loc, TU));
1337
1338 case TemplateName::SubstTemplateTemplateParm:
1339 return Visit(MakeCursorTemplateRef(
1340 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1341 Loc, TU));
1342
1343 case TemplateName::SubstTemplateTemplateParmPack:
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1346 Loc, TU));
1347 }
1348
1349 llvm_unreachable("Invalid TemplateName::Kind!");
1350}
1351
1352bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1353 switch (TAL.getArgument().getKind()) {
1354 case TemplateArgument::Null:
1355 case TemplateArgument::Integral:
1356 case TemplateArgument::Pack:
1357 return false;
1358
1359 case TemplateArgument::Type:
1360 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1361 return Visit(TSInfo->getTypeLoc());
1362 return false;
1363
1364 case TemplateArgument::Declaration:
1365 if (Expr *E = TAL.getSourceDeclExpression())
1366 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1367 return false;
1368
1369 case TemplateArgument::NullPtr:
1370 if (Expr *E = TAL.getSourceNullPtrExpression())
1371 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1372 return false;
1373
1374 case TemplateArgument::Expression:
1375 if (Expr *E = TAL.getSourceExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::Template:
1380 case TemplateArgument::TemplateExpansion:
1381 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1382 return true;
1383
1384 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1385 TAL.getTemplateNameLoc());
1386 }
1387
1388 llvm_unreachable("Invalid TemplateArgument::Kind!");
1389}
1390
1391bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1392 return VisitDeclContext(D);
1393}
1394
1395bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1396 return Visit(TL.getUnqualifiedLoc());
1397}
1398
1399bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1400 ASTContext &Context = AU->getASTContext();
1401
1402 // Some builtin types (such as Objective-C's "id", "sel", and
1403 // "Class") have associated declarations. Create cursors for those.
1404 QualType VisitType;
1405 switch (TL.getTypePtr()->getKind()) {
1406
1407 case BuiltinType::Void:
1408 case BuiltinType::NullPtr:
1409 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001410 case BuiltinType::OCLImage1d:
1411 case BuiltinType::OCLImage1dArray:
1412 case BuiltinType::OCLImage1dBuffer:
1413 case BuiltinType::OCLImage2d:
1414 case BuiltinType::OCLImage2dArray:
1415 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001416 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001417 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001418#define BUILTIN_TYPE(Id, SingletonId)
1419#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1420#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#include "clang/AST/BuiltinTypes.def"
1424 break;
1425
1426 case BuiltinType::ObjCId:
1427 VisitType = Context.getObjCIdType();
1428 break;
1429
1430 case BuiltinType::ObjCClass:
1431 VisitType = Context.getObjCClassType();
1432 break;
1433
1434 case BuiltinType::ObjCSel:
1435 VisitType = Context.getObjCSelType();
1436 break;
1437 }
1438
1439 if (!VisitType.isNull()) {
1440 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1441 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1442 TU));
1443 }
1444
1445 return false;
1446}
1447
1448bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1450}
1451
1452bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1457 if (TL.isDefinition())
1458 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1459
1460 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1468 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1469 return true;
1470
1471 return false;
1472}
1473
1474bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1475 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1476 return true;
1477
1478 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1479 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1480 TU)))
1481 return true;
1482 }
1483
1484 return false;
1485}
1486
1487bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1492 return Visit(TL.getInnerLoc());
1493}
1494
1495bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1516 return Visit(TL.getModifiedLoc());
1517}
1518
1519bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1520 bool SkipResultType) {
1521 if (!SkipResultType && Visit(TL.getResultLoc()))
1522 return true;
1523
1524 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1525 if (Decl *D = TL.getArg(I))
1526 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1527 return true;
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1533 if (Visit(TL.getElementLoc()))
1534 return true;
1535
1536 if (Expr *Size = TL.getSizeExpr())
1537 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1538
1539 return false;
1540}
1541
Reid Kleckner12df2462013-06-24 17:51:48 +00001542bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1543 return Visit(TL.getOriginalLoc());
1544}
1545
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001546bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1547 TemplateSpecializationTypeLoc TL) {
1548 // Visit the template name.
1549 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1550 TL.getTemplateNameLoc()))
1551 return true;
1552
1553 // Visit the template arguments.
1554 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1555 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1556 return true;
1557
1558 return false;
1559}
1560
1561bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1562 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1563}
1564
1565bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1566 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1567 return Visit(TSInfo->getTypeLoc());
1568
1569 return false;
1570}
1571
1572bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1573 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1574 return Visit(TSInfo->getTypeLoc());
1575
1576 return false;
1577}
1578
1579bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1580 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1581 return true;
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1587 DependentTemplateSpecializationTypeLoc TL) {
1588 // Visit the nested-name-specifier, if there is one.
1589 if (TL.getQualifierLoc() &&
1590 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 // Visit the template arguments.
1594 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1595 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1602 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1603 return true;
1604
1605 return Visit(TL.getNamedTypeLoc());
1606}
1607
1608bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1609 return Visit(TL.getPatternLoc());
1610}
1611
1612bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1613 if (Expr *E = TL.getUnderlyingExpr())
1614 return Visit(MakeCXCursor(E, StmtParent, TU));
1615
1616 return false;
1617}
1618
1619bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1620 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1621}
1622
1623bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1624 return Visit(TL.getValueLoc());
1625}
1626
1627#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1628bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1629 return Visit##PARENT##Loc(TL); \
1630}
1631
1632DEFAULT_TYPELOC_IMPL(Complex, Type)
1633DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1634DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1635DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1636DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1638DEFAULT_TYPELOC_IMPL(Vector, Type)
1639DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1640DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1641DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1642DEFAULT_TYPELOC_IMPL(Record, TagType)
1643DEFAULT_TYPELOC_IMPL(Enum, TagType)
1644DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1645DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1646DEFAULT_TYPELOC_IMPL(Auto, Type)
1647
1648bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1649 // Visit the nested-name-specifier, if present.
1650 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1651 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1652 return true;
1653
1654 if (D->isCompleteDefinition()) {
1655 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1656 E = D->bases_end(); I != E; ++I) {
1657 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1658 return true;
1659 }
1660 }
1661
1662 return VisitTagDecl(D);
1663}
1664
1665bool CursorVisitor::VisitAttributes(Decl *D) {
1666 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1667 i != e; ++i)
1668 if (Visit(MakeCXCursor(*i, D, TU)))
1669 return true;
1670
1671 return false;
1672}
1673
1674//===----------------------------------------------------------------------===//
1675// Data-recursive visitor methods.
1676//===----------------------------------------------------------------------===//
1677
1678namespace {
1679#define DEF_JOB(NAME, DATA, KIND)\
1680class NAME : public VisitorJob {\
1681public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001682 NAME(const DATA *d, CXCursor parent) : \
1683 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001684 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001685 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001686};
1687
1688DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1689DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1690DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1691DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1692DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1693 ExplicitTemplateArgsVisitKind)
1694DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1695DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1696DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1697#undef DEF_JOB
1698
1699class DeclVisit : public VisitorJob {
1700public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001701 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001702 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001703 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001704 static bool classof(const VisitorJob *VJ) {
1705 return VJ->getKind() == DeclVisitKind;
1706 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001707 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001708 bool isFirst() const { return data[1] ? true : false; }
1709};
1710class TypeLocVisit : public VisitorJob {
1711public:
1712 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1713 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1714 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1715
1716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == TypeLocVisitKind;
1718 }
1719
1720 TypeLoc get() const {
1721 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001722 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001723 }
1724};
1725
1726class LabelRefVisit : public VisitorJob {
1727public:
1728 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1729 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1730 labelLoc.getPtrEncoding()) {}
1731
1732 static bool classof(const VisitorJob *VJ) {
1733 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1734 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001735 const LabelDecl *get() const {
1736 return static_cast<const LabelDecl *>(data[0]);
1737 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001738 SourceLocation getLoc() const {
1739 return SourceLocation::getFromPtrEncoding(data[1]); }
1740};
1741
1742class NestedNameSpecifierLocVisit : public VisitorJob {
1743public:
1744 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1745 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1746 Qualifier.getNestedNameSpecifier(),
1747 Qualifier.getOpaqueData()) { }
1748
1749 static bool classof(const VisitorJob *VJ) {
1750 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1751 }
1752
1753 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001754 return NestedNameSpecifierLoc(
1755 const_cast<NestedNameSpecifier *>(
1756 static_cast<const NestedNameSpecifier *>(data[0])),
1757 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001758 }
1759};
1760
1761class DeclarationNameInfoVisit : public VisitorJob {
1762public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001763 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001764 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001765 static bool classof(const VisitorJob *VJ) {
1766 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1767 }
1768 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001769 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001770 switch (S->getStmtClass()) {
1771 default:
1772 llvm_unreachable("Unhandled Stmt");
1773 case clang::Stmt::MSDependentExistsStmtClass:
1774 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1775 case Stmt::CXXDependentScopeMemberExprClass:
1776 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1777 case Stmt::DependentScopeDeclRefExprClass:
1778 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1779 }
1780 }
1781};
1782class MemberRefVisit : public VisitorJob {
1783public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001784 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001785 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1786 L.getPtrEncoding()) {}
1787 static bool classof(const VisitorJob *VJ) {
1788 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1789 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001790 const FieldDecl *get() const {
1791 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001792 }
1793 SourceLocation getLoc() const {
1794 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1795 }
1796};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001797class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001798 friend class OMPClauseEnqueue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001799 VisitorWorkList &WL;
1800 CXCursor Parent;
1801public:
1802 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1803 : WL(wl), Parent(parent) {}
1804
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001805 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1806 void VisitBlockExpr(const BlockExpr *B);
1807 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1808 void VisitCompoundStmt(const CompoundStmt *S);
1809 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1810 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1811 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1812 void VisitCXXNewExpr(const CXXNewExpr *E);
1813 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1814 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1815 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1816 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1817 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1818 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1819 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1820 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1821 void VisitDeclRefExpr(const DeclRefExpr *D);
1822 void VisitDeclStmt(const DeclStmt *S);
1823 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1824 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1825 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1826 void VisitForStmt(const ForStmt *FS);
1827 void VisitGotoStmt(const GotoStmt *GS);
1828 void VisitIfStmt(const IfStmt *If);
1829 void VisitInitListExpr(const InitListExpr *IE);
1830 void VisitMemberExpr(const MemberExpr *M);
1831 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1832 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1833 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1834 void VisitOverloadExpr(const OverloadExpr *E);
1835 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1836 void VisitStmt(const Stmt *S);
1837 void VisitSwitchStmt(const SwitchStmt *S);
1838 void VisitWhileStmt(const WhileStmt *W);
1839 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1840 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1841 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1842 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1843 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1844 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1845 void VisitVAArgExpr(const VAArgExpr *E);
1846 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1847 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1848 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1849 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001850 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1851 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001852
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001853private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001854 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001855 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1856 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001857 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1858 void AddStmt(const Stmt *S);
1859 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001860 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001861 void EnqueueChildren(const Stmt *S);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001862 void EnqueueChildren(const OMPClause *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001863};
1864} // end anonyous namespace
1865
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001866void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001867 // 'S' should always be non-null, since it comes from the
1868 // statement we are visiting.
1869 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1870}
1871
1872void
1873EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1874 if (Qualifier)
1875 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1876}
1877
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001878void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001879 if (S)
1880 WL.push_back(StmtVisit(S, Parent));
1881}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001882void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001883 if (D)
1884 WL.push_back(DeclVisit(D, Parent, isFirst));
1885}
1886void EnqueueVisitor::
1887 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1888 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001889 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001890}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001891void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001892 if (D)
1893 WL.push_back(MemberRefVisit(D, L, Parent));
1894}
1895void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1896 if (TI)
1897 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1898 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001899void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001901 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001902 AddStmt(*Child);
1903 }
1904 if (size == WL.size())
1905 return;
1906 // Now reverse the entries we just added. This will match the DFS
1907 // ordering performed by the worklist.
1908 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1909 std::reverse(I, E);
1910}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001911namespace {
1912class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1913 EnqueueVisitor *Visitor;
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001914 /// \brief Process clauses with list of variables.
1915 template <typename T>
1916 void VisitOMPClauseList(T *Node);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001917public:
1918 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1919#define OPENMP_CLAUSE(Name, Class) \
1920 void Visit##Class(const Class *C);
1921#include "clang/Basic/OpenMPKinds.def"
1922};
1923
1924void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001925
1926template<typename T>
1927void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1928 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1929 E = Node->varlist_end();
1930 I != E; ++I)
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001931 Visitor->AddStmt(*I);
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001932}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001933
1934void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001935 VisitOMPClauseList(C);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001936}
Alexey Bataev0c018352013-09-06 18:03:48 +00001937void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001938 VisitOMPClauseList(C);
Alexey Bataev0c018352013-09-06 18:03:48 +00001939}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001940}
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001941
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001942void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1943 unsigned size = WL.size();
1944 OMPClauseEnqueue Visitor(this);
1945 Visitor.Visit(S);
1946 if (size == WL.size())
1947 return;
1948 // Now reverse the entries we just added. This will match the DFS
1949 // ordering performed by the worklist.
1950 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1951 std::reverse(I, E);
1952}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001953void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001954 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1955}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001956void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001957 AddDecl(B->getBlockDecl());
1958}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001959void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001960 EnqueueChildren(E);
1961 AddTypeLoc(E->getTypeSourceInfo());
1962}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001963void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1964 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001965 E = S->body_rend(); I != E; ++I) {
1966 AddStmt(*I);
1967 }
1968}
1969void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001970VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001971 AddStmt(S->getSubStmt());
1972 AddDeclarationNameInfo(S);
1973 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1974 AddNestedNameSpecifierLoc(QualifierLoc);
1975}
1976
1977void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001978VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001979 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1980 AddDeclarationNameInfo(E);
1981 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1982 AddNestedNameSpecifierLoc(QualifierLoc);
1983 if (!E->isImplicitAccess())
1984 AddStmt(E->getBase());
1985}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001987 // Enqueue the initializer , if any.
1988 AddStmt(E->getInitializer());
1989 // Enqueue the array size, if any.
1990 AddStmt(E->getArraySize());
1991 // Enqueue the allocated type.
1992 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1993 // Enqueue the placement arguments.
1994 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1995 AddStmt(E->getPlacementArg(I-1));
1996}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001997void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001998 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1999 AddStmt(CE->getArg(I-1));
2000 AddStmt(CE->getCallee());
2001 AddStmt(CE->getArg(0));
2002}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002003void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2004 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002005 // Visit the name of the type being destroyed.
2006 AddTypeLoc(E->getDestroyedTypeInfo());
2007 // Visit the scope type that looks disturbingly like the nested-name-specifier
2008 // but isn't.
2009 AddTypeLoc(E->getScopeTypeInfo());
2010 // Visit the nested-name-specifier.
2011 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2012 AddNestedNameSpecifierLoc(QualifierLoc);
2013 // Visit base expression.
2014 AddStmt(E->getBase());
2015}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2017 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002018 AddTypeLoc(E->getTypeSourceInfo());
2019}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2021 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002022 EnqueueChildren(E);
2023 AddTypeLoc(E->getTypeSourceInfo());
2024}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002026 EnqueueChildren(E);
2027 if (E->isTypeOperand())
2028 AddTypeLoc(E->getTypeOperandSourceInfo());
2029}
2030
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002031void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2032 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002033 EnqueueChildren(E);
2034 AddTypeLoc(E->getTypeSourceInfo());
2035}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002037 EnqueueChildren(E);
2038 if (E->isTypeOperand())
2039 AddTypeLoc(E->getTypeOperandSourceInfo());
2040}
2041
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002043 EnqueueChildren(S);
2044 AddDecl(S->getExceptionDecl());
2045}
2046
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002048 if (DR->hasExplicitTemplateArgs()) {
2049 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2050 }
2051 WL.push_back(DeclRefExprParts(DR, Parent));
2052}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2054 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002055 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2056 AddDeclarationNameInfo(E);
2057 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2058}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002060 unsigned size = WL.size();
2061 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002062 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002063 D != DEnd; ++D) {
2064 AddDecl(*D, isFirst);
2065 isFirst = false;
2066 }
2067 if (size == WL.size())
2068 return;
2069 // Now reverse the entries we just added. This will match the DFS
2070 // ordering performed by the worklist.
2071 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2072 std::reverse(I, E);
2073}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002075 AddStmt(E->getInit());
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002076 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002077 D = E->designators_rbegin(), DEnd = E->designators_rend();
2078 D != DEnd; ++D) {
2079 if (D->isFieldDesignator()) {
2080 if (FieldDecl *Field = D->getField())
2081 AddMemberRef(Field, D->getFieldLoc());
2082 continue;
2083 }
2084 if (D->isArrayDesignator()) {
2085 AddStmt(E->getArrayIndex(*D));
2086 continue;
2087 }
2088 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2089 AddStmt(E->getArrayRangeEnd(*D));
2090 AddStmt(E->getArrayRangeStart(*D));
2091 }
2092}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002094 EnqueueChildren(E);
2095 AddTypeLoc(E->getTypeInfoAsWritten());
2096}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002098 AddStmt(FS->getBody());
2099 AddStmt(FS->getInc());
2100 AddStmt(FS->getCond());
2101 AddDecl(FS->getConditionVariable());
2102 AddStmt(FS->getInit());
2103}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002105 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2106}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002108 AddStmt(If->getElse());
2109 AddStmt(If->getThen());
2110 AddStmt(If->getCond());
2111 AddDecl(If->getConditionVariable());
2112}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002114 // We care about the syntactic form of the initializer list, only.
2115 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2116 IE = Syntactic;
2117 EnqueueChildren(IE);
2118}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002120 WL.push_back(MemberExprParts(M, Parent));
2121
2122 // If the base of the member access expression is an implicit 'this', don't
2123 // visit it.
2124 // FIXME: If we ever want to show these implicit accesses, this will be
2125 // unfortunate. However, clang_getCursor() relies on this behavior.
2126 if (!M->isImplicitAccess())
2127 AddStmt(M->getBase());
2128}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002130 AddTypeLoc(E->getEncodedTypeSourceInfo());
2131}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002133 EnqueueChildren(M);
2134 AddTypeLoc(M->getClassReceiverTypeInfo());
2135}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002137 // Visit the components of the offsetof expression.
2138 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2139 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2140 const OffsetOfNode &Node = E->getComponent(I-1);
2141 switch (Node.getKind()) {
2142 case OffsetOfNode::Array:
2143 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2144 break;
2145 case OffsetOfNode::Field:
2146 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2147 break;
2148 case OffsetOfNode::Identifier:
2149 case OffsetOfNode::Base:
2150 continue;
2151 }
2152 }
2153 // Visit the type into which we're computing the offset.
2154 AddTypeLoc(E->getTypeSourceInfo());
2155}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002157 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2158 WL.push_back(OverloadExprParts(E, Parent));
2159}
2160void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002161 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002162 EnqueueChildren(E);
2163 if (E->isArgumentType())
2164 AddTypeLoc(E->getArgumentTypeInfo());
2165}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 EnqueueChildren(S);
2168}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002170 AddStmt(S->getBody());
2171 AddStmt(S->getCond());
2172 AddDecl(S->getConditionVariable());
2173}
2174
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002176 AddStmt(W->getBody());
2177 AddStmt(W->getCond());
2178 AddDecl(W->getConditionVariable());
2179}
2180
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002182 AddTypeLoc(E->getQueriedTypeSourceInfo());
2183}
2184
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002186 AddTypeLoc(E->getRhsTypeSourceInfo());
2187 AddTypeLoc(E->getLhsTypeSourceInfo());
2188}
2189
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002191 for (unsigned I = E->getNumArgs(); I > 0; --I)
2192 AddTypeLoc(E->getArg(I-1));
2193}
2194
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002196 AddTypeLoc(E->getQueriedTypeSourceInfo());
2197}
2198
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002200 EnqueueChildren(E);
2201}
2202
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002204 VisitOverloadExpr(U);
2205 if (!U->isImplicitAccess())
2206 AddStmt(U->getBase());
2207}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002209 AddStmt(E->getSubExpr());
2210 AddTypeLoc(E->getWrittenTypeInfo());
2211}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002213 WL.push_back(SizeOfPackExprParts(E, Parent));
2214}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002216 // If the opaque value has a source expression, just transparently
2217 // visit that. This is useful for (e.g.) pseudo-object expressions.
2218 if (Expr *SourceExpr = E->getSourceExpr())
2219 return Visit(SourceExpr);
2220}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002222 AddStmt(E->getBody());
2223 WL.push_back(LambdaExprParts(E, Parent));
2224}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002226 // Treat the expression like its syntactic form.
2227 Visit(E->getSyntacticForm());
2228}
2229
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002230void EnqueueVisitor::VisitOMPExecutableDirective(
2231 const OMPExecutableDirective *D) {
2232 EnqueueChildren(D);
2233 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2234 E = D->clauses().end();
2235 I != E; ++I)
2236 EnqueueChildren(*I);
2237}
2238
2239void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2240 VisitOMPExecutableDirective(D);
2241}
2242
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002243void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002244 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2245}
2246
2247bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2248 if (RegionOfInterest.isValid()) {
2249 SourceRange Range = getRawCursorExtent(C);
2250 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2251 return false;
2252 }
2253 return true;
2254}
2255
2256bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2257 while (!WL.empty()) {
2258 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002259 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002260
2261 // Set the Parent field, then back to its old value once we're done.
2262 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2263
2264 switch (LI.getKind()) {
2265 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002266 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002267 if (!D)
2268 continue;
2269
2270 // For now, perform default visitation for Decls.
2271 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2272 cast<DeclVisit>(&LI)->isFirst())))
2273 return true;
2274
2275 continue;
2276 }
2277 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2278 const ASTTemplateArgumentListInfo *ArgList =
2279 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2280 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2281 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2282 Arg != ArgEnd; ++Arg) {
2283 if (VisitTemplateArgumentLoc(*Arg))
2284 return true;
2285 }
2286 continue;
2287 }
2288 case VisitorJob::TypeLocVisitKind: {
2289 // Perform default visitation for TypeLocs.
2290 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2291 return true;
2292 continue;
2293 }
2294 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002295 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002296 if (LabelStmt *stmt = LS->getStmt()) {
2297 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2298 TU))) {
2299 return true;
2300 }
2301 }
2302 continue;
2303 }
2304
2305 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2306 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2307 if (VisitNestedNameSpecifierLoc(V->get()))
2308 return true;
2309 continue;
2310 }
2311
2312 case VisitorJob::DeclarationNameInfoVisitKind: {
2313 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2314 ->get()))
2315 return true;
2316 continue;
2317 }
2318 case VisitorJob::MemberRefVisitKind: {
2319 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2320 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2321 return true;
2322 continue;
2323 }
2324 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002325 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002326 if (!S)
2327 continue;
2328
2329 // Update the current cursor.
2330 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2331 if (!IsInRegionOfInterest(Cursor))
2332 continue;
2333 switch (Visitor(Cursor, Parent, ClientData)) {
2334 case CXChildVisit_Break: return true;
2335 case CXChildVisit_Continue: break;
2336 case CXChildVisit_Recurse:
2337 if (PostChildrenVisitor)
2338 WL.push_back(PostChildrenVisit(0, Cursor));
2339 EnqueueWorkList(WL, S);
2340 break;
2341 }
2342 continue;
2343 }
2344 case VisitorJob::MemberExprPartsKind: {
2345 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002346 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002347
2348 // Visit the nested-name-specifier
2349 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2350 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2351 return true;
2352
2353 // Visit the declaration name.
2354 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2355 return true;
2356
2357 // Visit the explicitly-specified template arguments, if any.
2358 if (M->hasExplicitTemplateArgs()) {
2359 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2360 *ArgEnd = Arg + M->getNumTemplateArgs();
2361 Arg != ArgEnd; ++Arg) {
2362 if (VisitTemplateArgumentLoc(*Arg))
2363 return true;
2364 }
2365 }
2366 continue;
2367 }
2368 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002369 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002370 // Visit nested-name-specifier, if present.
2371 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2372 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2373 return true;
2374 // Visit declaration name.
2375 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2376 return true;
2377 continue;
2378 }
2379 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002380 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002381 // Visit the nested-name-specifier.
2382 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2383 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2384 return true;
2385 // Visit the declaration name.
2386 if (VisitDeclarationNameInfo(O->getNameInfo()))
2387 return true;
2388 // Visit the overloaded declaration reference.
2389 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002394 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002395 NamedDecl *Pack = E->getPack();
2396 if (isa<TemplateTypeParmDecl>(Pack)) {
2397 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2398 E->getPackLoc(), TU)))
2399 return true;
2400
2401 continue;
2402 }
2403
2404 if (isa<TemplateTemplateParmDecl>(Pack)) {
2405 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2406 E->getPackLoc(), TU)))
2407 return true;
2408
2409 continue;
2410 }
2411
2412 // Non-type template parameter packs and function parameter packs are
2413 // treated like DeclRefExpr cursors.
2414 continue;
2415 }
2416
2417 case VisitorJob::LambdaExprPartsKind: {
2418 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002419 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002420 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2421 CEnd = E->explicit_capture_end();
2422 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002423 // FIXME: Lambda init-captures.
2424 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002425 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002426
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002427 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2428 C->getLocation(),
2429 TU)))
2430 return true;
2431 }
2432
2433 // Visit parameters and return type, if present.
2434 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2435 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2436 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2437 // Visit the whole type.
2438 if (Visit(TL))
2439 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002440 } else if (FunctionProtoTypeLoc Proto =
2441 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002442 if (E->hasExplicitParameters()) {
2443 // Visit parameters.
2444 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2445 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2446 return true;
2447 } else {
2448 // Visit result type.
2449 if (Visit(Proto.getResultLoc()))
2450 return true;
2451 }
2452 }
2453 }
2454 break;
2455 }
2456
2457 case VisitorJob::PostChildrenVisitKind:
2458 if (PostChildrenVisitor(Parent, ClientData))
2459 return true;
2460 break;
2461 }
2462 }
2463 return false;
2464}
2465
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002466bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002467 VisitorWorkList *WL = 0;
2468 if (!WorkListFreeList.empty()) {
2469 WL = WorkListFreeList.back();
2470 WL->clear();
2471 WorkListFreeList.pop_back();
2472 }
2473 else {
2474 WL = new VisitorWorkList();
2475 WorkListCache.push_back(WL);
2476 }
2477 EnqueueWorkList(*WL, S);
2478 bool result = RunVisitorWorkList(*WL);
2479 WorkListFreeList.push_back(WL);
2480 return result;
2481}
2482
2483namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002484typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002485RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2486 const DeclarationNameInfo &NI,
2487 const SourceRange &QLoc,
2488 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2489 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2490 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2491 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2492
2493 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2494
2495 RefNamePieces Pieces;
2496
2497 if (WantQualifier && QLoc.isValid())
2498 Pieces.push_back(QLoc);
2499
2500 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2501 Pieces.push_back(NI.getLoc());
2502
2503 if (WantTemplateArgs && TemplateArgs)
2504 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2505 TemplateArgs->RAngleLoc));
2506
2507 if (Kind == DeclarationName::CXXOperatorName) {
2508 Pieces.push_back(SourceLocation::getFromRawEncoding(
2509 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2510 Pieces.push_back(SourceLocation::getFromRawEncoding(
2511 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2512 }
2513
2514 if (WantSinglePiece) {
2515 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2516 Pieces.clear();
2517 Pieces.push_back(R);
2518 }
2519
2520 return Pieces;
2521}
2522}
2523
2524//===----------------------------------------------------------------------===//
2525// Misc. API hooks.
2526//===----------------------------------------------------------------------===//
2527
2528static llvm::sys::Mutex EnableMultithreadingMutex;
2529static bool EnabledMultithreading;
2530
Chad Rosier90836282013-03-27 18:28:23 +00002531static void fatal_error_handler(void *user_data, const std::string& reason,
2532 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002533 // Write the result out to stderr avoiding errs() because raw_ostreams can
2534 // call report_fatal_error.
2535 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2536 ::abort();
2537}
2538
2539extern "C" {
2540CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2541 int displayDiagnostics) {
2542 // Disable pretty stack trace functionality, which will otherwise be a very
2543 // poor citizen of the world and set up all sorts of signal handlers.
2544 llvm::DisablePrettyStackTrace = true;
2545
2546 // We use crash recovery to make some of our APIs more reliable, implicitly
2547 // enable it.
2548 llvm::CrashRecoveryContext::Enable();
2549
2550 // Enable support for multithreading in LLVM.
2551 {
2552 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2553 if (!EnabledMultithreading) {
2554 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2555 llvm::llvm_start_multithreaded();
2556 EnabledMultithreading = true;
2557 }
2558 }
2559
2560 CIndexer *CIdxr = new CIndexer();
2561 if (excludeDeclarationsFromPCH)
2562 CIdxr->setOnlyLocalDecls();
2563 if (displayDiagnostics)
2564 CIdxr->setDisplayDiagnostics();
2565
2566 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2567 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2568 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2569 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2570 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2571 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2572
2573 return CIdxr;
2574}
2575
2576void clang_disposeIndex(CXIndex CIdx) {
2577 if (CIdx)
2578 delete static_cast<CIndexer *>(CIdx);
2579}
2580
2581void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2582 if (CIdx)
2583 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2584}
2585
2586unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2587 if (CIdx)
2588 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2589 return 0;
2590}
2591
2592void clang_toggleCrashRecovery(unsigned isEnabled) {
2593 if (isEnabled)
2594 llvm::CrashRecoveryContext::Enable();
2595 else
2596 llvm::CrashRecoveryContext::Disable();
2597}
2598
2599CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2600 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002601 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002602 return 0;
2603
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002604 LOG_FUNC_SECTION {
2605 *Log << ast_filename;
2606 }
2607
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002608 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2609 FileSystemOptions FileSystemOpts;
2610
2611 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2612 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2613 CXXIdx->getOnlyLocalDecls(),
2614 0, 0,
2615 /*CaptureDiagnostics=*/true,
2616 /*AllowPCHWithCompilerErrors=*/true,
2617 /*UserFilesAreVolatile=*/true);
2618 return MakeCXTranslationUnit(CXXIdx, TU);
2619}
2620
2621unsigned clang_defaultEditingTranslationUnitOptions() {
2622 return CXTranslationUnit_PrecompiledPreamble |
2623 CXTranslationUnit_CacheCompletionResults;
2624}
2625
2626CXTranslationUnit
2627clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2628 const char *source_filename,
2629 int num_command_line_args,
2630 const char * const *command_line_args,
2631 unsigned num_unsaved_files,
2632 struct CXUnsavedFile *unsaved_files) {
2633 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2634 return clang_parseTranslationUnit(CIdx, source_filename,
2635 command_line_args, num_command_line_args,
2636 unsaved_files, num_unsaved_files,
2637 Options);
2638}
2639
2640struct ParseTranslationUnitInfo {
2641 CXIndex CIdx;
2642 const char *source_filename;
2643 const char *const *command_line_args;
2644 int num_command_line_args;
2645 struct CXUnsavedFile *unsaved_files;
2646 unsigned num_unsaved_files;
2647 unsigned options;
2648 CXTranslationUnit result;
2649};
2650static void clang_parseTranslationUnit_Impl(void *UserData) {
2651 ParseTranslationUnitInfo *PTUI =
2652 static_cast<ParseTranslationUnitInfo*>(UserData);
2653 CXIndex CIdx = PTUI->CIdx;
2654 const char *source_filename = PTUI->source_filename;
2655 const char * const *command_line_args = PTUI->command_line_args;
2656 int num_command_line_args = PTUI->num_command_line_args;
2657 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2658 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2659 unsigned options = PTUI->options;
2660 PTUI->result = 0;
2661
2662 if (!CIdx)
2663 return;
2664
2665 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2666
2667 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2668 setThreadBackgroundPriority();
2669
2670 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2671 // FIXME: Add a flag for modules.
2672 TranslationUnitKind TUKind
2673 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2674 bool CacheCodeCompetionResults
2675 = options & CXTranslationUnit_CacheCompletionResults;
2676 bool IncludeBriefCommentsInCodeCompletion
2677 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2678 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2679 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2680
2681 // Configure the diagnostics.
2682 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002683 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002684
2685 // Recover resources if we crash before exiting this function.
2686 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2687 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2688 DiagCleanup(Diags.getPtr());
2689
2690 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2691 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2692
2693 // Recover resources if we crash before exiting this function.
2694 llvm::CrashRecoveryContextCleanupRegistrar<
2695 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2696
2697 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2698 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2699 const llvm::MemoryBuffer *Buffer
2700 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2701 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2702 Buffer));
2703 }
2704
2705 OwningPtr<std::vector<const char *> >
2706 Args(new std::vector<const char*>());
2707
2708 // Recover resources if we crash before exiting this method.
2709 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2710 ArgsCleanup(Args.get());
2711
2712 // Since the Clang C library is primarily used by batch tools dealing with
2713 // (often very broken) source code, where spell-checking can have a
2714 // significant negative impact on performance (particularly when
2715 // precompiled headers are involved), we disable it by default.
2716 // Only do this if we haven't found a spell-checking-related argument.
2717 bool FoundSpellCheckingArgument = false;
2718 for (int I = 0; I != num_command_line_args; ++I) {
2719 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2720 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2721 FoundSpellCheckingArgument = true;
2722 break;
2723 }
2724 }
2725 if (!FoundSpellCheckingArgument)
2726 Args->push_back("-fno-spell-checking");
2727
2728 Args->insert(Args->end(), command_line_args,
2729 command_line_args + num_command_line_args);
2730
2731 // The 'source_filename' argument is optional. If the caller does not
2732 // specify it then it is assumed that the source file is specified
2733 // in the actual argument list.
2734 // Put the source file after command_line_args otherwise if '-x' flag is
2735 // present it will be unused.
2736 if (source_filename)
2737 Args->push_back(source_filename);
2738
2739 // Do we need the detailed preprocessing record?
2740 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2741 Args->push_back("-Xclang");
2742 Args->push_back("-detailed-preprocessing-record");
2743 }
2744
2745 unsigned NumErrors = Diags->getClient()->getNumErrors();
2746 OwningPtr<ASTUnit> ErrUnit;
2747 OwningPtr<ASTUnit> Unit(
2748 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2749 /* vector::data() not portable */,
2750 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2751 Diags,
2752 CXXIdx->getClangResourcesPath(),
2753 CXXIdx->getOnlyLocalDecls(),
2754 /*CaptureDiagnostics=*/true,
2755 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2756 RemappedFiles->size(),
2757 /*RemappedFilesKeepOriginalName=*/true,
2758 PrecompilePreamble,
2759 TUKind,
2760 CacheCodeCompetionResults,
2761 IncludeBriefCommentsInCodeCompletion,
2762 /*AllowPCHWithCompilerErrors=*/true,
2763 SkipFunctionBodies,
2764 /*UserFilesAreVolatile=*/true,
2765 ForSerialization,
2766 &ErrUnit));
2767
2768 if (NumErrors != Diags->getClient()->getNumErrors()) {
2769 // Make sure to check that 'Unit' is non-NULL.
2770 if (CXXIdx->getDisplayDiagnostics())
2771 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2772 }
2773
2774 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2775}
2776CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2777 const char *source_filename,
2778 const char * const *command_line_args,
2779 int num_command_line_args,
2780 struct CXUnsavedFile *unsaved_files,
2781 unsigned num_unsaved_files,
2782 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002783 LOG_FUNC_SECTION {
2784 *Log << source_filename << ": ";
2785 for (int i = 0; i != num_command_line_args; ++i)
2786 *Log << command_line_args[i] << " ";
2787 }
2788
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002789 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2790 num_command_line_args, unsaved_files,
2791 num_unsaved_files, options, 0 };
2792 llvm::CrashRecoveryContext CRC;
2793
2794 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2795 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2796 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2797 fprintf(stderr, " 'command_line_args' : [");
2798 for (int i = 0; i != num_command_line_args; ++i) {
2799 if (i)
2800 fprintf(stderr, ", ");
2801 fprintf(stderr, "'%s'", command_line_args[i]);
2802 }
2803 fprintf(stderr, "],\n");
2804 fprintf(stderr, " 'unsaved_files' : [");
2805 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2806 if (i)
2807 fprintf(stderr, ", ");
2808 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2809 unsaved_files[i].Length);
2810 }
2811 fprintf(stderr, "],\n");
2812 fprintf(stderr, " 'options' : %d,\n", options);
2813 fprintf(stderr, "}\n");
2814
2815 return 0;
2816 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2817 PrintLibclangResourceUsage(PTUI.result);
2818 }
2819
2820 return PTUI.result;
2821}
2822
2823unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2824 return CXSaveTranslationUnit_None;
2825}
2826
2827namespace {
2828
2829struct SaveTranslationUnitInfo {
2830 CXTranslationUnit TU;
2831 const char *FileName;
2832 unsigned options;
2833 CXSaveError result;
2834};
2835
2836}
2837
2838static void clang_saveTranslationUnit_Impl(void *UserData) {
2839 SaveTranslationUnitInfo *STUI =
2840 static_cast<SaveTranslationUnitInfo*>(UserData);
2841
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002842 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002843 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2844 setThreadBackgroundPriority();
2845
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002846 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002847 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2848}
2849
2850int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2851 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002852 LOG_FUNC_SECTION {
2853 *Log << TU << ' ' << FileName;
2854 }
2855
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002856 if (!TU)
2857 return CXSaveError_InvalidTU;
2858
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002860 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2861 if (!CXXUnit->hasSema())
2862 return CXSaveError_InvalidTU;
2863
2864 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2865
2866 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2867 getenv("LIBCLANG_NOTHREADS")) {
2868 clang_saveTranslationUnit_Impl(&STUI);
2869
2870 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2871 PrintLibclangResourceUsage(TU);
2872
2873 return STUI.result;
2874 }
2875
2876 // We have an AST that has invalid nodes due to compiler errors.
2877 // Use a crash recovery thread for protection.
2878
2879 llvm::CrashRecoveryContext CRC;
2880
2881 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2882 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2883 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2884 fprintf(stderr, " 'options' : %d,\n", options);
2885 fprintf(stderr, "}\n");
2886
2887 return CXSaveError_Unknown;
2888
2889 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2890 PrintLibclangResourceUsage(TU);
2891 }
2892
2893 return STUI.result;
2894}
2895
2896void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2897 if (CTUnit) {
2898 // If the translation unit has been marked as unsafe to free, just discard
2899 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002900 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002901 return;
2902
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002903 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002904 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002905 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2906 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002907 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002908 delete CTUnit;
2909 }
2910}
2911
2912unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2913 return CXReparse_None;
2914}
2915
2916struct ReparseTranslationUnitInfo {
2917 CXTranslationUnit TU;
2918 unsigned num_unsaved_files;
2919 struct CXUnsavedFile *unsaved_files;
2920 unsigned options;
2921 int result;
2922};
2923
2924static void clang_reparseTranslationUnit_Impl(void *UserData) {
2925 ReparseTranslationUnitInfo *RTUI =
2926 static_cast<ReparseTranslationUnitInfo*>(UserData);
2927 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002928 if (!TU)
2929 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002930
2931 // Reset the associated diagnostics.
2932 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2933 TU->Diagnostics = 0;
2934
2935 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2936 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2937 unsigned options = RTUI->options;
2938 (void) options;
2939 RTUI->result = 1;
2940
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002941 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002942 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2943 setThreadBackgroundPriority();
2944
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002946 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2947
2948 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2949 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2950
2951 // Recover resources if we crash before exiting this function.
2952 llvm::CrashRecoveryContextCleanupRegistrar<
2953 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2954
2955 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2956 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2957 const llvm::MemoryBuffer *Buffer
2958 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2959 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2960 Buffer));
2961 }
2962
2963 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2964 RemappedFiles->size()))
2965 RTUI->result = 0;
2966}
2967
2968int clang_reparseTranslationUnit(CXTranslationUnit TU,
2969 unsigned num_unsaved_files,
2970 struct CXUnsavedFile *unsaved_files,
2971 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002972 LOG_FUNC_SECTION {
2973 *Log << TU;
2974 }
2975
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002976 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2977 options, 0 };
2978
2979 if (getenv("LIBCLANG_NOTHREADS")) {
2980 clang_reparseTranslationUnit_Impl(&RTUI);
2981 return RTUI.result;
2982 }
2983
2984 llvm::CrashRecoveryContext CRC;
2985
2986 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2987 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002988 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002989 return 1;
2990 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2991 PrintLibclangResourceUsage(TU);
2992
2993 return RTUI.result;
2994}
2995
2996
2997CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2998 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002999 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003000
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003001 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003002 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003003}
3004
3005CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003006 if (!TU)
3007 return clang_getNullCursor();
3008
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003010 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3011}
3012
3013} // end: extern "C"
3014
3015//===----------------------------------------------------------------------===//
3016// CXFile Operations.
3017//===----------------------------------------------------------------------===//
3018
3019extern "C" {
3020CXString clang_getFileName(CXFile SFile) {
3021 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00003022 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003023
3024 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003025 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003026}
3027
3028time_t clang_getFileTime(CXFile SFile) {
3029 if (!SFile)
3030 return 0;
3031
3032 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3033 return FEnt->getModificationTime();
3034}
3035
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003036CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3037 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003038 return 0;
3039
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003041
3042 FileManager &FMgr = CXXUnit->getFileManager();
3043 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3044}
3045
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003046unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3047 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003048 return 0;
3049
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003050 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 FileEntry *FEnt = static_cast<FileEntry *>(file);
3052 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3053 .isFileMultipleIncludeGuarded(FEnt);
3054}
3055
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003056int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3057 if (!file || !outID)
3058 return 1;
3059
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003060 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-08-01 21:42:11 +00003061 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3062 outID->data[0] = ID.getDevice();
3063 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003064 outID->data[2] = FEnt->getModificationTime();
3065 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003066}
3067
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003068} // end: extern "C"
3069
3070//===----------------------------------------------------------------------===//
3071// CXCursor Operations.
3072//===----------------------------------------------------------------------===//
3073
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003074static const Decl *getDeclFromExpr(const Stmt *E) {
3075 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003076 return getDeclFromExpr(CE->getSubExpr());
3077
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003078 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003079 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003080 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003081 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003082 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003083 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003084 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003085 if (PRE->isExplicitProperty())
3086 return PRE->getExplicitProperty();
3087 // It could be messaging both getter and setter as in:
3088 // ++myobj.myprop;
3089 // in which case prefer to associate the setter since it is less obvious
3090 // from inspecting the source that the setter is going to get called.
3091 if (PRE->isMessagingSetter())
3092 return PRE->getImplicitPropertySetter();
3093 return PRE->getImplicitPropertyGetter();
3094 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003095 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003096 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003097 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003098 if (Expr *Src = OVE->getSourceExpr())
3099 return getDeclFromExpr(Src);
3100
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003101 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003102 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003103 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003104 if (!CE->isElidable())
3105 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003106 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003107 return OME->getMethodDecl();
3108
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003109 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003110 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003111 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003112 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3113 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003114 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003115 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3116 isa<ParmVarDecl>(SizeOfPack->getPack()))
3117 return SizeOfPack->getPack();
3118
3119 return 0;
3120}
3121
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003122static SourceLocation getLocationFromExpr(const Expr *E) {
3123 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003124 return getLocationFromExpr(CE->getSubExpr());
3125
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003126 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003127 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003128 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003129 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003130 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003131 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003132 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003134 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003136 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003137 return PropRef->getLocation();
3138
3139 return E->getLocStart();
3140}
3141
3142extern "C" {
3143
3144unsigned clang_visitChildren(CXCursor parent,
3145 CXCursorVisitor visitor,
3146 CXClientData client_data) {
3147 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3148 /*VisitPreprocessorLast=*/false);
3149 return CursorVis.VisitChildren(parent);
3150}
3151
3152#ifndef __has_feature
3153#define __has_feature(x) 0
3154#endif
3155#if __has_feature(blocks)
3156typedef enum CXChildVisitResult
3157 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3158
3159static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3160 CXClientData client_data) {
3161 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3162 return block(cursor, parent);
3163}
3164#else
3165// If we are compiled with a compiler that doesn't have native blocks support,
3166// define and call the block manually, so the
3167typedef struct _CXChildVisitResult
3168{
3169 void *isa;
3170 int flags;
3171 int reserved;
3172 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3173 CXCursor);
3174} *CXCursorVisitorBlock;
3175
3176static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3177 CXClientData client_data) {
3178 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3179 return block->invoke(block, cursor, parent);
3180}
3181#endif
3182
3183
3184unsigned clang_visitChildrenWithBlock(CXCursor parent,
3185 CXCursorVisitorBlock block) {
3186 return clang_visitChildren(parent, visitWithBlock, block);
3187}
3188
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003189static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003190 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003191 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003193 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003194 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003195 if (const ObjCPropertyImplDecl *PropImpl =
3196 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003198 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003200 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003201 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003202 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003204 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205 }
3206
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003207 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003208 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003210 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003211 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3212 // and returns different names. NamedDecl returns the class name and
3213 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003214 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003215
3216 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003217 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003218
3219 SmallString<1024> S;
3220 llvm::raw_svector_ostream os(S);
3221 ND->printName(os);
3222
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003223 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003224}
3225
3226CXString clang_getCursorSpelling(CXCursor C) {
3227 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003228 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003229
3230 if (clang_isReference(C.kind)) {
3231 switch (C.kind) {
3232 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003233 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003234 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003235 }
3236 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003237 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003238 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003239 }
3240 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003241 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003243 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003244 }
3245 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003246 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003247 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003248 }
3249 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003250 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003251 assert(Type && "Missing type decl");
3252
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003253 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003254 getAsString());
3255 }
3256 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003257 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 assert(Template && "Missing template decl");
3259
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003260 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003261 }
3262
3263 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003264 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003265 assert(NS && "Missing namespace decl");
3266
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003267 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003268 }
3269
3270 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003271 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003272 assert(Field && "Missing member decl");
3273
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003274 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003275 }
3276
3277 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003278 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003279 assert(Label && "Missing label");
3280
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003281 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282 }
3283
3284 case CXCursor_OverloadedDeclRef: {
3285 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003286 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3287 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003288 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003289 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003290 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003291 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003292 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293 OverloadedTemplateStorage *Ovl
3294 = Storage.get<OverloadedTemplateStorage*>();
3295 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003297 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003298 }
3299
3300 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003301 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003302 assert(Var && "Missing variable decl");
3303
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003304 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003305 }
3306
3307 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003308 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003309 }
3310 }
3311
3312 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003313 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003314 if (D)
3315 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003316 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003317 }
3318
3319 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003320 const Stmt *S = getCursorStmt(C);
3321 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003322 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003323
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003325 }
3326
3327 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003328 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003329 ->getNameStart());
3330
3331 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003332 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003333 ->getNameStart());
3334
3335 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003336 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003337
3338 if (clang_isDeclaration(C.kind))
3339 return getDeclSpelling(getCursorDecl(C));
3340
3341 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003342 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003343 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003344 }
3345
3346 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003347 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003348 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003349 }
3350
Argyrios Kyrtzidis51337112013-09-25 00:14:38 +00003351 if (C.kind == CXCursor_PackedAttr) {
3352 return cxstring::createRef("packed");
3353 }
3354
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003355 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003356}
3357
3358CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3359 unsigned pieceIndex,
3360 unsigned options) {
3361 if (clang_Cursor_isNull(C))
3362 return clang_getNullRange();
3363
3364 ASTContext &Ctx = getCursorContext(C);
3365
3366 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003367 const Stmt *S = getCursorStmt(C);
3368 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003369 if (pieceIndex > 0)
3370 return clang_getNullRange();
3371 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3372 }
3373
3374 return clang_getNullRange();
3375 }
3376
3377 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003378 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003379 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3380 if (pieceIndex >= ME->getNumSelectorLocs())
3381 return clang_getNullRange();
3382 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3383 }
3384 }
3385
3386 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3387 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003388 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003389 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3390 if (pieceIndex >= MD->getNumSelectorLocs())
3391 return clang_getNullRange();
3392 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3393 }
3394 }
3395
3396 if (C.kind == CXCursor_ObjCCategoryDecl ||
3397 C.kind == CXCursor_ObjCCategoryImplDecl) {
3398 if (pieceIndex > 0)
3399 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003400 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003401 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3402 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003403 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003404 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3405 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3406 }
3407
3408 if (C.kind == CXCursor_ModuleImportDecl) {
3409 if (pieceIndex > 0)
3410 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003411 if (const ImportDecl *ImportD =
3412 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003413 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3414 if (!Locs.empty())
3415 return cxloc::translateSourceRange(Ctx,
3416 SourceRange(Locs.front(), Locs.back()));
3417 }
3418 return clang_getNullRange();
3419 }
3420
3421 // FIXME: A CXCursor_InclusionDirective should give the location of the
3422 // filename, but we don't keep track of this.
3423
3424 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3425 // but we don't keep track of this.
3426
3427 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3428 // but we don't keep track of this.
3429
3430 // Default handling, give the location of the cursor.
3431
3432 if (pieceIndex > 0)
3433 return clang_getNullRange();
3434
3435 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3436 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3437 return cxloc::translateSourceRange(Ctx, Loc);
3438}
3439
3440CXString clang_getCursorDisplayName(CXCursor C) {
3441 if (!clang_isDeclaration(C.kind))
3442 return clang_getCursorSpelling(C);
3443
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003444 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003445 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003446 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003447
3448 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003449 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003450 D = FunTmpl->getTemplatedDecl();
3451
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003452 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003453 SmallString<64> Str;
3454 llvm::raw_svector_ostream OS(Str);
3455 OS << *Function;
3456 if (Function->getPrimaryTemplate())
3457 OS << "<>";
3458 OS << "(";
3459 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3460 if (I)
3461 OS << ", ";
3462 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3463 }
3464
3465 if (Function->isVariadic()) {
3466 if (Function->getNumParams())
3467 OS << ", ";
3468 OS << "...";
3469 }
3470 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003471 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003472 }
3473
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003474 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 SmallString<64> Str;
3476 llvm::raw_svector_ostream OS(Str);
3477 OS << *ClassTemplate;
3478 OS << "<";
3479 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3480 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3481 if (I)
3482 OS << ", ";
3483
3484 NamedDecl *Param = Params->getParam(I);
3485 if (Param->getIdentifier()) {
3486 OS << Param->getIdentifier()->getName();
3487 continue;
3488 }
3489
3490 // There is no parameter name, which makes this tricky. Try to come up
3491 // with something useful that isn't too long.
3492 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3493 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3494 else if (NonTypeTemplateParmDecl *NTTP
3495 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3496 OS << NTTP->getType().getAsString(Policy);
3497 else
3498 OS << "template<...> class";
3499 }
3500
3501 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003502 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 }
3504
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003505 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003506 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3507 // If the type was explicitly written, use that.
3508 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003509 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510
Benjamin Kramer5eada842013-02-22 15:46:01 +00003511 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003512 llvm::raw_svector_ostream OS(Str);
3513 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003514 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 ClassSpec->getTemplateArgs().data(),
3516 ClassSpec->getTemplateArgs().size(),
3517 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003518 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 }
3520
3521 return clang_getCursorSpelling(C);
3522}
3523
3524CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3525 switch (Kind) {
3526 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003654 case CXCursor_ObjCSelfExpr:
3655 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003739 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003740 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003741 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003742 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003743 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003744 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003745 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003746 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003747 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003748 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003749 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003750 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003751 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003752 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003753 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003754 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003755 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003756 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003757 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003758 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003759 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003760 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003761 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003762 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003763 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003764 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003765 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003766 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003767 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003768 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003769 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003770 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003771 return cxstring::createRef("asm label");
Argyrios Kyrtzidis51337112013-09-25 00:14:38 +00003772 case CXCursor_PackedAttr:
3773 return cxstring::createRef("attribute(packed)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003774 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003775 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003776 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003777 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003778 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003779 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003780 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003781 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003782 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003783 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003784 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003785 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003786 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003787 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003788 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003790 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003791 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003792 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003794 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003795 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003797 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003798 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003799 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003801 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003802 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003803 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003804 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003805 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003806 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003807 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003808 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003809 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003810 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003811 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003812 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003813 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003814 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003816 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003818 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003819 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003820 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003821 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003822 case CXCursor_OMPParallelDirective:
3823 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003824 }
3825
3826 llvm_unreachable("Unhandled CXCursorKind");
3827}
3828
3829struct GetCursorData {
3830 SourceLocation TokenBeginLoc;
3831 bool PointsAtMacroArgExpansion;
3832 bool VisitedObjCPropertyImplDecl;
3833 SourceLocation VisitedDeclaratorDeclStartLoc;
3834 CXCursor &BestCursor;
3835
3836 GetCursorData(SourceManager &SM,
3837 SourceLocation tokenBegin, CXCursor &outputCursor)
3838 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3839 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3840 VisitedObjCPropertyImplDecl = false;
3841 }
3842};
3843
3844static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3845 CXCursor parent,
3846 CXClientData client_data) {
3847 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3848 CXCursor *BestCursor = &Data->BestCursor;
3849
3850 // If we point inside a macro argument we should provide info of what the
3851 // token is so use the actual cursor, don't replace it with a macro expansion
3852 // cursor.
3853 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3854 return CXChildVisit_Recurse;
3855
3856 if (clang_isDeclaration(cursor.kind)) {
3857 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003858 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003859 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3860 if (MD->isImplicit())
3861 return CXChildVisit_Break;
3862
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003863 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003864 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3865 // Check that when we have multiple @class references in the same line,
3866 // that later ones do not override the previous ones.
3867 // If we have:
3868 // @class Foo, Bar;
3869 // source ranges for both start at '@', so 'Bar' will end up overriding
3870 // 'Foo' even though the cursor location was at 'Foo'.
3871 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3872 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003873 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003874 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3875 if (PrevID != ID &&
3876 !PrevID->isThisDeclarationADefinition() &&
3877 !ID->isThisDeclarationADefinition())
3878 return CXChildVisit_Break;
3879 }
3880
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003881 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003882 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3883 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3884 // Check that when we have multiple declarators in the same line,
3885 // that later ones do not override the previous ones.
3886 // If we have:
3887 // int Foo, Bar;
3888 // source ranges for both start at 'int', so 'Bar' will end up overriding
3889 // 'Foo' even though the cursor location was at 'Foo'.
3890 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3891 return CXChildVisit_Break;
3892 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3893
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003894 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003895 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3896 (void)PropImp;
3897 // Check that when we have multiple @synthesize in the same line,
3898 // that later ones do not override the previous ones.
3899 // If we have:
3900 // @synthesize Foo, Bar;
3901 // source ranges for both start at '@', so 'Bar' will end up overriding
3902 // 'Foo' even though the cursor location was at 'Foo'.
3903 if (Data->VisitedObjCPropertyImplDecl)
3904 return CXChildVisit_Break;
3905 Data->VisitedObjCPropertyImplDecl = true;
3906 }
3907 }
3908
3909 if (clang_isExpression(cursor.kind) &&
3910 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003911 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003912 // Avoid having the cursor of an expression replace the declaration cursor
3913 // when the expression source range overlaps the declaration range.
3914 // This can happen for C++ constructor expressions whose range generally
3915 // include the variable declaration, e.g.:
3916 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3917 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3918 D->getLocation() == Data->TokenBeginLoc)
3919 return CXChildVisit_Break;
3920 }
3921 }
3922
3923 // If our current best cursor is the construction of a temporary object,
3924 // don't replace that cursor with a type reference, because we want
3925 // clang_getCursor() to point at the constructor.
3926 if (clang_isExpression(BestCursor->kind) &&
3927 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3928 cursor.kind == CXCursor_TypeRef) {
3929 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3930 // as having the actual point on the type reference.
3931 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3932 return CXChildVisit_Recurse;
3933 }
3934
3935 *BestCursor = cursor;
3936 return CXChildVisit_Recurse;
3937}
3938
3939CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3940 if (!TU)
3941 return clang_getNullCursor();
3942
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003943 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003944 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3945
3946 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3947 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3948
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003949 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003950 CXFile SearchFile;
3951 unsigned SearchLine, SearchColumn;
3952 CXFile ResultFile;
3953 unsigned ResultLine, ResultColumn;
3954 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3955 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3956 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3957
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003958 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3959 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003960 &ResultColumn, 0);
3961 SearchFileName = clang_getFileName(SearchFile);
3962 ResultFileName = clang_getFileName(ResultFile);
3963 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3964 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003965 *Log << llvm::format("(%s:%d:%d) = %s",
3966 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3967 clang_getCString(KindSpelling))
3968 << llvm::format("(%s:%d:%d):%s%s",
3969 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3970 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003971 clang_disposeString(SearchFileName);
3972 clang_disposeString(ResultFileName);
3973 clang_disposeString(KindSpelling);
3974 clang_disposeString(USR);
3975
3976 CXCursor Definition = clang_getCursorDefinition(Result);
3977 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3978 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3979 CXString DefinitionKindSpelling
3980 = clang_getCursorKindSpelling(Definition.kind);
3981 CXFile DefinitionFile;
3982 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003983 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003984 &DefinitionLine, &DefinitionColumn, 0);
3985 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003986 *Log << llvm::format(" -> %s(%s:%d:%d)",
3987 clang_getCString(DefinitionKindSpelling),
3988 clang_getCString(DefinitionFileName),
3989 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003990 clang_disposeString(DefinitionFileName);
3991 clang_disposeString(DefinitionKindSpelling);
3992 }
3993 }
3994
3995 return Result;
3996}
3997
3998CXCursor clang_getNullCursor(void) {
3999 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4000}
4001
4002unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00004003 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4004 // can't set consistently. For example, when visiting a DeclStmt we will set
4005 // it but we don't set it on the result of clang_getCursorDefinition for
4006 // a reference of the same declaration.
4007 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4008 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4009 // to provide that kind of info.
4010 if (clang_isDeclaration(X.kind))
4011 X.data[1] = 0;
4012 if (clang_isDeclaration(Y.kind))
4013 Y.data[1] = 0;
4014
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004015 return X == Y;
4016}
4017
4018unsigned clang_hashCursor(CXCursor C) {
4019 unsigned Index = 0;
4020 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4021 Index = 1;
4022
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004023 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004024 std::make_pair(C.kind, C.data[Index]));
4025}
4026
4027unsigned clang_isInvalid(enum CXCursorKind K) {
4028 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4029}
4030
4031unsigned clang_isDeclaration(enum CXCursorKind K) {
4032 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4033 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4034}
4035
4036unsigned clang_isReference(enum CXCursorKind K) {
4037 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4038}
4039
4040unsigned clang_isExpression(enum CXCursorKind K) {
4041 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4042}
4043
4044unsigned clang_isStatement(enum CXCursorKind K) {
4045 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4046}
4047
4048unsigned clang_isAttribute(enum CXCursorKind K) {
4049 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4050}
4051
4052unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4053 return K == CXCursor_TranslationUnit;
4054}
4055
4056unsigned clang_isPreprocessing(enum CXCursorKind K) {
4057 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4058}
4059
4060unsigned clang_isUnexposed(enum CXCursorKind K) {
4061 switch (K) {
4062 case CXCursor_UnexposedDecl:
4063 case CXCursor_UnexposedExpr:
4064 case CXCursor_UnexposedStmt:
4065 case CXCursor_UnexposedAttr:
4066 return true;
4067 default:
4068 return false;
4069 }
4070}
4071
4072CXCursorKind clang_getCursorKind(CXCursor C) {
4073 return C.kind;
4074}
4075
4076CXSourceLocation clang_getCursorLocation(CXCursor C) {
4077 if (clang_isReference(C.kind)) {
4078 switch (C.kind) {
4079 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004080 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004081 = getCursorObjCSuperClassRef(C);
4082 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4083 }
4084
4085 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004086 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004087 = getCursorObjCProtocolRef(C);
4088 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4089 }
4090
4091 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004092 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004093 = getCursorObjCClassRef(C);
4094 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4095 }
4096
4097 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004098 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004099 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4100 }
4101
4102 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004103 std::pair<const TemplateDecl *, SourceLocation> P =
4104 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004105 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4106 }
4107
4108 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004109 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004110 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4111 }
4112
4113 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004114 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004115 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4116 }
4117
4118 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004119 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004120 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4121 }
4122
4123 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004124 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004125 if (!BaseSpec)
4126 return clang_getNullLocation();
4127
4128 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4129 return cxloc::translateSourceLocation(getCursorContext(C),
4130 TSInfo->getTypeLoc().getBeginLoc());
4131
4132 return cxloc::translateSourceLocation(getCursorContext(C),
4133 BaseSpec->getLocStart());
4134 }
4135
4136 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004137 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004138 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4139 }
4140
4141 case CXCursor_OverloadedDeclRef:
4142 return cxloc::translateSourceLocation(getCursorContext(C),
4143 getCursorOverloadedDeclRef(C).second);
4144
4145 default:
4146 // FIXME: Need a way to enumerate all non-reference cases.
4147 llvm_unreachable("Missed a reference kind");
4148 }
4149 }
4150
4151 if (clang_isExpression(C.kind))
4152 return cxloc::translateSourceLocation(getCursorContext(C),
4153 getLocationFromExpr(getCursorExpr(C)));
4154
4155 if (clang_isStatement(C.kind))
4156 return cxloc::translateSourceLocation(getCursorContext(C),
4157 getCursorStmt(C)->getLocStart());
4158
4159 if (C.kind == CXCursor_PreprocessingDirective) {
4160 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4161 return cxloc::translateSourceLocation(getCursorContext(C), L);
4162 }
4163
4164 if (C.kind == CXCursor_MacroExpansion) {
4165 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004166 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004167 return cxloc::translateSourceLocation(getCursorContext(C), L);
4168 }
4169
4170 if (C.kind == CXCursor_MacroDefinition) {
4171 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4172 return cxloc::translateSourceLocation(getCursorContext(C), L);
4173 }
4174
4175 if (C.kind == CXCursor_InclusionDirective) {
4176 SourceLocation L
4177 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4178 return cxloc::translateSourceLocation(getCursorContext(C), L);
4179 }
4180
Argyrios Kyrtzidis51337112013-09-25 00:14:38 +00004181 if (clang_isAttribute(C.kind)) {
4182 SourceLocation L
4183 = cxcursor::getCursorAttr(C)->getLocation();
4184 return cxloc::translateSourceLocation(getCursorContext(C), L);
4185 }
4186
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004187 if (!clang_isDeclaration(C.kind))
4188 return clang_getNullLocation();
4189
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004190 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004191 if (!D)
4192 return clang_getNullLocation();
4193
4194 SourceLocation Loc = D->getLocation();
4195 // FIXME: Multiple variables declared in a single declaration
4196 // currently lack the information needed to correctly determine their
4197 // ranges when accounting for the type-specifier. We use context
4198 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4199 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004200 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004201 if (!cxcursor::isFirstInDeclGroup(C))
4202 Loc = VD->getLocation();
4203 }
4204
4205 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004206 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004207 Loc = MD->getSelectorStartLoc();
4208
4209 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4210}
4211
4212} // end extern "C"
4213
4214CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4215 assert(TU);
4216
4217 // Guard against an invalid SourceLocation, or we may assert in one
4218 // of the following calls.
4219 if (SLoc.isInvalid())
4220 return clang_getNullCursor();
4221
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004222 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004223
4224 // Translate the given source location to make it point at the beginning of
4225 // the token under the cursor.
4226 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4227 CXXUnit->getASTContext().getLangOpts());
4228
4229 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4230 if (SLoc.isValid()) {
4231 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4232 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4233 /*VisitPreprocessorLast=*/true,
4234 /*VisitIncludedEntities=*/false,
4235 SourceLocation(SLoc));
4236 CursorVis.visitFileRegion();
4237 }
4238
4239 return Result;
4240}
4241
4242static SourceRange getRawCursorExtent(CXCursor C) {
4243 if (clang_isReference(C.kind)) {
4244 switch (C.kind) {
4245 case CXCursor_ObjCSuperClassRef:
4246 return getCursorObjCSuperClassRef(C).second;
4247
4248 case CXCursor_ObjCProtocolRef:
4249 return getCursorObjCProtocolRef(C).second;
4250
4251 case CXCursor_ObjCClassRef:
4252 return getCursorObjCClassRef(C).second;
4253
4254 case CXCursor_TypeRef:
4255 return getCursorTypeRef(C).second;
4256
4257 case CXCursor_TemplateRef:
4258 return getCursorTemplateRef(C).second;
4259
4260 case CXCursor_NamespaceRef:
4261 return getCursorNamespaceRef(C).second;
4262
4263 case CXCursor_MemberRef:
4264 return getCursorMemberRef(C).second;
4265
4266 case CXCursor_CXXBaseSpecifier:
4267 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4268
4269 case CXCursor_LabelRef:
4270 return getCursorLabelRef(C).second;
4271
4272 case CXCursor_OverloadedDeclRef:
4273 return getCursorOverloadedDeclRef(C).second;
4274
4275 case CXCursor_VariableRef:
4276 return getCursorVariableRef(C).second;
4277
4278 default:
4279 // FIXME: Need a way to enumerate all non-reference cases.
4280 llvm_unreachable("Missed a reference kind");
4281 }
4282 }
4283
4284 if (clang_isExpression(C.kind))
4285 return getCursorExpr(C)->getSourceRange();
4286
4287 if (clang_isStatement(C.kind))
4288 return getCursorStmt(C)->getSourceRange();
4289
4290 if (clang_isAttribute(C.kind))
4291 return getCursorAttr(C)->getRange();
4292
4293 if (C.kind == CXCursor_PreprocessingDirective)
4294 return cxcursor::getCursorPreprocessingDirective(C);
4295
4296 if (C.kind == CXCursor_MacroExpansion) {
4297 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004298 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004299 return TU->mapRangeFromPreamble(Range);
4300 }
4301
4302 if (C.kind == CXCursor_MacroDefinition) {
4303 ASTUnit *TU = getCursorASTUnit(C);
4304 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4305 return TU->mapRangeFromPreamble(Range);
4306 }
4307
4308 if (C.kind == CXCursor_InclusionDirective) {
4309 ASTUnit *TU = getCursorASTUnit(C);
4310 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4311 return TU->mapRangeFromPreamble(Range);
4312 }
4313
4314 if (C.kind == CXCursor_TranslationUnit) {
4315 ASTUnit *TU = getCursorASTUnit(C);
4316 FileID MainID = TU->getSourceManager().getMainFileID();
4317 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4318 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4319 return SourceRange(Start, End);
4320 }
4321
4322 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004323 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004324 if (!D)
4325 return SourceRange();
4326
4327 SourceRange R = D->getSourceRange();
4328 // FIXME: Multiple variables declared in a single declaration
4329 // currently lack the information needed to correctly determine their
4330 // ranges when accounting for the type-specifier. We use context
4331 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4332 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004333 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004334 if (!cxcursor::isFirstInDeclGroup(C))
4335 R.setBegin(VD->getLocation());
4336 }
4337 return R;
4338 }
4339 return SourceRange();
4340}
4341
4342/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4343/// the decl-specifier-seq for declarations.
4344static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4345 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004346 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004347 if (!D)
4348 return SourceRange();
4349
4350 SourceRange R = D->getSourceRange();
4351
4352 // Adjust the start of the location for declarations preceded by
4353 // declaration specifiers.
4354 SourceLocation StartLoc;
4355 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4356 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4357 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004358 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004359 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4360 StartLoc = TI->getTypeLoc().getLocStart();
4361 }
4362
4363 if (StartLoc.isValid() && R.getBegin().isValid() &&
4364 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4365 R.setBegin(StartLoc);
4366
4367 // FIXME: Multiple variables declared in a single declaration
4368 // currently lack the information needed to correctly determine their
4369 // ranges when accounting for the type-specifier. We use context
4370 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4371 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004372 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004373 if (!cxcursor::isFirstInDeclGroup(C))
4374 R.setBegin(VD->getLocation());
4375 }
4376
4377 return R;
4378 }
4379
4380 return getRawCursorExtent(C);
4381}
4382
4383extern "C" {
4384
4385CXSourceRange clang_getCursorExtent(CXCursor C) {
4386 SourceRange R = getRawCursorExtent(C);
4387 if (R.isInvalid())
4388 return clang_getNullRange();
4389
4390 return cxloc::translateSourceRange(getCursorContext(C), R);
4391}
4392
4393CXCursor clang_getCursorReferenced(CXCursor C) {
4394 if (clang_isInvalid(C.kind))
4395 return clang_getNullCursor();
4396
4397 CXTranslationUnit tu = getCursorTU(C);
4398 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004399 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004400 if (!D)
4401 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004402 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004403 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004404 if (const ObjCPropertyImplDecl *PropImpl =
4405 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004406 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4407 return MakeCXCursor(Property, tu);
4408
4409 return C;
4410 }
4411
4412 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004413 const Expr *E = getCursorExpr(C);
4414 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004415 if (D) {
4416 CXCursor declCursor = MakeCXCursor(D, tu);
4417 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4418 declCursor);
4419 return declCursor;
4420 }
4421
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004422 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004423 return MakeCursorOverloadedDeclRef(Ovl, tu);
4424
4425 return clang_getNullCursor();
4426 }
4427
4428 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004429 const Stmt *S = getCursorStmt(C);
4430 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004431 if (LabelDecl *label = Goto->getLabel())
4432 if (LabelStmt *labelS = label->getStmt())
4433 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4434
4435 return clang_getNullCursor();
4436 }
4437
4438 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004439 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004440 return MakeMacroDefinitionCursor(Def, tu);
4441 }
4442
4443 if (!clang_isReference(C.kind))
4444 return clang_getNullCursor();
4445
4446 switch (C.kind) {
4447 case CXCursor_ObjCSuperClassRef:
4448 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4449
4450 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004451 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4452 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004453 return MakeCXCursor(Def, tu);
4454
4455 return MakeCXCursor(Prot, tu);
4456 }
4457
4458 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004459 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4460 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004461 return MakeCXCursor(Def, tu);
4462
4463 return MakeCXCursor(Class, tu);
4464 }
4465
4466 case CXCursor_TypeRef:
4467 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4468
4469 case CXCursor_TemplateRef:
4470 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4471
4472 case CXCursor_NamespaceRef:
4473 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4474
4475 case CXCursor_MemberRef:
4476 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4477
4478 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004479 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004480 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4481 tu ));
4482 }
4483
4484 case CXCursor_LabelRef:
4485 // FIXME: We end up faking the "parent" declaration here because we
4486 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004487 return MakeCXCursor(getCursorLabelRef(C).first,
4488 cxtu::getASTUnit(tu)->getASTContext()
4489 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004490 tu);
4491
4492 case CXCursor_OverloadedDeclRef:
4493 return C;
4494
4495 case CXCursor_VariableRef:
4496 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4497
4498 default:
4499 // We would prefer to enumerate all non-reference cursor kinds here.
4500 llvm_unreachable("Unhandled reference cursor kind");
4501 }
4502}
4503
4504CXCursor clang_getCursorDefinition(CXCursor C) {
4505 if (clang_isInvalid(C.kind))
4506 return clang_getNullCursor();
4507
4508 CXTranslationUnit TU = getCursorTU(C);
4509
4510 bool WasReference = false;
4511 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4512 C = clang_getCursorReferenced(C);
4513 WasReference = true;
4514 }
4515
4516 if (C.kind == CXCursor_MacroExpansion)
4517 return clang_getCursorReferenced(C);
4518
4519 if (!clang_isDeclaration(C.kind))
4520 return clang_getNullCursor();
4521
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004522 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004523 if (!D)
4524 return clang_getNullCursor();
4525
4526 switch (D->getKind()) {
4527 // Declaration kinds that don't really separate the notions of
4528 // declaration and definition.
4529 case Decl::Namespace:
4530 case Decl::Typedef:
4531 case Decl::TypeAlias:
4532 case Decl::TypeAliasTemplate:
4533 case Decl::TemplateTypeParm:
4534 case Decl::EnumConstant:
4535 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004536 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004537 case Decl::IndirectField:
4538 case Decl::ObjCIvar:
4539 case Decl::ObjCAtDefsField:
4540 case Decl::ImplicitParam:
4541 case Decl::ParmVar:
4542 case Decl::NonTypeTemplateParm:
4543 case Decl::TemplateTemplateParm:
4544 case Decl::ObjCCategoryImpl:
4545 case Decl::ObjCImplementation:
4546 case Decl::AccessSpec:
4547 case Decl::LinkageSpec:
4548 case Decl::ObjCPropertyImpl:
4549 case Decl::FileScopeAsm:
4550 case Decl::StaticAssert:
4551 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004552 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004553 case Decl::Label: // FIXME: Is this right??
4554 case Decl::ClassScopeFunctionSpecialization:
4555 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004556 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004557 return C;
4558
4559 // Declaration kinds that don't make any sense here, but are
4560 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004561 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004562 case Decl::TranslationUnit:
4563 break;
4564
4565 // Declaration kinds for which the definition is not resolvable.
4566 case Decl::UnresolvedUsingTypename:
4567 case Decl::UnresolvedUsingValue:
4568 break;
4569
4570 case Decl::UsingDirective:
4571 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4572 TU);
4573
4574 case Decl::NamespaceAlias:
4575 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4576
4577 case Decl::Enum:
4578 case Decl::Record:
4579 case Decl::CXXRecord:
4580 case Decl::ClassTemplateSpecialization:
4581 case Decl::ClassTemplatePartialSpecialization:
4582 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4583 return MakeCXCursor(Def, TU);
4584 return clang_getNullCursor();
4585
4586 case Decl::Function:
4587 case Decl::CXXMethod:
4588 case Decl::CXXConstructor:
4589 case Decl::CXXDestructor:
4590 case Decl::CXXConversion: {
4591 const FunctionDecl *Def = 0;
4592 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004593 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004594 return clang_getNullCursor();
4595 }
4596
Larisse Voufoef4579c2013-08-06 01:03:05 +00004597 case Decl::Var:
4598 case Decl::VarTemplateSpecialization:
4599 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004600 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004601 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004602 return MakeCXCursor(Def, TU);
4603 return clang_getNullCursor();
4604 }
4605
4606 case Decl::FunctionTemplate: {
4607 const FunctionDecl *Def = 0;
4608 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4609 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4610 return clang_getNullCursor();
4611 }
4612
4613 case Decl::ClassTemplate: {
4614 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4615 ->getDefinition())
4616 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4617 TU);
4618 return clang_getNullCursor();
4619 }
4620
Larisse Voufoef4579c2013-08-06 01:03:05 +00004621 case Decl::VarTemplate: {
4622 if (VarDecl *Def =
4623 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4624 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4625 return clang_getNullCursor();
4626 }
4627
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004628 case Decl::Using:
4629 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4630 D->getLocation(), TU);
4631
4632 case Decl::UsingShadow:
4633 return clang_getCursorDefinition(
4634 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4635 TU));
4636
4637 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004638 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004639 if (Method->isThisDeclarationADefinition())
4640 return C;
4641
4642 // Dig out the method definition in the associated
4643 // @implementation, if we have it.
4644 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004645 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004646 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4647 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4648 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4649 Method->isInstanceMethod()))
4650 if (Def->isThisDeclarationADefinition())
4651 return MakeCXCursor(Def, TU);
4652
4653 return clang_getNullCursor();
4654 }
4655
4656 case Decl::ObjCCategory:
4657 if (ObjCCategoryImplDecl *Impl
4658 = cast<ObjCCategoryDecl>(D)->getImplementation())
4659 return MakeCXCursor(Impl, TU);
4660 return clang_getNullCursor();
4661
4662 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004663 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004664 return MakeCXCursor(Def, TU);
4665 return clang_getNullCursor();
4666
4667 case Decl::ObjCInterface: {
4668 // There are two notions of a "definition" for an Objective-C
4669 // class: the interface and its implementation. When we resolved a
4670 // reference to an Objective-C class, produce the @interface as
4671 // the definition; when we were provided with the interface,
4672 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004673 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004674 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004675 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004676 return MakeCXCursor(Def, TU);
4677 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4678 return MakeCXCursor(Impl, TU);
4679 return clang_getNullCursor();
4680 }
4681
4682 case Decl::ObjCProperty:
4683 // FIXME: We don't really know where to find the
4684 // ObjCPropertyImplDecls that implement this property.
4685 return clang_getNullCursor();
4686
4687 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004688 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004689 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004690 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004691 return MakeCXCursor(Def, TU);
4692
4693 return clang_getNullCursor();
4694
4695 case Decl::Friend:
4696 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4697 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4698 return clang_getNullCursor();
4699
4700 case Decl::FriendTemplate:
4701 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4702 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4703 return clang_getNullCursor();
4704 }
4705
4706 return clang_getNullCursor();
4707}
4708
4709unsigned clang_isCursorDefinition(CXCursor C) {
4710 if (!clang_isDeclaration(C.kind))
4711 return 0;
4712
4713 return clang_getCursorDefinition(C) == C;
4714}
4715
4716CXCursor clang_getCanonicalCursor(CXCursor C) {
4717 if (!clang_isDeclaration(C.kind))
4718 return C;
4719
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004720 if (const Decl *D = getCursorDecl(C)) {
4721 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004722 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4723 return MakeCXCursor(CatD, getCursorTU(C));
4724
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004725 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4726 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004727 return MakeCXCursor(IFD, getCursorTU(C));
4728
4729 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4730 }
4731
4732 return C;
4733}
4734
4735int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4736 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4737}
4738
4739unsigned clang_getNumOverloadedDecls(CXCursor C) {
4740 if (C.kind != CXCursor_OverloadedDeclRef)
4741 return 0;
4742
4743 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004744 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004745 return E->getNumDecls();
4746
4747 if (OverloadedTemplateStorage *S
4748 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4749 return S->size();
4750
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004751 const Decl *D = Storage.get<const Decl *>();
4752 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004753 return Using->shadow_size();
4754
4755 return 0;
4756}
4757
4758CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4759 if (cursor.kind != CXCursor_OverloadedDeclRef)
4760 return clang_getNullCursor();
4761
4762 if (index >= clang_getNumOverloadedDecls(cursor))
4763 return clang_getNullCursor();
4764
4765 CXTranslationUnit TU = getCursorTU(cursor);
4766 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004767 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004768 return MakeCXCursor(E->decls_begin()[index], TU);
4769
4770 if (OverloadedTemplateStorage *S
4771 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4772 return MakeCXCursor(S->begin()[index], TU);
4773
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004774 const Decl *D = Storage.get<const Decl *>();
4775 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004776 // FIXME: This is, unfortunately, linear time.
4777 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4778 std::advance(Pos, index);
4779 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4780 }
4781
4782 return clang_getNullCursor();
4783}
4784
4785void clang_getDefinitionSpellingAndExtent(CXCursor C,
4786 const char **startBuf,
4787 const char **endBuf,
4788 unsigned *startLine,
4789 unsigned *startColumn,
4790 unsigned *endLine,
4791 unsigned *endColumn) {
4792 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004793 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004794 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4795
4796 SourceManager &SM = FD->getASTContext().getSourceManager();
4797 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4798 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4799 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4800 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4801 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4802 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4803}
4804
4805
4806CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4807 unsigned PieceIndex) {
4808 RefNamePieces Pieces;
4809
4810 switch (C.kind) {
4811 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004812 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004813 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4814 E->getQualifierLoc().getSourceRange());
4815 break;
4816
4817 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004818 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004819 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4820 E->getQualifierLoc().getSourceRange(),
4821 E->getOptionalExplicitTemplateArgs());
4822 break;
4823
4824 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004825 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004826 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004827 const Expr *Callee = OCE->getCallee();
4828 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004829 Callee = ICE->getSubExpr();
4830
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004831 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004832 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4833 DRE->getQualifierLoc().getSourceRange());
4834 }
4835 break;
4836
4837 default:
4838 break;
4839 }
4840
4841 if (Pieces.empty()) {
4842 if (PieceIndex == 0)
4843 return clang_getCursorExtent(C);
4844 } else if (PieceIndex < Pieces.size()) {
4845 SourceRange R = Pieces[PieceIndex];
4846 if (R.isValid())
4847 return cxloc::translateSourceRange(getCursorContext(C), R);
4848 }
4849
4850 return clang_getNullRange();
4851}
4852
4853void clang_enableStackTraces(void) {
4854 llvm::sys::PrintStackTraceOnErrorSignal();
4855}
4856
4857void clang_executeOnThread(void (*fn)(void*), void *user_data,
4858 unsigned stack_size) {
4859 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4860}
4861
4862} // end: extern "C"
4863
4864//===----------------------------------------------------------------------===//
4865// Token-based Operations.
4866//===----------------------------------------------------------------------===//
4867
4868/* CXToken layout:
4869 * int_data[0]: a CXTokenKind
4870 * int_data[1]: starting token location
4871 * int_data[2]: token length
4872 * int_data[3]: reserved
4873 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4874 * otherwise unused.
4875 */
4876extern "C" {
4877
4878CXTokenKind clang_getTokenKind(CXToken CXTok) {
4879 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4880}
4881
4882CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4883 switch (clang_getTokenKind(CXTok)) {
4884 case CXToken_Identifier:
4885 case CXToken_Keyword:
4886 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004887 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004888 ->getNameStart());
4889
4890 case CXToken_Literal: {
4891 // We have stashed the starting pointer in the ptr_data field. Use it.
4892 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004893 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004894 }
4895
4896 case CXToken_Punctuation:
4897 case CXToken_Comment:
4898 break;
4899 }
4900
4901 // We have to find the starting buffer pointer the hard way, by
4902 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004903 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004904 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004905 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004906
4907 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4908 std::pair<FileID, unsigned> LocInfo
4909 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4910 bool Invalid = false;
4911 StringRef Buffer
4912 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4913 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004914 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004915
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004916 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004917}
4918
4919CXSourceLocation clang_getTokenLocation(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_getNullLocation();
4923
4924 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4925 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4926}
4927
4928CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004929 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004930 if (!CXXUnit)
4931 return clang_getNullRange();
4932
4933 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4934 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4935}
4936
4937static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4938 SmallVectorImpl<CXToken> &CXTokens) {
4939 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4940 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004941 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004942 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004943 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004944
4945 // Cannot tokenize across files.
4946 if (BeginLocInfo.first != EndLocInfo.first)
4947 return;
4948
4949 // Create a lexer
4950 bool Invalid = false;
4951 StringRef Buffer
4952 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4953 if (Invalid)
4954 return;
4955
4956 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4957 CXXUnit->getASTContext().getLangOpts(),
4958 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4959 Lex.SetCommentRetentionState(true);
4960
4961 // Lex tokens until we hit the end of the range.
4962 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4963 Token Tok;
4964 bool previousWasAt = false;
4965 do {
4966 // Lex the next token
4967 Lex.LexFromRawLexer(Tok);
4968 if (Tok.is(tok::eof))
4969 break;
4970
4971 // Initialize the CXToken.
4972 CXToken CXTok;
4973
4974 // - Common fields
4975 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4976 CXTok.int_data[2] = Tok.getLength();
4977 CXTok.int_data[3] = 0;
4978
4979 // - Kind-specific fields
4980 if (Tok.isLiteral()) {
4981 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004982 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004983 } else if (Tok.is(tok::raw_identifier)) {
4984 // Lookup the identifier to determine whether we have a keyword.
4985 IdentifierInfo *II
4986 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4987
4988 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4989 CXTok.int_data[0] = CXToken_Keyword;
4990 }
4991 else {
4992 CXTok.int_data[0] = Tok.is(tok::identifier)
4993 ? CXToken_Identifier
4994 : CXToken_Keyword;
4995 }
4996 CXTok.ptr_data = II;
4997 } else if (Tok.is(tok::comment)) {
4998 CXTok.int_data[0] = CXToken_Comment;
4999 CXTok.ptr_data = 0;
5000 } else {
5001 CXTok.int_data[0] = CXToken_Punctuation;
5002 CXTok.ptr_data = 0;
5003 }
5004 CXTokens.push_back(CXTok);
5005 previousWasAt = Tok.is(tok::at);
5006 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5007}
5008
5009void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5010 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005011 LOG_FUNC_SECTION {
5012 *Log << TU << ' ' << Range;
5013 }
5014
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005015 if (Tokens)
5016 *Tokens = 0;
5017 if (NumTokens)
5018 *NumTokens = 0;
5019
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005020 if (!TU)
5021 return;
5022
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005023 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005024 if (!CXXUnit || !Tokens || !NumTokens)
5025 return;
5026
5027 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5028
5029 SourceRange R = cxloc::translateCXSourceRange(Range);
5030 if (R.isInvalid())
5031 return;
5032
5033 SmallVector<CXToken, 32> CXTokens;
5034 getTokens(CXXUnit, R, CXTokens);
5035
5036 if (CXTokens.empty())
5037 return;
5038
5039 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5040 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5041 *NumTokens = CXTokens.size();
5042}
5043
5044void clang_disposeTokens(CXTranslationUnit TU,
5045 CXToken *Tokens, unsigned NumTokens) {
5046 free(Tokens);
5047}
5048
5049} // end: extern "C"
5050
5051//===----------------------------------------------------------------------===//
5052// Token annotation APIs.
5053//===----------------------------------------------------------------------===//
5054
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005055static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5056 CXCursor parent,
5057 CXClientData client_data);
5058static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5059 CXClientData client_data);
5060
5061namespace {
5062class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005063 CXToken *Tokens;
5064 CXCursor *Cursors;
5065 unsigned NumTokens;
5066 unsigned TokIdx;
5067 unsigned PreprocessingTokIdx;
5068 CursorVisitor AnnotateVis;
5069 SourceManager &SrcMgr;
5070 bool HasContextSensitiveKeywords;
5071
5072 struct PostChildrenInfo {
5073 CXCursor Cursor;
5074 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005075 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005076 unsigned BeforeChildrenTokenIdx;
5077 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005078 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005079
5080 bool MoreTokens() const { return TokIdx < NumTokens; }
5081 unsigned NextToken() const { return TokIdx; }
5082 void AdvanceToken() { ++TokIdx; }
5083 SourceLocation GetTokenLoc(unsigned tokI) {
5084 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5085 }
5086 bool isFunctionMacroToken(unsigned tokI) const {
5087 return Tokens[tokI].int_data[3] != 0;
5088 }
5089 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5090 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5091 }
5092
5093 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005094 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005095 SourceRange);
5096
5097public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005098 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005099 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005100 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005101 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005102 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005103 AnnotateTokensVisitor, this,
5104 /*VisitPreprocessorLast=*/true,
5105 /*VisitIncludedEntities=*/false,
5106 RegionOfInterest,
5107 /*VisitDeclsOnly=*/false,
5108 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005109 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005110 HasContextSensitiveKeywords(false) { }
5111
5112 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5113 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5114 bool postVisitChildren(CXCursor cursor);
5115 void AnnotateTokens();
5116
5117 /// \brief Determine whether the annotator saw any cursors that have
5118 /// context-sensitive keywords.
5119 bool hasContextSensitiveKeywords() const {
5120 return HasContextSensitiveKeywords;
5121 }
5122
5123 ~AnnotateTokensWorker() {
5124 assert(PostChildrenInfos.empty());
5125 }
5126};
5127}
5128
5129void AnnotateTokensWorker::AnnotateTokens() {
5130 // Walk the AST within the region of interest, annotating tokens
5131 // along the way.
5132 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005133}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005134
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005135static inline void updateCursorAnnotation(CXCursor &Cursor,
5136 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005137 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005138 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005139 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005140}
5141
5142/// \brief It annotates and advances tokens with a cursor until the comparison
5143//// between the cursor location and the source range is the same as
5144/// \arg compResult.
5145///
5146/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5147/// Pass RangeOverlap to annotate tokens inside a range.
5148void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5149 RangeComparisonResult compResult,
5150 SourceRange range) {
5151 while (MoreTokens()) {
5152 const unsigned I = NextToken();
5153 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005154 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5155 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005156
5157 SourceLocation TokLoc = GetTokenLoc(I);
5158 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005159 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005160 AdvanceToken();
5161 continue;
5162 }
5163 break;
5164 }
5165}
5166
5167/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005168/// \returns true if it advanced beyond all macro tokens, false otherwise.
5169bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005170 CXCursor updateC,
5171 RangeComparisonResult compResult,
5172 SourceRange range) {
5173 assert(MoreTokens());
5174 assert(isFunctionMacroToken(NextToken()) &&
5175 "Should be called only for macro arg tokens");
5176
5177 // This works differently than annotateAndAdvanceTokens; because expanded
5178 // macro arguments can have arbitrary translation-unit source order, we do not
5179 // advance the token index one by one until a token fails the range test.
5180 // We only advance once past all of the macro arg tokens if all of them
5181 // pass the range test. If one of them fails we keep the token index pointing
5182 // at the start of the macro arg tokens so that the failing token will be
5183 // annotated by a subsequent annotation try.
5184
5185 bool atLeastOneCompFail = false;
5186
5187 unsigned I = NextToken();
5188 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5189 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5190 if (TokLoc.isFileID())
5191 continue; // not macro arg token, it's parens or comma.
5192 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5193 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5194 Cursors[I] = updateC;
5195 } else
5196 atLeastOneCompFail = true;
5197 }
5198
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005199 if (atLeastOneCompFail)
5200 return false;
5201
5202 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5203 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005204}
5205
5206enum CXChildVisitResult
5207AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005208 SourceRange cursorRange = getRawCursorExtent(cursor);
5209 if (cursorRange.isInvalid())
5210 return CXChildVisit_Recurse;
5211
5212 if (!HasContextSensitiveKeywords) {
5213 // Objective-C properties can have context-sensitive keywords.
5214 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005215 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005216 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5217 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5218 }
5219 // Objective-C methods can have context-sensitive keywords.
5220 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5221 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005222 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005223 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5224 if (Method->getObjCDeclQualifier())
5225 HasContextSensitiveKeywords = true;
5226 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005227 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5228 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005229 P != PEnd; ++P) {
5230 if ((*P)->getObjCDeclQualifier()) {
5231 HasContextSensitiveKeywords = true;
5232 break;
5233 }
5234 }
5235 }
5236 }
5237 }
5238 // C++ methods can have context-sensitive keywords.
5239 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005240 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005241 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5242 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5243 HasContextSensitiveKeywords = true;
5244 }
5245 }
5246 // C++ classes can have context-sensitive keywords.
5247 else if (cursor.kind == CXCursor_StructDecl ||
5248 cursor.kind == CXCursor_ClassDecl ||
5249 cursor.kind == CXCursor_ClassTemplate ||
5250 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005251 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005252 if (D->hasAttr<FinalAttr>())
5253 HasContextSensitiveKeywords = true;
5254 }
5255 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005256
5257 // Don't override a property annotation with its getter/setter method.
5258 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5259 parent.kind == CXCursor_ObjCPropertyDecl)
5260 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005261
5262 if (clang_isPreprocessing(cursor.kind)) {
5263 // Items in the preprocessing record are kept separate from items in
5264 // declarations, so we keep a separate token index.
5265 unsigned SavedTokIdx = TokIdx;
5266 TokIdx = PreprocessingTokIdx;
5267
5268 // Skip tokens up until we catch up to the beginning of the preprocessing
5269 // entry.
5270 while (MoreTokens()) {
5271 const unsigned I = NextToken();
5272 SourceLocation TokLoc = GetTokenLoc(I);
5273 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5274 case RangeBefore:
5275 AdvanceToken();
5276 continue;
5277 case RangeAfter:
5278 case RangeOverlap:
5279 break;
5280 }
5281 break;
5282 }
5283
5284 // Look at all of the tokens within this range.
5285 while (MoreTokens()) {
5286 const unsigned I = NextToken();
5287 SourceLocation TokLoc = GetTokenLoc(I);
5288 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5289 case RangeBefore:
5290 llvm_unreachable("Infeasible");
5291 case RangeAfter:
5292 break;
5293 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005294 // For macro expansions, just note where the beginning of the macro
5295 // expansion occurs.
5296 if (cursor.kind == CXCursor_MacroExpansion) {
5297 if (TokLoc == cursorRange.getBegin())
5298 Cursors[I] = cursor;
5299 AdvanceToken();
5300 break;
5301 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005302 // We may have already annotated macro names inside macro definitions.
5303 if (Cursors[I].kind != CXCursor_MacroExpansion)
5304 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005305 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005306 continue;
5307 }
5308 break;
5309 }
5310
5311 // Save the preprocessing token index; restore the non-preprocessing
5312 // token index.
5313 PreprocessingTokIdx = TokIdx;
5314 TokIdx = SavedTokIdx;
5315 return CXChildVisit_Recurse;
5316 }
5317
5318 if (cursorRange.isInvalid())
5319 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005320
5321 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005322 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005323 const enum CXCursorKind K = clang_getCursorKind(parent);
5324 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005325 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5326 // Attributes are annotated out-of-order, skip tokens until we reach it.
5327 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005328 ? clang_getNullCursor() : parent;
5329
5330 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5331
5332 // Avoid having the cursor of an expression "overwrite" the annotation of the
5333 // variable declaration that it belongs to.
5334 // This can happen for C++ constructor expressions whose range generally
5335 // include the variable declaration, e.g.:
5336 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5337 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005338 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005339 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005340 const unsigned I = NextToken();
5341 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5342 E->getLocStart() == D->getLocation() &&
5343 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005344 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005345 AdvanceToken();
5346 }
5347 }
5348 }
5349
5350 // Before recursing into the children keep some state that we are going
5351 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5352 // extra work after the child nodes are visited.
5353 // Note that we don't call VisitChildren here to avoid traversing statements
5354 // code-recursively which can blow the stack.
5355
5356 PostChildrenInfo Info;
5357 Info.Cursor = cursor;
5358 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005359 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005360 Info.BeforeChildrenTokenIdx = NextToken();
5361 PostChildrenInfos.push_back(Info);
5362
5363 return CXChildVisit_Recurse;
5364}
5365
5366bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5367 if (PostChildrenInfos.empty())
5368 return false;
5369 const PostChildrenInfo &Info = PostChildrenInfos.back();
5370 if (!clang_equalCursors(Info.Cursor, cursor))
5371 return false;
5372
5373 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5374 const unsigned AfterChildren = NextToken();
5375 SourceRange cursorRange = Info.CursorRange;
5376
5377 // Scan the tokens that are at the end of the cursor, but are not captured
5378 // but the child cursors.
5379 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5380
5381 // Scan the tokens that are at the beginning of the cursor, but are not
5382 // capture by the child cursors.
5383 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5384 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5385 break;
5386
5387 Cursors[I] = cursor;
5388 }
5389
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005390 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5391 // encountered the attribute cursor.
5392 if (clang_isAttribute(cursor.kind))
5393 TokIdx = Info.BeforeReachingCursorIdx;
5394
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005395 PostChildrenInfos.pop_back();
5396 return false;
5397}
5398
5399static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5400 CXCursor parent,
5401 CXClientData client_data) {
5402 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5403}
5404
5405static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5406 CXClientData client_data) {
5407 return static_cast<AnnotateTokensWorker*>(client_data)->
5408 postVisitChildren(cursor);
5409}
5410
5411namespace {
5412
5413/// \brief Uses the macro expansions in the preprocessing record to find
5414/// and mark tokens that are macro arguments. This info is used by the
5415/// AnnotateTokensWorker.
5416class MarkMacroArgTokensVisitor {
5417 SourceManager &SM;
5418 CXToken *Tokens;
5419 unsigned NumTokens;
5420 unsigned CurIdx;
5421
5422public:
5423 MarkMacroArgTokensVisitor(SourceManager &SM,
5424 CXToken *tokens, unsigned numTokens)
5425 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5426
5427 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5428 if (cursor.kind != CXCursor_MacroExpansion)
5429 return CXChildVisit_Continue;
5430
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005431 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005432 if (macroRange.getBegin() == macroRange.getEnd())
5433 return CXChildVisit_Continue; // it's not a function macro.
5434
5435 for (; CurIdx < NumTokens; ++CurIdx) {
5436 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5437 macroRange.getBegin()))
5438 break;
5439 }
5440
5441 if (CurIdx == NumTokens)
5442 return CXChildVisit_Break;
5443
5444 for (; CurIdx < NumTokens; ++CurIdx) {
5445 SourceLocation tokLoc = getTokenLoc(CurIdx);
5446 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5447 break;
5448
5449 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5450 }
5451
5452 if (CurIdx == NumTokens)
5453 return CXChildVisit_Break;
5454
5455 return CXChildVisit_Continue;
5456 }
5457
5458private:
5459 SourceLocation getTokenLoc(unsigned tokI) {
5460 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5461 }
5462
5463 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5464 // The third field is reserved and currently not used. Use it here
5465 // to mark macro arg expanded tokens with their expanded locations.
5466 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5467 }
5468};
5469
5470} // end anonymous namespace
5471
5472static CXChildVisitResult
5473MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5474 CXClientData client_data) {
5475 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5476 parent);
5477}
5478
5479namespace {
5480 struct clang_annotateTokens_Data {
5481 CXTranslationUnit TU;
5482 ASTUnit *CXXUnit;
5483 CXToken *Tokens;
5484 unsigned NumTokens;
5485 CXCursor *Cursors;
5486 };
5487}
5488
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005489/// \brief Used by \c annotatePreprocessorTokens.
5490/// \returns true if lexing was finished, false otherwise.
5491static bool lexNext(Lexer &Lex, Token &Tok,
5492 unsigned &NextIdx, unsigned NumTokens) {
5493 if (NextIdx >= NumTokens)
5494 return true;
5495
5496 ++NextIdx;
5497 Lex.LexFromRawLexer(Tok);
5498 if (Tok.is(tok::eof))
5499 return true;
5500
5501 return false;
5502}
5503
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005504static void annotatePreprocessorTokens(CXTranslationUnit TU,
5505 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005506 CXCursor *Cursors,
5507 CXToken *Tokens,
5508 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005509 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005510
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005511 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005512 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5513 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005514 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005515 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005516 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005517
5518 if (BeginLocInfo.first != EndLocInfo.first)
5519 return;
5520
5521 StringRef Buffer;
5522 bool Invalid = false;
5523 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5524 if (Buffer.empty() || Invalid)
5525 return;
5526
5527 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5528 CXXUnit->getASTContext().getLangOpts(),
5529 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5530 Buffer.end());
5531 Lex.SetCommentRetentionState(true);
5532
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005533 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005534 // Lex tokens in raw mode until we hit the end of the range, to avoid
5535 // entering #includes or expanding macros.
5536 while (true) {
5537 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005538 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5539 break;
5540 unsigned TokIdx = NextIdx-1;
5541 assert(Tok.getLocation() ==
5542 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005543
5544 reprocess:
5545 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005546 // We have found a preprocessing directive. Annotate the tokens
5547 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005548 //
5549 // FIXME: Some simple tests here could identify macro definitions and
5550 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005551
5552 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005553 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5554 break;
5555
5556 MacroInfo *MI = 0;
5557 if (Tok.is(tok::raw_identifier) &&
5558 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5559 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5560 break;
5561
5562 if (Tok.is(tok::raw_identifier)) {
5563 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5564 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5565 SourceLocation MappedTokLoc =
5566 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5567 MI = getMacroInfo(II, MappedTokLoc, TU);
5568 }
5569 }
5570
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005571 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005572 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005573 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5574 finished = true;
5575 break;
5576 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005577 // If we are in a macro definition, check if the token was ever a
5578 // macro name and annotate it if that's the case.
5579 if (MI) {
5580 SourceLocation SaveLoc = Tok.getLocation();
5581 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5582 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5583 Tok.setLocation(SaveLoc);
5584 if (MacroDef)
5585 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5586 Tok.getLocation(), TU);
5587 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005588 } while (!Tok.isAtStartOfLine());
5589
5590 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5591 assert(TokIdx <= LastIdx);
5592 SourceLocation EndLoc =
5593 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5594 CXCursor Cursor =
5595 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5596
5597 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005598 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005599
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005600 if (finished)
5601 break;
5602 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005603 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005604 }
5605}
5606
5607// This gets run a separate thread to avoid stack blowout.
5608static void clang_annotateTokensImpl(void *UserData) {
5609 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5610 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5611 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5612 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5613 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5614
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005615 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005616 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5617 setThreadBackgroundPriority();
5618
5619 // Determine the region of interest, which contains all of the tokens.
5620 SourceRange RegionOfInterest;
5621 RegionOfInterest.setBegin(
5622 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5623 RegionOfInterest.setEnd(
5624 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5625 Tokens[NumTokens-1])));
5626
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005627 // Relex the tokens within the source range to look for preprocessing
5628 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005629 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005630
5631 // If begin location points inside a macro argument, set it to the expansion
5632 // location so we can have the full context when annotating semantically.
5633 {
5634 SourceManager &SM = CXXUnit->getSourceManager();
5635 SourceLocation Loc =
5636 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5637 if (Loc.isMacroID())
5638 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5639 }
5640
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005641 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5642 // Search and mark tokens that are macro argument expansions.
5643 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5644 Tokens, NumTokens);
5645 CursorVisitor MacroArgMarker(TU,
5646 MarkMacroArgTokensVisitorDelegate, &Visitor,
5647 /*VisitPreprocessorLast=*/true,
5648 /*VisitIncludedEntities=*/false,
5649 RegionOfInterest);
5650 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5651 }
5652
5653 // Annotate all of the source locations in the region of interest that map to
5654 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005655 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005656
5657 // FIXME: We use a ridiculous stack size here because the data-recursion
5658 // algorithm uses a large stack frame than the non-data recursive version,
5659 // and AnnotationTokensWorker currently transforms the data-recursion
5660 // algorithm back into a traditional recursion by explicitly calling
5661 // VisitChildren(). We will need to remove this explicit recursive call.
5662 W.AnnotateTokens();
5663
5664 // If we ran into any entities that involve context-sensitive keywords,
5665 // take another pass through the tokens to mark them as such.
5666 if (W.hasContextSensitiveKeywords()) {
5667 for (unsigned I = 0; I != NumTokens; ++I) {
5668 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5669 continue;
5670
5671 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5672 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005673 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005674 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5675 if (Property->getPropertyAttributesAsWritten() != 0 &&
5676 llvm::StringSwitch<bool>(II->getName())
5677 .Case("readonly", true)
5678 .Case("assign", true)
5679 .Case("unsafe_unretained", true)
5680 .Case("readwrite", true)
5681 .Case("retain", true)
5682 .Case("copy", true)
5683 .Case("nonatomic", true)
5684 .Case("atomic", true)
5685 .Case("getter", true)
5686 .Case("setter", true)
5687 .Case("strong", true)
5688 .Case("weak", true)
5689 .Default(false))
5690 Tokens[I].int_data[0] = CXToken_Keyword;
5691 }
5692 continue;
5693 }
5694
5695 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5696 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5697 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5698 if (llvm::StringSwitch<bool>(II->getName())
5699 .Case("in", true)
5700 .Case("out", true)
5701 .Case("inout", true)
5702 .Case("oneway", true)
5703 .Case("bycopy", true)
5704 .Case("byref", true)
5705 .Default(false))
5706 Tokens[I].int_data[0] = CXToken_Keyword;
5707 continue;
5708 }
5709
5710 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5711 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5712 Tokens[I].int_data[0] = CXToken_Keyword;
5713 continue;
5714 }
5715 }
5716 }
5717}
5718
5719extern "C" {
5720
5721void clang_annotateTokens(CXTranslationUnit TU,
5722 CXToken *Tokens, unsigned NumTokens,
5723 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005724 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005725 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005726 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005727 }
5728
5729 LOG_FUNC_SECTION {
5730 *Log << TU << ' ';
5731 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5732 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5733 *Log << clang_getRange(bloc, eloc);
5734 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005735
5736 // Any token we don't specifically annotate will have a NULL cursor.
5737 CXCursor C = clang_getNullCursor();
5738 for (unsigned I = 0; I != NumTokens; ++I)
5739 Cursors[I] = C;
5740
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005741 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005742 if (!CXXUnit)
5743 return;
5744
5745 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5746
5747 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5748 llvm::CrashRecoveryContext CRC;
5749 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5750 GetSafetyThreadStackSize() * 2)) {
5751 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5752 }
5753}
5754
5755} // end: extern "C"
5756
5757//===----------------------------------------------------------------------===//
5758// Operations for querying linkage of a cursor.
5759//===----------------------------------------------------------------------===//
5760
5761extern "C" {
5762CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5763 if (!clang_isDeclaration(cursor.kind))
5764 return CXLinkage_Invalid;
5765
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005766 const Decl *D = cxcursor::getCursorDecl(cursor);
5767 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005768 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005769 case NoLinkage:
5770 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005771 case InternalLinkage: return CXLinkage_Internal;
5772 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5773 case ExternalLinkage: return CXLinkage_External;
5774 };
5775
5776 return CXLinkage_Invalid;
5777}
5778} // end: extern "C"
5779
5780//===----------------------------------------------------------------------===//
5781// Operations for querying language of a cursor.
5782//===----------------------------------------------------------------------===//
5783
5784static CXLanguageKind getDeclLanguage(const Decl *D) {
5785 if (!D)
5786 return CXLanguage_C;
5787
5788 switch (D->getKind()) {
5789 default:
5790 break;
5791 case Decl::ImplicitParam:
5792 case Decl::ObjCAtDefsField:
5793 case Decl::ObjCCategory:
5794 case Decl::ObjCCategoryImpl:
5795 case Decl::ObjCCompatibleAlias:
5796 case Decl::ObjCImplementation:
5797 case Decl::ObjCInterface:
5798 case Decl::ObjCIvar:
5799 case Decl::ObjCMethod:
5800 case Decl::ObjCProperty:
5801 case Decl::ObjCPropertyImpl:
5802 case Decl::ObjCProtocol:
5803 return CXLanguage_ObjC;
5804 case Decl::CXXConstructor:
5805 case Decl::CXXConversion:
5806 case Decl::CXXDestructor:
5807 case Decl::CXXMethod:
5808 case Decl::CXXRecord:
5809 case Decl::ClassTemplate:
5810 case Decl::ClassTemplatePartialSpecialization:
5811 case Decl::ClassTemplateSpecialization:
5812 case Decl::Friend:
5813 case Decl::FriendTemplate:
5814 case Decl::FunctionTemplate:
5815 case Decl::LinkageSpec:
5816 case Decl::Namespace:
5817 case Decl::NamespaceAlias:
5818 case Decl::NonTypeTemplateParm:
5819 case Decl::StaticAssert:
5820 case Decl::TemplateTemplateParm:
5821 case Decl::TemplateTypeParm:
5822 case Decl::UnresolvedUsingTypename:
5823 case Decl::UnresolvedUsingValue:
5824 case Decl::Using:
5825 case Decl::UsingDirective:
5826 case Decl::UsingShadow:
5827 return CXLanguage_CPlusPlus;
5828 }
5829
5830 return CXLanguage_C;
5831}
5832
5833extern "C" {
5834
5835enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5836 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005837 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005838 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5839 return CXAvailability_Available;
5840
5841 switch (D->getAvailability()) {
5842 case AR_Available:
5843 case AR_NotYetIntroduced:
5844 return CXAvailability_Available;
5845
5846 case AR_Deprecated:
5847 return CXAvailability_Deprecated;
5848
5849 case AR_Unavailable:
5850 return CXAvailability_NotAvailable;
5851 }
5852 }
5853
5854 return CXAvailability_Available;
5855}
5856
5857static CXVersion convertVersion(VersionTuple In) {
5858 CXVersion Out = { -1, -1, -1 };
5859 if (In.empty())
5860 return Out;
5861
5862 Out.Major = In.getMajor();
5863
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005864 Optional<unsigned> Minor = In.getMinor();
5865 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005866 Out.Minor = *Minor;
5867 else
5868 return Out;
5869
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005870 Optional<unsigned> Subminor = In.getSubminor();
5871 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005872 Out.Subminor = *Subminor;
5873
5874 return Out;
5875}
5876
5877int clang_getCursorPlatformAvailability(CXCursor cursor,
5878 int *always_deprecated,
5879 CXString *deprecated_message,
5880 int *always_unavailable,
5881 CXString *unavailable_message,
5882 CXPlatformAvailability *availability,
5883 int availability_size) {
5884 if (always_deprecated)
5885 *always_deprecated = 0;
5886 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005887 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005888 if (always_unavailable)
5889 *always_unavailable = 0;
5890 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005891 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005892
5893 if (!clang_isDeclaration(cursor.kind))
5894 return 0;
5895
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005896 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005897 if (!D)
5898 return 0;
5899
5900 int N = 0;
5901 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5902 ++A) {
5903 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5904 if (always_deprecated)
5905 *always_deprecated = 1;
5906 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005907 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005908 continue;
5909 }
5910
5911 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5912 if (always_unavailable)
5913 *always_unavailable = 1;
5914 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005915 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005916 }
5917 continue;
5918 }
5919
5920 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5921 if (N < availability_size) {
5922 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005923 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005924 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5925 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5926 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5927 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005928 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005929 }
5930 ++N;
5931 }
5932 }
5933
5934 return N;
5935}
5936
5937void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5938 clang_disposeString(availability->Platform);
5939 clang_disposeString(availability->Message);
5940}
5941
5942CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5943 if (clang_isDeclaration(cursor.kind))
5944 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5945
5946 return CXLanguage_Invalid;
5947}
5948
5949 /// \brief If the given cursor is the "templated" declaration
5950 /// descibing a class or function template, return the class or
5951 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005952static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005953 if (!D)
5954 return 0;
5955
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005956 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005957 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5958 return FunTmpl;
5959
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005960 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005961 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5962 return ClassTmpl;
5963
5964 return D;
5965}
5966
5967CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5968 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005969 if (const Decl *D = getCursorDecl(cursor)) {
5970 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005971 if (!DC)
5972 return clang_getNullCursor();
5973
5974 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5975 getCursorTU(cursor));
5976 }
5977 }
5978
5979 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005980 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005981 return MakeCXCursor(D, getCursorTU(cursor));
5982 }
5983
5984 return clang_getNullCursor();
5985}
5986
5987CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5988 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005989 if (const Decl *D = getCursorDecl(cursor)) {
5990 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005991 if (!DC)
5992 return clang_getNullCursor();
5993
5994 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5995 getCursorTU(cursor));
5996 }
5997 }
5998
5999 // FIXME: Note that we can't easily compute the lexical context of a
6000 // statement or expression, so we return nothing.
6001 return clang_getNullCursor();
6002}
6003
6004CXFile clang_getIncludedFile(CXCursor cursor) {
6005 if (cursor.kind != CXCursor_InclusionDirective)
6006 return 0;
6007
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006008 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00006009 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006010}
6011
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00006012unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6013 if (C.kind != CXCursor_ObjCPropertyDecl)
6014 return CXObjCPropertyAttr_noattr;
6015
6016 unsigned Result = CXObjCPropertyAttr_noattr;
6017 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6018 ObjCPropertyDecl::PropertyAttributeKind Attr =
6019 PD->getPropertyAttributesAsWritten();
6020
6021#define SET_CXOBJCPROP_ATTR(A) \
6022 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6023 Result |= CXObjCPropertyAttr_##A
6024 SET_CXOBJCPROP_ATTR(readonly);
6025 SET_CXOBJCPROP_ATTR(getter);
6026 SET_CXOBJCPROP_ATTR(assign);
6027 SET_CXOBJCPROP_ATTR(readwrite);
6028 SET_CXOBJCPROP_ATTR(retain);
6029 SET_CXOBJCPROP_ATTR(copy);
6030 SET_CXOBJCPROP_ATTR(nonatomic);
6031 SET_CXOBJCPROP_ATTR(setter);
6032 SET_CXOBJCPROP_ATTR(atomic);
6033 SET_CXOBJCPROP_ATTR(weak);
6034 SET_CXOBJCPROP_ATTR(strong);
6035 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6036#undef SET_CXOBJCPROP_ATTR
6037
6038 return Result;
6039}
6040
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006041unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6042 if (!clang_isDeclaration(C.kind))
6043 return CXObjCDeclQualifier_None;
6044
6045 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6046 const Decl *D = getCursorDecl(C);
6047 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6048 QT = MD->getObjCDeclQualifier();
6049 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6050 QT = PD->getObjCDeclQualifier();
6051 if (QT == Decl::OBJC_TQ_None)
6052 return CXObjCDeclQualifier_None;
6053
6054 unsigned Result = CXObjCDeclQualifier_None;
6055 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6056 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6057 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6058 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6059 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6060 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6061
6062 return Result;
6063}
6064
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006065unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6066 if (!clang_isDeclaration(C.kind))
6067 return 0;
6068
6069 const Decl *D = getCursorDecl(C);
6070 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6071 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6072 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6073 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6074
6075 return 0;
6076}
6077
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006078unsigned clang_Cursor_isVariadic(CXCursor C) {
6079 if (!clang_isDeclaration(C.kind))
6080 return 0;
6081
6082 const Decl *D = getCursorDecl(C);
6083 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6084 return FD->isVariadic();
6085 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6086 return MD->isVariadic();
6087
6088 return 0;
6089}
6090
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006091CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6092 if (!clang_isDeclaration(C.kind))
6093 return clang_getNullRange();
6094
6095 const Decl *D = getCursorDecl(C);
6096 ASTContext &Context = getCursorContext(C);
6097 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6098 if (!RC)
6099 return clang_getNullRange();
6100
6101 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6102}
6103
6104CXString clang_Cursor_getRawCommentText(CXCursor C) {
6105 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006106 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006107
6108 const Decl *D = getCursorDecl(C);
6109 ASTContext &Context = getCursorContext(C);
6110 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6111 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6112 StringRef();
6113
6114 // Don't duplicate the string because RawText points directly into source
6115 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006116 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006117}
6118
6119CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6120 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006121 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006122
6123 const Decl *D = getCursorDecl(C);
6124 const ASTContext &Context = getCursorContext(C);
6125 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6126
6127 if (RC) {
6128 StringRef BriefText = RC->getBriefText(Context);
6129
6130 // Don't duplicate the string because RawComment ensures that this memory
6131 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006132 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006133 }
6134
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006135 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006136}
6137
6138CXComment clang_Cursor_getParsedComment(CXCursor C) {
6139 if (!clang_isDeclaration(C.kind))
6140 return cxcomment::createCXComment(NULL, NULL);
6141
6142 const Decl *D = getCursorDecl(C);
6143 const ASTContext &Context = getCursorContext(C);
6144 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6145
6146 return cxcomment::createCXComment(FC, getCursorTU(C));
6147}
6148
6149CXModule clang_Cursor_getModule(CXCursor C) {
6150 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006151 if (const ImportDecl *ImportD =
6152 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006153 return ImportD->getImportedModule();
6154 }
6155
6156 return 0;
6157}
6158
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006159CXFile clang_Module_getASTFile(CXModule CXMod) {
6160 if (!CXMod)
6161 return 0;
6162 Module *Mod = static_cast<Module*>(CXMod);
6163 return const_cast<FileEntry *>(Mod->getASTFile());
6164}
6165
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006166CXModule clang_Module_getParent(CXModule CXMod) {
6167 if (!CXMod)
6168 return 0;
6169 Module *Mod = static_cast<Module*>(CXMod);
6170 return Mod->Parent;
6171}
6172
6173CXString clang_Module_getName(CXModule CXMod) {
6174 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006175 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006176 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006177 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006178}
6179
6180CXString clang_Module_getFullName(CXModule CXMod) {
6181 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006182 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006183 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006184 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006185}
6186
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006187unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6188 CXModule CXMod) {
6189 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006190 return 0;
6191 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006192 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6193 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6194 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006195}
6196
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006197CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6198 CXModule CXMod, unsigned Index) {
6199 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006200 return 0;
6201 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006202 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006203
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006204 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6205 if (Index < TopHeaders.size())
6206 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006207
6208 return 0;
6209}
6210
6211} // end: extern "C"
6212
6213//===----------------------------------------------------------------------===//
6214// C++ AST instrospection.
6215//===----------------------------------------------------------------------===//
6216
6217extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006218unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6219 if (!clang_isDeclaration(C.kind))
6220 return 0;
6221
6222 const CXXMethodDecl *Method = 0;
6223 const Decl *D = cxcursor::getCursorDecl(C);
6224 if (const FunctionTemplateDecl *FunTmpl =
6225 dyn_cast_or_null<FunctionTemplateDecl>(D))
6226 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6227 else
6228 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6229 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6230}
6231
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006232unsigned clang_CXXMethod_isStatic(CXCursor C) {
6233 if (!clang_isDeclaration(C.kind))
6234 return 0;
6235
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006236 const CXXMethodDecl *Method = 0;
6237 const Decl *D = cxcursor::getCursorDecl(C);
6238 if (const FunctionTemplateDecl *FunTmpl =
6239 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006240 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6241 else
6242 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6243 return (Method && Method->isStatic()) ? 1 : 0;
6244}
6245
6246unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6247 if (!clang_isDeclaration(C.kind))
6248 return 0;
6249
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006250 const CXXMethodDecl *Method = 0;
6251 const Decl *D = cxcursor::getCursorDecl(C);
6252 if (const FunctionTemplateDecl *FunTmpl =
6253 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006254 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6255 else
6256 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6257 return (Method && Method->isVirtual()) ? 1 : 0;
6258}
6259} // end: extern "C"
6260
6261//===----------------------------------------------------------------------===//
6262// Attribute introspection.
6263//===----------------------------------------------------------------------===//
6264
6265extern "C" {
6266CXType clang_getIBOutletCollectionType(CXCursor C) {
6267 if (C.kind != CXCursor_IBOutletCollectionAttr)
6268 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6269
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006270 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006271 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6272
6273 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6274}
6275} // end: extern "C"
6276
6277//===----------------------------------------------------------------------===//
6278// Inspecting memory usage.
6279//===----------------------------------------------------------------------===//
6280
6281typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6282
6283static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6284 enum CXTUResourceUsageKind k,
6285 unsigned long amount) {
6286 CXTUResourceUsageEntry entry = { k, amount };
6287 entries.push_back(entry);
6288}
6289
6290extern "C" {
6291
6292const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6293 const char *str = "";
6294 switch (kind) {
6295 case CXTUResourceUsage_AST:
6296 str = "ASTContext: expressions, declarations, and types";
6297 break;
6298 case CXTUResourceUsage_Identifiers:
6299 str = "ASTContext: identifiers";
6300 break;
6301 case CXTUResourceUsage_Selectors:
6302 str = "ASTContext: selectors";
6303 break;
6304 case CXTUResourceUsage_GlobalCompletionResults:
6305 str = "Code completion: cached global results";
6306 break;
6307 case CXTUResourceUsage_SourceManagerContentCache:
6308 str = "SourceManager: content cache allocator";
6309 break;
6310 case CXTUResourceUsage_AST_SideTables:
6311 str = "ASTContext: side tables";
6312 break;
6313 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6314 str = "SourceManager: malloc'ed memory buffers";
6315 break;
6316 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6317 str = "SourceManager: mmap'ed memory buffers";
6318 break;
6319 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6320 str = "ExternalASTSource: malloc'ed memory buffers";
6321 break;
6322 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6323 str = "ExternalASTSource: mmap'ed memory buffers";
6324 break;
6325 case CXTUResourceUsage_Preprocessor:
6326 str = "Preprocessor: malloc'ed memory";
6327 break;
6328 case CXTUResourceUsage_PreprocessingRecord:
6329 str = "Preprocessor: PreprocessingRecord";
6330 break;
6331 case CXTUResourceUsage_SourceManager_DataStructures:
6332 str = "SourceManager: data structures and tables";
6333 break;
6334 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6335 str = "Preprocessor: header search tables";
6336 break;
6337 }
6338 return str;
6339}
6340
6341CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6342 if (!TU) {
6343 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6344 return usage;
6345 }
6346
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006347 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006348 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6349 ASTContext &astContext = astUnit->getASTContext();
6350
6351 // How much memory is used by AST nodes and types?
6352 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6353 (unsigned long) astContext.getASTAllocatedMemory());
6354
6355 // How much memory is used by identifiers?
6356 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6357 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6358
6359 // How much memory is used for selectors?
6360 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6361 (unsigned long) astContext.Selectors.getTotalMemory());
6362
6363 // How much memory is used by ASTContext's side tables?
6364 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6365 (unsigned long) astContext.getSideTableAllocatedMemory());
6366
6367 // How much memory is used for caching global code completion results?
6368 unsigned long completionBytes = 0;
6369 if (GlobalCodeCompletionAllocator *completionAllocator =
6370 astUnit->getCachedCompletionAllocator().getPtr()) {
6371 completionBytes = completionAllocator->getTotalMemory();
6372 }
6373 createCXTUResourceUsageEntry(*entries,
6374 CXTUResourceUsage_GlobalCompletionResults,
6375 completionBytes);
6376
6377 // How much memory is being used by SourceManager's content cache?
6378 createCXTUResourceUsageEntry(*entries,
6379 CXTUResourceUsage_SourceManagerContentCache,
6380 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6381
6382 // How much memory is being used by the MemoryBuffer's in SourceManager?
6383 const SourceManager::MemoryBufferSizes &srcBufs =
6384 astUnit->getSourceManager().getMemoryBufferSizes();
6385
6386 createCXTUResourceUsageEntry(*entries,
6387 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6388 (unsigned long) srcBufs.malloc_bytes);
6389 createCXTUResourceUsageEntry(*entries,
6390 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6391 (unsigned long) srcBufs.mmap_bytes);
6392 createCXTUResourceUsageEntry(*entries,
6393 CXTUResourceUsage_SourceManager_DataStructures,
6394 (unsigned long) astContext.getSourceManager()
6395 .getDataStructureSizes());
6396
6397 // How much memory is being used by the ExternalASTSource?
6398 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6399 const ExternalASTSource::MemoryBufferSizes &sizes =
6400 esrc->getMemoryBufferSizes();
6401
6402 createCXTUResourceUsageEntry(*entries,
6403 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6404 (unsigned long) sizes.malloc_bytes);
6405 createCXTUResourceUsageEntry(*entries,
6406 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6407 (unsigned long) sizes.mmap_bytes);
6408 }
6409
6410 // How much memory is being used by the Preprocessor?
6411 Preprocessor &pp = astUnit->getPreprocessor();
6412 createCXTUResourceUsageEntry(*entries,
6413 CXTUResourceUsage_Preprocessor,
6414 pp.getTotalMemory());
6415
6416 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6417 createCXTUResourceUsageEntry(*entries,
6418 CXTUResourceUsage_PreprocessingRecord,
6419 pRec->getTotalMemory());
6420 }
6421
6422 createCXTUResourceUsageEntry(*entries,
6423 CXTUResourceUsage_Preprocessor_HeaderSearch,
6424 pp.getHeaderSearchInfo().getTotalMemory());
6425
6426 CXTUResourceUsage usage = { (void*) entries.get(),
6427 (unsigned) entries->size(),
6428 entries->size() ? &(*entries)[0] : 0 };
6429 entries.take();
6430 return usage;
6431}
6432
6433void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6434 if (usage.data)
6435 delete (MemUsageEntries*) usage.data;
6436}
6437
6438} // end extern "C"
6439
6440void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6441 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6442 for (unsigned I = 0; I != Usage.numEntries; ++I)
6443 fprintf(stderr, " %s: %lu\n",
6444 clang_getTUResourceUsageName(Usage.entries[I].kind),
6445 Usage.entries[I].amount);
6446
6447 clang_disposeCXTUResourceUsage(Usage);
6448}
6449
6450//===----------------------------------------------------------------------===//
6451// Misc. utility functions.
6452//===----------------------------------------------------------------------===//
6453
6454/// Default to using an 8 MB stack size on "safety" threads.
6455static unsigned SafetyStackThreadSize = 8 << 20;
6456
6457namespace clang {
6458
6459bool RunSafely(llvm::CrashRecoveryContext &CRC,
6460 void (*Fn)(void*), void *UserData,
6461 unsigned Size) {
6462 if (!Size)
6463 Size = GetSafetyThreadStackSize();
6464 if (Size)
6465 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6466 return CRC.RunSafely(Fn, UserData);
6467}
6468
6469unsigned GetSafetyThreadStackSize() {
6470 return SafetyStackThreadSize;
6471}
6472
6473void SetSafetyThreadStackSize(unsigned Value) {
6474 SafetyStackThreadSize = Value;
6475}
6476
6477}
6478
6479void clang::setThreadBackgroundPriority() {
6480 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6481 return;
6482
6483 // FIXME: Move to llvm/Support and make it cross-platform.
6484#ifdef __APPLE__
6485 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6486#endif
6487}
6488
6489void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6490 if (!Unit)
6491 return;
6492
6493 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6494 DEnd = Unit->stored_diag_end();
6495 D != DEnd; ++D) {
6496 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6497 CXString Msg = clang_formatDiagnostic(&Diag,
6498 clang_defaultDiagnosticDisplayOptions());
6499 fprintf(stderr, "%s\n", clang_getCString(Msg));
6500 clang_disposeString(Msg);
6501 }
6502#ifdef LLVM_ON_WIN32
6503 // On Windows, force a flush, since there may be multiple copies of
6504 // stderr and stdout in the file system, all with different buffers
6505 // but writing to the same device.
6506 fflush(stderr);
6507#endif
6508}
6509
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006510MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6511 SourceLocation MacroDefLoc,
6512 CXTranslationUnit TU){
6513 if (MacroDefLoc.isInvalid() || !TU)
6514 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006515 if (!II.hadMacroDefinition())
6516 return 0;
6517
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006518 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006519 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006520 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006521 if (MD) {
6522 for (MacroDirective::DefInfo
6523 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6524 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6525 return Def.getMacroInfo();
6526 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006527 }
6528
6529 return 0;
6530}
6531
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006532const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6533 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006534 if (!MacroDef || !TU)
6535 return 0;
6536 const IdentifierInfo *II = MacroDef->getName();
6537 if (!II)
6538 return 0;
6539
6540 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6541}
6542
6543MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6544 const Token &Tok,
6545 CXTranslationUnit TU) {
6546 if (!MI || !TU)
6547 return 0;
6548 if (Tok.isNot(tok::raw_identifier))
6549 return 0;
6550
6551 if (MI->getNumTokens() == 0)
6552 return 0;
6553 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6554 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006555 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006556
6557 // Check that the token is inside the definition and not its argument list.
6558 SourceManager &SM = Unit->getSourceManager();
6559 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6560 return 0;
6561 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6562 return 0;
6563
6564 Preprocessor &PP = Unit->getPreprocessor();
6565 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6566 if (!PPRec)
6567 return 0;
6568
6569 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6570 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6571 if (!II.hadMacroDefinition())
6572 return 0;
6573
6574 // Check that the identifier is not one of the macro arguments.
6575 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6576 return 0;
6577
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006578 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6579 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006580 return 0;
6581
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006582 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006583}
6584
6585MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6586 SourceLocation Loc,
6587 CXTranslationUnit TU) {
6588 if (Loc.isInvalid() || !MI || !TU)
6589 return 0;
6590
6591 if (MI->getNumTokens() == 0)
6592 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006593 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006594 Preprocessor &PP = Unit->getPreprocessor();
6595 if (!PP.getPreprocessingRecord())
6596 return 0;
6597 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6598 Token Tok;
6599 if (PP.getRawToken(Loc, Tok))
6600 return 0;
6601
6602 return checkForMacroInMacroDefinition(MI, Tok, TU);
6603}
6604
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006605extern "C" {
6606
6607CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006608 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006609}
6610
6611} // end: extern "C"
6612
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006613Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6614 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006615 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006616 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006617 if (Unit->isMainFileAST())
6618 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006619 return *this;
6620 }
6621 }
6622
6623 LogOS << "<NULL TU>";
6624 return *this;
6625}
6626
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006627Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6628 *this << FE->getName();
6629 return *this;
6630}
6631
6632Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6633 CXString cursorName = clang_getCursorDisplayName(cursor);
6634 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6635 clang_disposeString(cursorName);
6636 return *this;
6637}
6638
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006639Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6640 CXFile File;
6641 unsigned Line, Column;
6642 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6643 CXString FileName = clang_getFileName(File);
6644 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6645 clang_disposeString(FileName);
6646 return *this;
6647}
6648
6649Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6650 CXSourceLocation BLoc = clang_getRangeStart(range);
6651 CXSourceLocation ELoc = clang_getRangeEnd(range);
6652
6653 CXFile BFile;
6654 unsigned BLine, BColumn;
6655 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6656
6657 CXFile EFile;
6658 unsigned ELine, EColumn;
6659 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6660
6661 CXString BFileName = clang_getFileName(BFile);
6662 if (BFile == EFile) {
6663 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6664 BLine, BColumn, ELine, EColumn);
6665 } else {
6666 CXString EFileName = clang_getFileName(EFile);
6667 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6668 BLine, BColumn)
6669 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6670 ELine, EColumn);
6671 clang_disposeString(EFileName);
6672 }
6673 clang_disposeString(BFileName);
6674 return *this;
6675}
6676
6677Logger &cxindex::Logger::operator<<(CXString Str) {
6678 *this << clang_getCString(Str);
6679 return *this;
6680}
6681
6682Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6683 LogOS << Fmt;
6684 return *this;
6685}
6686
6687cxindex::Logger::~Logger() {
6688 LogOS.flush();
6689
6690 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6691
6692 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6693
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006694 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006695 OS << "[libclang:" << Name << ':';
6696
6697 // FIXME: Portability.
6698#if HAVE_PTHREAD_H && __APPLE__
6699 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6700 OS << tid << ':';
6701#endif
6702
6703 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6704 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6705 OS << Msg.str() << '\n';
6706
6707 if (Trace) {
6708 llvm::sys::PrintStackTrace(stderr);
6709 OS << "--------------------------------------------------\n";
6710 }
6711}