blob: d1b02c4b65455c6c6f7493c09f6cec9e7a6bfe68 [file] [log] [blame]
Guy Benyei11169dd2012-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 Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-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"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
28#include "clang/Basic/Version.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
31#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000032#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000033#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 Carruth4b417452013-01-19 08:09:44 +000040#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/Support/Compiler.h"
42#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/MemoryBuffer.h"
45#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/Program.h"
47#include "llvm/Support/SaveAndRestore.h"
48#include "llvm/Support/Signals.h"
49#include "llvm/Support/Threading.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000052
53#if HAVE_PTHREAD_H
54#include <pthread.h>
55#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000056
57using namespace clang;
58using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000059using namespace clang::cxtu;
60using namespace clang::cxindex;
61
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000062CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
63 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000064 return 0;
65 CXTranslationUnit D = new CXTranslationUnitImpl();
66 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000067 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000068 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000069 D->Diagnostics = 0;
70 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000071 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000072 return D;
73}
74
75cxtu::CXTUOwner::~CXTUOwner() {
76 if (TU)
77 clang_disposeTranslationUnit(TU);
78}
79
80/// \brief Compare two source ranges to determine their relative position in
81/// the translation unit.
82static RangeComparisonResult RangeCompare(SourceManager &SM,
83 SourceRange R1,
84 SourceRange R2) {
85 assert(R1.isValid() && "First range is invalid?");
86 assert(R2.isValid() && "Second range is invalid?");
87 if (R1.getEnd() != R2.getBegin() &&
88 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
89 return RangeBefore;
90 if (R2.getEnd() != R1.getBegin() &&
91 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
92 return RangeAfter;
93 return RangeOverlap;
94}
95
96/// \brief Determine if a source location falls within, before, or after a
97/// a given source range.
98static RangeComparisonResult LocationCompare(SourceManager &SM,
99 SourceLocation L, SourceRange R) {
100 assert(R.isValid() && "First range is invalid?");
101 assert(L.isValid() && "Second range is invalid?");
102 if (L == R.getBegin() || L == R.getEnd())
103 return RangeOverlap;
104 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
105 return RangeBefore;
106 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
107 return RangeAfter;
108 return RangeOverlap;
109}
110
111/// \brief Translate a Clang source range into a CIndex source range.
112///
113/// Clang internally represents ranges where the end location points to the
114/// start of the token at the end. However, for external clients it is more
115/// useful to have a CXSourceRange be a proper half-open interval. This routine
116/// does the appropriate translation.
117CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
118 const LangOptions &LangOpts,
119 const CharSourceRange &R) {
120 // We want the last character in this location, so we will adjust the
121 // location accordingly.
122 SourceLocation EndLoc = R.getEnd();
123 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
124 EndLoc = SM.getExpansionRange(EndLoc).second;
125 if (R.isTokenRange() && !EndLoc.isInvalid()) {
126 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
127 SM, LangOpts);
128 EndLoc = EndLoc.getLocWithOffset(Length);
129 }
130
Bill Wendlingeade3622013-01-23 08:25:41 +0000131 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000132 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000133 R.getBegin().getRawEncoding(),
134 EndLoc.getRawEncoding()
135 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000136 return Result;
137}
138
139//===----------------------------------------------------------------------===//
140// Cursor visitor.
141//===----------------------------------------------------------------------===//
142
143static SourceRange getRawCursorExtent(CXCursor C);
144static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
145
146
147RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
148 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
149}
150
151/// \brief Visit the given cursor and, if requested by the visitor,
152/// its children.
153///
154/// \param Cursor the cursor to visit.
155///
156/// \param CheckedRegionOfInterest if true, then the caller already checked
157/// that this cursor is within the region of interest.
158///
159/// \returns true if the visitation should be aborted, false if it
160/// should continue.
161bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
162 if (clang_isInvalid(Cursor.kind))
163 return false;
164
165 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000166 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000167 if (!D) {
168 assert(0 && "Invalid declaration cursor");
169 return true; // abort.
170 }
171
172 // Ignore implicit declarations, unless it's an objc method because
173 // currently we should report implicit methods for properties when indexing.
174 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
175 return false;
176 }
177
178 // If we have a range of interest, and this cursor doesn't intersect with it,
179 // we're done.
180 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
181 SourceRange Range = getRawCursorExtent(Cursor);
182 if (Range.isInvalid() || CompareRegionOfInterest(Range))
183 return false;
184 }
185
186 switch (Visitor(Cursor, Parent, ClientData)) {
187 case CXChildVisit_Break:
188 return true;
189
190 case CXChildVisit_Continue:
191 return false;
192
193 case CXChildVisit_Recurse: {
194 bool ret = VisitChildren(Cursor);
195 if (PostChildrenVisitor)
196 if (PostChildrenVisitor(Cursor, ClientData))
197 return true;
198 return ret;
199 }
200 }
201
202 llvm_unreachable("Invalid CXChildVisitResult!");
203}
204
205static bool visitPreprocessedEntitiesInRange(SourceRange R,
206 PreprocessingRecord &PPRec,
207 CursorVisitor &Visitor) {
208 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
209 FileID FID;
210
211 if (!Visitor.shouldVisitIncludedEntities()) {
212 // If the begin/end of the range lie in the same FileID, do the optimization
213 // where we skip preprocessed entities that do not come from the same FileID.
214 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
215 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
216 FID = FileID();
217 }
218
219 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
220 Entities = PPRec.getPreprocessedEntitiesInRange(R);
221 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
222 PPRec, FID);
223}
224
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000225bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000226 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000227 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000228
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000229 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000230 SourceManager &SM = Unit->getSourceManager();
231
232 std::pair<FileID, unsigned>
233 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
234 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
235
236 if (End.first != Begin.first) {
237 // If the end does not reside in the same file, try to recover by
238 // picking the end of the file of begin location.
239 End.first = Begin.first;
240 End.second = SM.getFileIDSize(Begin.first);
241 }
242
243 assert(Begin.first == End.first);
244 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000246
247 FileID File = Begin.first;
248 unsigned Offset = Begin.second;
249 unsigned Length = End.second - Begin.second;
250
251 if (!VisitDeclsOnly && !VisitPreprocessorLast)
252 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000253 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000254
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000255 if (visitDeclsFromFileRegion(File, Offset, Length))
256 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000257
258 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000259 return visitPreprocessedEntitiesInRegion();
260
261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262}
263
264static bool isInLexicalContext(Decl *D, DeclContext *DC) {
265 if (!DC)
266 return false;
267
268 for (DeclContext *DeclDC = D->getLexicalDeclContext();
269 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
270 if (DeclDC == DC)
271 return true;
272 }
273 return false;
274}
275
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000277 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000278 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000279 SourceManager &SM = Unit->getSourceManager();
280 SourceRange Range = RegionOfInterest;
281
282 SmallVector<Decl *, 16> Decls;
283 Unit->findFileRegionDecls(File, Offset, Length, Decls);
284
285 // If we didn't find any file level decls for the file, try looking at the
286 // file that it was included from.
287 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
288 bool Invalid = false;
289 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
290 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000291 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000292
293 SourceLocation Outer;
294 if (SLEntry.isFile())
295 Outer = SLEntry.getFile().getIncludeLoc();
296 else
297 Outer = SLEntry.getExpansion().getExpansionLocStart();
298 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000300
301 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
302 Length = 0;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304 }
305
306 assert(!Decls.empty());
307
308 bool VisitedAtLeastOnce = false;
309 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000310 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
311 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000312 Decl *D = *DIt;
313 if (D->getSourceRange().isInvalid())
314 continue;
315
316 if (isInLexicalContext(D, CurDC))
317 continue;
318
319 CurDC = dyn_cast<DeclContext>(D);
320
321 if (TagDecl *TD = dyn_cast<TagDecl>(D))
322 if (!TD->isFreeStanding())
323 continue;
324
325 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
326 if (CompRes == RangeBefore)
327 continue;
328 if (CompRes == RangeAfter)
329 break;
330
331 assert(CompRes == RangeOverlap);
332 VisitedAtLeastOnce = true;
333
334 if (isa<ObjCContainerDecl>(D)) {
335 FileDI_current = &DIt;
336 FileDE_current = DE;
337 } else {
338 FileDI_current = 0;
339 }
340
341 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000342 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000343 }
344
345 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000346 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000347
348 // No Decls overlapped with the range. Move up the lexical context until there
349 // is a context that contains the range or we reach the translation unit
350 // level.
351 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
352 : (*(DIt-1))->getLexicalDeclContext();
353
354 while (DC && !DC->isTranslationUnit()) {
355 Decl *D = cast<Decl>(DC);
356 SourceRange CurDeclRange = D->getSourceRange();
357 if (CurDeclRange.isInvalid())
358 break;
359
360 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 DC = D->getLexicalDeclContext();
366 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367
368 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000369}
370
371bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
372 if (!AU->getPreprocessor().getPreprocessingRecord())
373 return false;
374
375 PreprocessingRecord &PPRec
376 = *AU->getPreprocessor().getPreprocessingRecord();
377 SourceManager &SM = AU->getSourceManager();
378
379 if (RegionOfInterest.isValid()) {
380 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
381 SourceLocation B = MappedRange.getBegin();
382 SourceLocation E = MappedRange.getEnd();
383
384 if (AU->isInPreambleFileID(B)) {
385 if (SM.isLoadedSourceLocation(E))
386 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
387 PPRec, *this);
388
389 // Beginning of range lies in the preamble but it also extends beyond
390 // it into the main file. Split the range into 2 parts, one covering
391 // the preamble and another covering the main file. This allows subsequent
392 // calls to visitPreprocessedEntitiesInRange to accept a source range that
393 // lies in the same FileID, allowing it to skip preprocessed entities that
394 // do not come from the same FileID.
395 bool breaked =
396 visitPreprocessedEntitiesInRange(
397 SourceRange(B, AU->getEndOfPreambleFileID()),
398 PPRec, *this);
399 if (breaked) return true;
400 return visitPreprocessedEntitiesInRange(
401 SourceRange(AU->getStartOfMainFileID(), E),
402 PPRec, *this);
403 }
404
405 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
406 }
407
408 bool OnlyLocalDecls
409 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
410
411 if (OnlyLocalDecls)
412 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
413 PPRec);
414
415 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
416}
417
418template<typename InputIterator>
419bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
420 InputIterator Last,
421 PreprocessingRecord &PPRec,
422 FileID FID) {
423 for (; First != Last; ++First) {
424 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
425 continue;
426
427 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000428 if (!PPE)
429 continue;
430
Guy Benyei11169dd2012-12-18 14:30:41 +0000431 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
432 if (Visit(MakeMacroExpansionCursor(ME, TU)))
433 return true;
434
435 continue;
436 }
437
438 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
439 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
440 return true;
441
442 continue;
443 }
444
445 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
446 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
447 return true;
448
449 continue;
450 }
451 }
452
453 return false;
454}
455
456/// \brief Visit the children of the given cursor.
457///
458/// \returns true if the visitation should be aborted, false if it
459/// should continue.
460bool CursorVisitor::VisitChildren(CXCursor Cursor) {
461 if (clang_isReference(Cursor.kind) &&
462 Cursor.kind != CXCursor_CXXBaseSpecifier) {
463 // By definition, references have no children.
464 return false;
465 }
466
467 // Set the Parent field to Cursor, then back to its old value once we're
468 // done.
469 SetParentRAII SetParent(Parent, StmtParent, Cursor);
470
471 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000472 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000473 if (!D)
474 return false;
475
476 return VisitAttributes(D) || Visit(D);
477 }
478
479 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000480 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000481 return Visit(S);
482
483 return false;
484 }
485
486 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000487 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 return Visit(E);
489
490 return false;
491 }
492
493 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000494 CXTranslationUnit TU = getCursorTU(Cursor);
495 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000496
497 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
498 for (unsigned I = 0; I != 2; ++I) {
499 if (VisitOrder[I]) {
500 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
501 RegionOfInterest.isInvalid()) {
502 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
503 TLEnd = CXXUnit->top_level_end();
504 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000505 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000506 return true;
507 }
508 } else if (VisitDeclContext(
509 CXXUnit->getASTContext().getTranslationUnitDecl()))
510 return true;
511 continue;
512 }
513
514 // Walk the preprocessing record.
515 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
516 visitPreprocessedEntitiesInRegion();
517 }
518
519 return false;
520 }
521
522 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000523 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000524 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
525 return Visit(BaseTSInfo->getTypeLoc());
526 }
527 }
528 }
529
530 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000531 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000532 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000533 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000534 return Visit(cxcursor::MakeCursorObjCClassRef(
535 ObjT->getInterface(),
536 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000537 }
538
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000539 // If pointing inside a macro definition, check if the token is an identifier
540 // that was ever defined as a macro. In such a case, create a "pseudo" macro
541 // expansion cursor for that token.
542 SourceLocation BeginLoc = RegionOfInterest.getBegin();
543 if (Cursor.kind == CXCursor_MacroDefinition &&
544 BeginLoc == RegionOfInterest.getEnd()) {
545 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 const MacroInfo *MI =
547 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000548 if (MacroDefinition *MacroDef =
549 checkForMacroInMacroDefinition(MI, Loc, TU))
550 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
551 }
552
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 // Nothing to visit at the moment.
554 return false;
555}
556
557bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
558 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
559 if (Visit(TSInfo->getTypeLoc()))
560 return true;
561
562 if (Stmt *Body = B->getBody())
563 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
564
565 return false;
566}
567
Ted Kremenek03325582013-02-21 01:29:01 +0000568Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 if (RegionOfInterest.isValid()) {
570 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
571 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000572 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000573
574 switch (CompareRegionOfInterest(Range)) {
575 case RangeBefore:
576 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000577 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000578
579 case RangeAfter:
580 // This declaration comes after the region of interest; we're done.
581 return false;
582
583 case RangeOverlap:
584 // This declaration overlaps the region of interest; visit it.
585 break;
586 }
587 }
588 return true;
589}
590
591bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
592 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
593
594 // FIXME: Eventually remove. This part of a hack to support proper
595 // iteration over all Decls contained lexically within an ObjC container.
596 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
597 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
598
599 for ( ; I != E; ++I) {
600 Decl *D = *I;
601 if (D->getLexicalDeclContext() != DC)
602 continue;
603 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
604
605 // Ignore synthesized ivars here, otherwise if we have something like:
606 // @synthesize prop = _prop;
607 // and '_prop' is not declared, we will encounter a '_prop' ivar before
608 // encountering the 'prop' synthesize declaration and we will think that
609 // we passed the region-of-interest.
610 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
611 if (ivarD->getSynthesize())
612 continue;
613 }
614
615 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
616 // declarations is a mismatch with the compiler semantics.
617 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
618 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
619 if (!ID->isThisDeclarationADefinition())
620 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
621
622 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
623 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
624 if (!PD->isThisDeclarationADefinition())
625 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
626 }
627
Ted Kremenek03325582013-02-21 01:29:01 +0000628 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000629 if (!V.hasValue())
630 continue;
631 if (!V.getValue())
632 return false;
633 if (Visit(Cursor, true))
634 return true;
635 }
636 return false;
637}
638
639bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
640 llvm_unreachable("Translation units are visited directly by Visit()");
641}
642
643bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
644 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
645 return Visit(TSInfo->getTypeLoc());
646
647 return false;
648}
649
650bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
651 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
652 return Visit(TSInfo->getTypeLoc());
653
654 return false;
655}
656
657bool CursorVisitor::VisitTagDecl(TagDecl *D) {
658 return VisitDeclContext(D);
659}
660
661bool CursorVisitor::VisitClassTemplateSpecializationDecl(
662 ClassTemplateSpecializationDecl *D) {
663 bool ShouldVisitBody = false;
664 switch (D->getSpecializationKind()) {
665 case TSK_Undeclared:
666 case TSK_ImplicitInstantiation:
667 // Nothing to visit
668 return false;
669
670 case TSK_ExplicitInstantiationDeclaration:
671 case TSK_ExplicitInstantiationDefinition:
672 break;
673
674 case TSK_ExplicitSpecialization:
675 ShouldVisitBody = true;
676 break;
677 }
678
679 // Visit the template arguments used in the specialization.
680 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
681 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000682 if (TemplateSpecializationTypeLoc TSTLoc =
683 TL.getAs<TemplateSpecializationTypeLoc>()) {
684 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
685 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000686 return true;
687 }
688 }
689
690 if (ShouldVisitBody && VisitCXXRecordDecl(D))
691 return true;
692
693 return false;
694}
695
696bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
697 ClassTemplatePartialSpecializationDecl *D) {
698 // FIXME: Visit the "outer" template parameter lists on the TagDecl
699 // before visiting these template parameters.
700 if (VisitTemplateParameters(D->getTemplateParameters()))
701 return true;
702
703 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000704 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
705 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
706 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000707 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
708 return true;
709
710 return VisitCXXRecordDecl(D);
711}
712
713bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
714 // Visit the default argument.
715 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
716 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
717 if (Visit(DefArg->getTypeLoc()))
718 return true;
719
720 return false;
721}
722
723bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
724 if (Expr *Init = D->getInitExpr())
725 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
726 return false;
727}
728
729bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000730 unsigned NumParamList = DD->getNumTemplateParameterLists();
731 for (unsigned i = 0; i < NumParamList; i++) {
732 TemplateParameterList* Params = DD->getTemplateParameterList(i);
733 if (VisitTemplateParameters(Params))
734 return true;
735 }
736
Guy Benyei11169dd2012-12-18 14:30:41 +0000737 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
738 if (Visit(TSInfo->getTypeLoc()))
739 return true;
740
741 // Visit the nested-name-specifier, if present.
742 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
743 if (VisitNestedNameSpecifierLoc(QualifierLoc))
744 return true;
745
746 return false;
747}
748
749/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000750static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
751 CXXCtorInitializer *const *Y) {
752 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000753}
754
755bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000756 unsigned NumParamList = ND->getNumTemplateParameterLists();
757 for (unsigned i = 0; i < NumParamList; i++) {
758 TemplateParameterList* Params = ND->getTemplateParameterList(i);
759 if (VisitTemplateParameters(Params))
760 return true;
761 }
762
Guy Benyei11169dd2012-12-18 14:30:41 +0000763 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
764 // Visit the function declaration's syntactic components in the order
765 // written. This requires a bit of work.
766 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000767 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000768
769 // If we have a function declared directly (without the use of a typedef),
770 // visit just the return type. Otherwise, just visit the function's type
771 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000772 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000773 (!FTL && Visit(TL)))
774 return true;
775
776 // Visit the nested-name-specifier, if present.
777 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
778 if (VisitNestedNameSpecifierLoc(QualifierLoc))
779 return true;
780
781 // Visit the declaration name.
782 if (VisitDeclarationNameInfo(ND->getNameInfo()))
783 return true;
784
785 // FIXME: Visit explicitly-specified template arguments!
786
787 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000788 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 return true;
790
Bill Wendling44426052012-12-20 19:22:21 +0000791 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000792 }
793
794 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
795 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
796 // Find the initializers that were written in the source.
797 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
798 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
799 IEnd = Constructor->init_end();
800 I != IEnd; ++I) {
801 if (!(*I)->isWritten())
802 continue;
803
804 WrittenInits.push_back(*I);
805 }
806
807 // Sort the initializers in source order
808 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
809 &CompareCXXCtorInitializers);
810
811 // Visit the initializers in source order
812 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
813 CXXCtorInitializer *Init = WrittenInits[I];
814 if (Init->isAnyMemberInitializer()) {
815 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
816 Init->getMemberLocation(), TU)))
817 return true;
818 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
819 if (Visit(TInfo->getTypeLoc()))
820 return true;
821 }
822
823 // Visit the initializer value.
824 if (Expr *Initializer = Init->getInit())
825 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
826 return true;
827 }
828 }
829
830 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
831 return true;
832 }
833
834 return false;
835}
836
837bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
838 if (VisitDeclaratorDecl(D))
839 return true;
840
841 if (Expr *BitWidth = D->getBitWidth())
842 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
843
844 return false;
845}
846
847bool CursorVisitor::VisitVarDecl(VarDecl *D) {
848 if (VisitDeclaratorDecl(D))
849 return true;
850
851 if (Expr *Init = D->getInit())
852 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
853
854 return false;
855}
856
857bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
858 if (VisitDeclaratorDecl(D))
859 return true;
860
861 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
862 if (Expr *DefArg = D->getDefaultArgument())
863 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
864
865 return false;
866}
867
868bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
869 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
870 // before visiting these template parameters.
871 if (VisitTemplateParameters(D->getTemplateParameters()))
872 return true;
873
874 return VisitFunctionDecl(D->getTemplatedDecl());
875}
876
877bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
878 // FIXME: Visit the "outer" template parameter lists on the TagDecl
879 // before visiting these template parameters.
880 if (VisitTemplateParameters(D->getTemplateParameters()))
881 return true;
882
883 return VisitCXXRecordDecl(D->getTemplatedDecl());
884}
885
886bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
887 if (VisitTemplateParameters(D->getTemplateParameters()))
888 return true;
889
890 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
891 VisitTemplateArgumentLoc(D->getDefaultArgument()))
892 return true;
893
894 return false;
895}
896
897bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000898 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000899 if (Visit(TSInfo->getTypeLoc()))
900 return true;
901
902 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
903 PEnd = ND->param_end();
904 P != PEnd; ++P) {
905 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
906 return true;
907 }
908
909 if (ND->isThisDeclarationADefinition() &&
910 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
911 return true;
912
913 return false;
914}
915
916template <typename DeclIt>
917static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
918 SourceManager &SM, SourceLocation EndLoc,
919 SmallVectorImpl<Decl *> &Decls) {
920 DeclIt next = *DI_current;
921 while (++next != DE_current) {
922 Decl *D_next = *next;
923 if (!D_next)
924 break;
925 SourceLocation L = D_next->getLocStart();
926 if (!L.isValid())
927 break;
928 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
929 *DI_current = next;
930 Decls.push_back(D_next);
931 continue;
932 }
933 break;
934 }
935}
936
937namespace {
938 struct ContainerDeclsSort {
939 SourceManager &SM;
940 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
941 bool operator()(Decl *A, Decl *B) {
942 SourceLocation L_A = A->getLocStart();
943 SourceLocation L_B = B->getLocStart();
944 assert(L_A.isValid() && L_B.isValid());
945 return SM.isBeforeInTranslationUnit(L_A, L_B);
946 }
947 };
948}
949
950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
981 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
982 I!=E; ++I) {
983 Decl *subDecl = *I;
984 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
985 subDecl->getLocStart().isInvalid())
986 continue;
987 DeclsInContainer.push_back(subDecl);
988 }
989
990 // Now sort the Decls so that they appear in lexical order.
991 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
992 ContainerDeclsSort(SM));
993
994 // Now visit the decls.
995 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
996 E = DeclsInContainer.end(); I != E; ++I) {
997 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +0000998 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000999 if (!V.hasValue())
1000 continue;
1001 if (!V.getValue())
1002 return false;
1003 if (Visit(Cursor, true))
1004 return true;
1005 }
1006 return false;
1007}
1008
1009bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1010 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1011 TU)))
1012 return true;
1013
1014 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1015 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1016 E = ND->protocol_end(); I != E; ++I, ++PL)
1017 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1018 return true;
1019
1020 return VisitObjCContainerDecl(ND);
1021}
1022
1023bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1024 if (!PID->isThisDeclarationADefinition())
1025 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1026
1027 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1028 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1029 E = PID->protocol_end(); I != E; ++I, ++PL)
1030 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1031 return true;
1032
1033 return VisitObjCContainerDecl(PID);
1034}
1035
1036bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1037 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1038 return true;
1039
1040 // FIXME: This implements a workaround with @property declarations also being
1041 // installed in the DeclContext for the @interface. Eventually this code
1042 // should be removed.
1043 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1044 if (!CDecl || !CDecl->IsClassExtension())
1045 return false;
1046
1047 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1048 if (!ID)
1049 return false;
1050
1051 IdentifierInfo *PropertyId = PD->getIdentifier();
1052 ObjCPropertyDecl *prevDecl =
1053 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1054
1055 if (!prevDecl)
1056 return false;
1057
1058 // Visit synthesized methods since they will be skipped when visiting
1059 // the @interface.
1060 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1061 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1062 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1063 return true;
1064
1065 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1066 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1067 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1068 return true;
1069
1070 return false;
1071}
1072
1073bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1074 if (!D->isThisDeclarationADefinition()) {
1075 // Forward declaration is treated like a reference.
1076 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1077 }
1078
1079 // Issue callbacks for super class.
1080 if (D->getSuperClass() &&
1081 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1082 D->getSuperClassLoc(),
1083 TU)))
1084 return true;
1085
1086 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1087 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1088 E = D->protocol_end(); I != E; ++I, ++PL)
1089 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1090 return true;
1091
1092 return VisitObjCContainerDecl(D);
1093}
1094
1095bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1096 return VisitObjCContainerDecl(D);
1097}
1098
1099bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1100 // 'ID' could be null when dealing with invalid code.
1101 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1102 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1103 return true;
1104
1105 return VisitObjCImplDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1109#if 0
1110 // Issue callbacks for super class.
1111 // FIXME: No source location information!
1112 if (D->getSuperClass() &&
1113 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1114 D->getSuperClassLoc(),
1115 TU)))
1116 return true;
1117#endif
1118
1119 return VisitObjCImplDecl(D);
1120}
1121
1122bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1123 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1124 if (PD->isIvarNameSpecified())
1125 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1126
1127 return false;
1128}
1129
1130bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1131 return VisitDeclContext(D);
1132}
1133
1134bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1135 // Visit nested-name-specifier.
1136 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1137 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1138 return true;
1139
1140 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1141 D->getTargetNameLoc(), TU));
1142}
1143
1144bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149 }
1150
1151 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1152 return true;
1153
1154 return VisitDeclarationNameInfo(D->getNameInfo());
1155}
1156
1157bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1158 // Visit nested-name-specifier.
1159 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1160 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1161 return true;
1162
1163 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1164 D->getIdentLocation(), TU));
1165}
1166
1167bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172 }
1173
1174 return VisitDeclarationNameInfo(D->getNameInfo());
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1178 UnresolvedUsingTypenameDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183
1184 return false;
1185}
1186
1187bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1188 switch (Name.getName().getNameKind()) {
1189 case clang::DeclarationName::Identifier:
1190 case clang::DeclarationName::CXXLiteralOperatorName:
1191 case clang::DeclarationName::CXXOperatorName:
1192 case clang::DeclarationName::CXXUsingDirective:
1193 return false;
1194
1195 case clang::DeclarationName::CXXConstructorName:
1196 case clang::DeclarationName::CXXDestructorName:
1197 case clang::DeclarationName::CXXConversionFunctionName:
1198 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1199 return Visit(TSInfo->getTypeLoc());
1200 return false;
1201
1202 case clang::DeclarationName::ObjCZeroArgSelector:
1203 case clang::DeclarationName::ObjCOneArgSelector:
1204 case clang::DeclarationName::ObjCMultiArgSelector:
1205 // FIXME: Per-identifier location info?
1206 return false;
1207 }
1208
1209 llvm_unreachable("Invalid DeclarationName::Kind!");
1210}
1211
1212bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1213 SourceRange Range) {
1214 // FIXME: This whole routine is a hack to work around the lack of proper
1215 // source information in nested-name-specifiers (PR5791). Since we do have
1216 // a beginning source location, we can visit the first component of the
1217 // nested-name-specifier, if it's a single-token component.
1218 if (!NNS)
1219 return false;
1220
1221 // Get the first component in the nested-name-specifier.
1222 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1223 NNS = Prefix;
1224
1225 switch (NNS->getKind()) {
1226 case NestedNameSpecifier::Namespace:
1227 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1228 TU));
1229
1230 case NestedNameSpecifier::NamespaceAlias:
1231 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1232 Range.getBegin(), TU));
1233
1234 case NestedNameSpecifier::TypeSpec: {
1235 // If the type has a form where we know that the beginning of the source
1236 // range matches up with a reference cursor. Visit the appropriate reference
1237 // cursor.
1238 const Type *T = NNS->getAsType();
1239 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1240 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1241 if (const TagType *Tag = dyn_cast<TagType>(T))
1242 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1243 if (const TemplateSpecializationType *TST
1244 = dyn_cast<TemplateSpecializationType>(T))
1245 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1246 break;
1247 }
1248
1249 case NestedNameSpecifier::TypeSpecWithTemplate:
1250 case NestedNameSpecifier::Global:
1251 case NestedNameSpecifier::Identifier:
1252 break;
1253 }
1254
1255 return false;
1256}
1257
1258bool
1259CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1260 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1261 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1262 Qualifiers.push_back(Qualifier);
1263
1264 while (!Qualifiers.empty()) {
1265 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1266 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1267 switch (NNS->getKind()) {
1268 case NestedNameSpecifier::Namespace:
1269 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1270 Q.getLocalBeginLoc(),
1271 TU)))
1272 return true;
1273
1274 break;
1275
1276 case NestedNameSpecifier::NamespaceAlias:
1277 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1278 Q.getLocalBeginLoc(),
1279 TU)))
1280 return true;
1281
1282 break;
1283
1284 case NestedNameSpecifier::TypeSpec:
1285 case NestedNameSpecifier::TypeSpecWithTemplate:
1286 if (Visit(Q.getTypeLoc()))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::Global:
1292 case NestedNameSpecifier::Identifier:
1293 break;
1294 }
1295 }
1296
1297 return false;
1298}
1299
1300bool CursorVisitor::VisitTemplateParameters(
1301 const TemplateParameterList *Params) {
1302 if (!Params)
1303 return false;
1304
1305 for (TemplateParameterList::const_iterator P = Params->begin(),
1306 PEnd = Params->end();
1307 P != PEnd; ++P) {
1308 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1309 return true;
1310 }
1311
1312 return false;
1313}
1314
1315bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1316 switch (Name.getKind()) {
1317 case TemplateName::Template:
1318 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1319
1320 case TemplateName::OverloadedTemplate:
1321 // Visit the overloaded template set.
1322 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1323 return true;
1324
1325 return false;
1326
1327 case TemplateName::DependentTemplate:
1328 // FIXME: Visit nested-name-specifier.
1329 return false;
1330
1331 case TemplateName::QualifiedTemplate:
1332 // FIXME: Visit nested-name-specifier.
1333 return Visit(MakeCursorTemplateRef(
1334 Name.getAsQualifiedTemplateName()->getDecl(),
1335 Loc, TU));
1336
1337 case TemplateName::SubstTemplateTemplateParm:
1338 return Visit(MakeCursorTemplateRef(
1339 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1340 Loc, TU));
1341
1342 case TemplateName::SubstTemplateTemplateParmPack:
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1345 Loc, TU));
1346 }
1347
1348 llvm_unreachable("Invalid TemplateName::Kind!");
1349}
1350
1351bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1352 switch (TAL.getArgument().getKind()) {
1353 case TemplateArgument::Null:
1354 case TemplateArgument::Integral:
1355 case TemplateArgument::Pack:
1356 return false;
1357
1358 case TemplateArgument::Type:
1359 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1360 return Visit(TSInfo->getTypeLoc());
1361 return false;
1362
1363 case TemplateArgument::Declaration:
1364 if (Expr *E = TAL.getSourceDeclExpression())
1365 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1366 return false;
1367
1368 case TemplateArgument::NullPtr:
1369 if (Expr *E = TAL.getSourceNullPtrExpression())
1370 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1371 return false;
1372
1373 case TemplateArgument::Expression:
1374 if (Expr *E = TAL.getSourceExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::Template:
1379 case TemplateArgument::TemplateExpansion:
1380 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1381 return true;
1382
1383 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1384 TAL.getTemplateNameLoc());
1385 }
1386
1387 llvm_unreachable("Invalid TemplateArgument::Kind!");
1388}
1389
1390bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1391 return VisitDeclContext(D);
1392}
1393
1394bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1395 return Visit(TL.getUnqualifiedLoc());
1396}
1397
1398bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1399 ASTContext &Context = AU->getASTContext();
1400
1401 // Some builtin types (such as Objective-C's "id", "sel", and
1402 // "Class") have associated declarations. Create cursors for those.
1403 QualType VisitType;
1404 switch (TL.getTypePtr()->getKind()) {
1405
1406 case BuiltinType::Void:
1407 case BuiltinType::NullPtr:
1408 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001409 case BuiltinType::OCLImage1d:
1410 case BuiltinType::OCLImage1dArray:
1411 case BuiltinType::OCLImage1dBuffer:
1412 case BuiltinType::OCLImage2d:
1413 case BuiltinType::OCLImage2dArray:
1414 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001415 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001416 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001417#define BUILTIN_TYPE(Id, SingletonId)
1418#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1419#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1420#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#include "clang/AST/BuiltinTypes.def"
1423 break;
1424
1425 case BuiltinType::ObjCId:
1426 VisitType = Context.getObjCIdType();
1427 break;
1428
1429 case BuiltinType::ObjCClass:
1430 VisitType = Context.getObjCClassType();
1431 break;
1432
1433 case BuiltinType::ObjCSel:
1434 VisitType = Context.getObjCSelType();
1435 break;
1436 }
1437
1438 if (!VisitType.isNull()) {
1439 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1440 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1441 TU));
1442 }
1443
1444 return false;
1445}
1446
1447bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1448 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1449}
1450
1451bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1452 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1453}
1454
1455bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1456 if (TL.isDefinition())
1457 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1458
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1467 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1468 return true;
1469
1470 return false;
1471}
1472
1473bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1474 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1475 return true;
1476
1477 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1478 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1479 TU)))
1480 return true;
1481 }
1482
1483 return false;
1484}
1485
1486bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1487 return Visit(TL.getPointeeLoc());
1488}
1489
1490bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1491 return Visit(TL.getInnerLoc());
1492}
1493
1494bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1495 return Visit(TL.getPointeeLoc());
1496}
1497
1498bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1503 return Visit(TL.getPointeeLoc());
1504}
1505
1506bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1515 return Visit(TL.getModifiedLoc());
1516}
1517
1518bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1519 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001520 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001521 return true;
1522
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001523 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1524 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001525 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1526 return true;
1527
1528 return false;
1529}
1530
1531bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1532 if (Visit(TL.getElementLoc()))
1533 return true;
1534
1535 if (Expr *Size = TL.getSizeExpr())
1536 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1537
1538 return false;
1539}
1540
Reid Kleckner8a365022013-06-24 17:51:48 +00001541bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1542 return Visit(TL.getOriginalLoc());
1543}
1544
Reid Kleckner0503a872013-12-05 01:23:43 +00001545bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1546 return Visit(TL.getOriginalLoc());
1547}
1548
Guy Benyei11169dd2012-12-18 14:30:41 +00001549bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1550 TemplateSpecializationTypeLoc TL) {
1551 // Visit the template name.
1552 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1553 TL.getTemplateNameLoc()))
1554 return true;
1555
1556 // Visit the template arguments.
1557 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1558 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1559 return true;
1560
1561 return false;
1562}
1563
1564bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1565 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1566}
1567
1568bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1569 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1570 return Visit(TSInfo->getTypeLoc());
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1583 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1584 return true;
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1590 DependentTemplateSpecializationTypeLoc TL) {
1591 // Visit the nested-name-specifier, if there is one.
1592 if (TL.getQualifierLoc() &&
1593 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1594 return true;
1595
1596 // Visit the template arguments.
1597 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1598 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1599 return true;
1600
1601 return false;
1602}
1603
1604bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1605 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 return Visit(TL.getNamedTypeLoc());
1609}
1610
1611bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1612 return Visit(TL.getPatternLoc());
1613}
1614
1615bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1616 if (Expr *E = TL.getUnderlyingExpr())
1617 return Visit(MakeCXCursor(E, StmtParent, TU));
1618
1619 return false;
1620}
1621
1622bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1623 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1624}
1625
1626bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1627 return Visit(TL.getValueLoc());
1628}
1629
1630#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1631bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1632 return Visit##PARENT##Loc(TL); \
1633}
1634
1635DEFAULT_TYPELOC_IMPL(Complex, Type)
1636DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1638DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1641DEFAULT_TYPELOC_IMPL(Vector, Type)
1642DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1643DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1644DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1645DEFAULT_TYPELOC_IMPL(Record, TagType)
1646DEFAULT_TYPELOC_IMPL(Enum, TagType)
1647DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1648DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1649DEFAULT_TYPELOC_IMPL(Auto, Type)
1650
1651bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1652 // Visit the nested-name-specifier, if present.
1653 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1654 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1655 return true;
1656
1657 if (D->isCompleteDefinition()) {
1658 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1659 E = D->bases_end(); I != E; ++I) {
1660 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1661 return true;
1662 }
1663 }
1664
1665 return VisitTagDecl(D);
1666}
1667
1668bool CursorVisitor::VisitAttributes(Decl *D) {
1669 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1670 i != e; ++i)
1671 if (Visit(MakeCXCursor(*i, D, TU)))
1672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001706 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001801 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 VisitorWorkList &WL;
1803 CXCursor Parent;
1804public:
1805 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1806 : WL(wl), Parent(parent) {}
1807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1809 void VisitBlockExpr(const BlockExpr *B);
1810 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1811 void VisitCompoundStmt(const CompoundStmt *S);
1812 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1813 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1814 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1815 void VisitCXXNewExpr(const CXXNewExpr *E);
1816 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1817 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1818 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1819 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1820 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1821 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1822 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1823 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1824 void VisitDeclRefExpr(const DeclRefExpr *D);
1825 void VisitDeclStmt(const DeclStmt *S);
1826 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1827 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1828 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1829 void VisitForStmt(const ForStmt *FS);
1830 void VisitGotoStmt(const GotoStmt *GS);
1831 void VisitIfStmt(const IfStmt *If);
1832 void VisitInitListExpr(const InitListExpr *IE);
1833 void VisitMemberExpr(const MemberExpr *M);
1834 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1835 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1836 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1837 void VisitOverloadExpr(const OverloadExpr *E);
1838 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1839 void VisitStmt(const Stmt *S);
1840 void VisitSwitchStmt(const SwitchStmt *S);
1841 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853
Guy Benyei11169dd2012-12-18 14:30:41 +00001854private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001856 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1857 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1859 void AddStmt(const Stmt *S);
1860 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001863 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001864};
1865} // end anonyous namespace
1866
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001868 // 'S' should always be non-null, since it comes from the
1869 // statement we are visiting.
1870 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1871}
1872
1873void
1874EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1875 if (Qualifier)
1876 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1877}
1878
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 if (S)
1881 WL.push_back(StmtVisit(S, Parent));
1882}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 if (D)
1885 WL.push_back(DeclVisit(D, Parent, isFirst));
1886}
1887void EnqueueVisitor::
1888 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1889 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001891}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001893 if (D)
1894 WL.push_back(MemberRefVisit(D, L, Parent));
1895}
1896void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1897 if (TI)
1898 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1899 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 AddStmt(*Child);
1904 }
1905 if (size == WL.size())
1906 return;
1907 // Now reverse the entries we just added. This will match the DFS
1908 // ordering performed by the worklist.
1909 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1910 std::reverse(I, E);
1911}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001912namespace {
1913class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1914 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001915 /// \brief Process clauses with list of variables.
1916 template <typename T>
1917 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918public:
1919 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1920#define OPENMP_CLAUSE(Name, Class) \
1921 void Visit##Class(const Class *C);
1922#include "clang/Basic/OpenMPKinds.def"
1923};
1924
1925void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001926
1927template<typename T>
1928void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1929 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1930 E = Node->varlist_end();
1931 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001933}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001934
1935void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001936 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001937}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001938void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1939 const OMPFirstprivateClause *C) {
1940 VisitOMPClauseList(C);
1941}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001942void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001943 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001944}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945}
Alexey Bataev756c1962013-09-24 03:17:45 +00001946
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1948 unsigned size = WL.size();
1949 OMPClauseEnqueue Visitor(this);
1950 Visitor.Visit(S);
1951 if (size == WL.size())
1952 return;
1953 // Now reverse the entries we just added. This will match the DFS
1954 // ordering performed by the worklist.
1955 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1956 std::reverse(I, E);
1957}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1960}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 AddDecl(B->getBlockDecl());
1963}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 EnqueueChildren(E);
1966 AddTypeLoc(E->getTypeSourceInfo());
1967}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1969 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 E = S->body_rend(); I != E; ++I) {
1971 AddStmt(*I);
1972 }
1973}
1974void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 AddStmt(S->getSubStmt());
1977 AddDeclarationNameInfo(S);
1978 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1979 AddNestedNameSpecifierLoc(QualifierLoc);
1980}
1981
1982void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1985 AddDeclarationNameInfo(E);
1986 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1987 AddNestedNameSpecifierLoc(QualifierLoc);
1988 if (!E->isImplicitAccess())
1989 AddStmt(E->getBase());
1990}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 // Enqueue the initializer , if any.
1993 AddStmt(E->getInitializer());
1994 // Enqueue the array size, if any.
1995 AddStmt(E->getArraySize());
1996 // Enqueue the allocated type.
1997 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1998 // Enqueue the placement arguments.
1999 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2000 AddStmt(E->getPlacementArg(I-1));
2001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2004 AddStmt(CE->getArg(I-1));
2005 AddStmt(CE->getCallee());
2006 AddStmt(CE->getArg(0));
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2009 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 // Visit the name of the type being destroyed.
2011 AddTypeLoc(E->getDestroyedTypeInfo());
2012 // Visit the scope type that looks disturbingly like the nested-name-specifier
2013 // but isn't.
2014 AddTypeLoc(E->getScopeTypeInfo());
2015 // Visit the nested-name-specifier.
2016 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2017 AddNestedNameSpecifierLoc(QualifierLoc);
2018 // Visit base expression.
2019 AddStmt(E->getBase());
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2022 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 AddTypeLoc(E->getTypeSourceInfo());
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2026 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 EnqueueChildren(E);
2028 AddTypeLoc(E->getTypeSourceInfo());
2029}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 EnqueueChildren(E);
2032 if (E->isTypeOperand())
2033 AddTypeLoc(E->getTypeOperandSourceInfo());
2034}
2035
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2037 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002038 EnqueueChildren(E);
2039 AddTypeLoc(E->getTypeSourceInfo());
2040}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 EnqueueChildren(E);
2043 if (E->isTypeOperand())
2044 AddTypeLoc(E->getTypeOperandSourceInfo());
2045}
2046
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(S);
2049 AddDecl(S->getExceptionDecl());
2050}
2051
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 if (DR->hasExplicitTemplateArgs()) {
2054 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2055 }
2056 WL.push_back(DeclRefExprParts(DR, Parent));
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2059 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2061 AddDeclarationNameInfo(E);
2062 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 unsigned size = WL.size();
2066 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 D != DEnd; ++D) {
2069 AddDecl(*D, isFirst);
2070 isFirst = false;
2071 }
2072 if (size == WL.size())
2073 return;
2074 // Now reverse the entries we just added. This will match the DFS
2075 // ordering performed by the worklist.
2076 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2077 std::reverse(I, E);
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 D = E->designators_rbegin(), DEnd = E->designators_rend();
2083 D != DEnd; ++D) {
2084 if (D->isFieldDesignator()) {
2085 if (FieldDecl *Field = D->getField())
2086 AddMemberRef(Field, D->getFieldLoc());
2087 continue;
2088 }
2089 if (D->isArrayDesignator()) {
2090 AddStmt(E->getArrayIndex(*D));
2091 continue;
2092 }
2093 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2094 AddStmt(E->getArrayRangeEnd(*D));
2095 AddStmt(E->getArrayRangeStart(*D));
2096 }
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 EnqueueChildren(E);
2100 AddTypeLoc(E->getTypeInfoAsWritten());
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 AddStmt(FS->getBody());
2104 AddStmt(FS->getInc());
2105 AddStmt(FS->getCond());
2106 AddDecl(FS->getConditionVariable());
2107 AddStmt(FS->getInit());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 AddStmt(If->getElse());
2114 AddStmt(If->getThen());
2115 AddStmt(If->getCond());
2116 AddDecl(If->getConditionVariable());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 // We care about the syntactic form of the initializer list, only.
2120 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2121 IE = Syntactic;
2122 EnqueueChildren(IE);
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 WL.push_back(MemberExprParts(M, Parent));
2126
2127 // If the base of the member access expression is an implicit 'this', don't
2128 // visit it.
2129 // FIXME: If we ever want to show these implicit accesses, this will be
2130 // unfortunate. However, clang_getCursor() relies on this behavior.
2131 if (!M->isImplicitAccess())
2132 AddStmt(M->getBase());
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 AddTypeLoc(E->getEncodedTypeSourceInfo());
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 EnqueueChildren(M);
2139 AddTypeLoc(M->getClassReceiverTypeInfo());
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 // Visit the components of the offsetof expression.
2143 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2144 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2145 const OffsetOfNode &Node = E->getComponent(I-1);
2146 switch (Node.getKind()) {
2147 case OffsetOfNode::Array:
2148 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2149 break;
2150 case OffsetOfNode::Field:
2151 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2152 break;
2153 case OffsetOfNode::Identifier:
2154 case OffsetOfNode::Base:
2155 continue;
2156 }
2157 }
2158 // Visit the type into which we're computing the offset.
2159 AddTypeLoc(E->getTypeSourceInfo());
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2163 WL.push_back(OverloadExprParts(E, Parent));
2164}
2165void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 EnqueueChildren(E);
2168 if (E->isArgumentType())
2169 AddTypeLoc(E->getArgumentTypeInfo());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(S);
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddStmt(S->getBody());
2176 AddStmt(S->getCond());
2177 AddDecl(S->getConditionVariable());
2178}
2179
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddStmt(W->getBody());
2182 AddStmt(W->getCond());
2183 AddDecl(W->getConditionVariable());
2184}
2185
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 for (unsigned I = E->getNumArgs(); I > 0; --I)
2188 AddTypeLoc(E->getArg(I-1));
2189}
2190
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddTypeLoc(E->getQueriedTypeSourceInfo());
2193}
2194
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 EnqueueChildren(E);
2197}
2198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 VisitOverloadExpr(U);
2201 if (!U->isImplicitAccess())
2202 AddStmt(U->getBase());
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddStmt(E->getSubExpr());
2206 AddTypeLoc(E->getWrittenTypeInfo());
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 WL.push_back(SizeOfPackExprParts(E, Parent));
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 // If the opaque value has a source expression, just transparently
2213 // visit that. This is useful for (e.g.) pseudo-object expressions.
2214 if (Expr *SourceExpr = E->getSourceExpr())
2215 return Visit(SourceExpr);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddStmt(E->getBody());
2219 WL.push_back(LambdaExprParts(E, Parent));
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 // Treat the expression like its syntactic form.
2223 Visit(E->getSyntacticForm());
2224}
2225
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002226void EnqueueVisitor::VisitOMPExecutableDirective(
2227 const OMPExecutableDirective *D) {
2228 EnqueueChildren(D);
2229 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2230 E = D->clauses().end();
2231 I != E; ++I)
2232 EnqueueChildren(*I);
2233}
2234
2235void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2236 VisitOMPExecutableDirective(D);
2237}
2238
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2241}
2242
2243bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2244 if (RegionOfInterest.isValid()) {
2245 SourceRange Range = getRawCursorExtent(C);
2246 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2247 return false;
2248 }
2249 return true;
2250}
2251
2252bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2253 while (!WL.empty()) {
2254 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002255 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002256
2257 // Set the Parent field, then back to its old value once we're done.
2258 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2259
2260 switch (LI.getKind()) {
2261 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 if (!D)
2264 continue;
2265
2266 // For now, perform default visitation for Decls.
2267 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2268 cast<DeclVisit>(&LI)->isFirst())))
2269 return true;
2270
2271 continue;
2272 }
2273 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2274 const ASTTemplateArgumentListInfo *ArgList =
2275 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2276 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2277 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2278 Arg != ArgEnd; ++Arg) {
2279 if (VisitTemplateArgumentLoc(*Arg))
2280 return true;
2281 }
2282 continue;
2283 }
2284 case VisitorJob::TypeLocVisitKind: {
2285 // Perform default visitation for TypeLocs.
2286 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2287 return true;
2288 continue;
2289 }
2290 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 if (LabelStmt *stmt = LS->getStmt()) {
2293 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2294 TU))) {
2295 return true;
2296 }
2297 }
2298 continue;
2299 }
2300
2301 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2302 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2303 if (VisitNestedNameSpecifierLoc(V->get()))
2304 return true;
2305 continue;
2306 }
2307
2308 case VisitorJob::DeclarationNameInfoVisitKind: {
2309 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2310 ->get()))
2311 return true;
2312 continue;
2313 }
2314 case VisitorJob::MemberRefVisitKind: {
2315 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2316 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2317 return true;
2318 continue;
2319 }
2320 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 if (!S)
2323 continue;
2324
2325 // Update the current cursor.
2326 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2327 if (!IsInRegionOfInterest(Cursor))
2328 continue;
2329 switch (Visitor(Cursor, Parent, ClientData)) {
2330 case CXChildVisit_Break: return true;
2331 case CXChildVisit_Continue: break;
2332 case CXChildVisit_Recurse:
2333 if (PostChildrenVisitor)
2334 WL.push_back(PostChildrenVisit(0, Cursor));
2335 EnqueueWorkList(WL, S);
2336 break;
2337 }
2338 continue;
2339 }
2340 case VisitorJob::MemberExprPartsKind: {
2341 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343
2344 // Visit the nested-name-specifier
2345 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2346 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2347 return true;
2348
2349 // Visit the declaration name.
2350 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2351 return true;
2352
2353 // Visit the explicitly-specified template arguments, if any.
2354 if (M->hasExplicitTemplateArgs()) {
2355 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2356 *ArgEnd = Arg + M->getNumTemplateArgs();
2357 Arg != ArgEnd; ++Arg) {
2358 if (VisitTemplateArgumentLoc(*Arg))
2359 return true;
2360 }
2361 }
2362 continue;
2363 }
2364 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002366 // Visit nested-name-specifier, if present.
2367 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2368 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2369 return true;
2370 // Visit declaration name.
2371 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2372 return true;
2373 continue;
2374 }
2375 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 // Visit the nested-name-specifier.
2378 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2379 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2380 return true;
2381 // Visit the declaration name.
2382 if (VisitDeclarationNameInfo(O->getNameInfo()))
2383 return true;
2384 // Visit the overloaded declaration reference.
2385 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2386 return true;
2387 continue;
2388 }
2389 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 NamedDecl *Pack = E->getPack();
2392 if (isa<TemplateTypeParmDecl>(Pack)) {
2393 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2394 E->getPackLoc(), TU)))
2395 return true;
2396
2397 continue;
2398 }
2399
2400 if (isa<TemplateTemplateParmDecl>(Pack)) {
2401 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2402 E->getPackLoc(), TU)))
2403 return true;
2404
2405 continue;
2406 }
2407
2408 // Non-type template parameter packs and function parameter packs are
2409 // treated like DeclRefExpr cursors.
2410 continue;
2411 }
2412
2413 case VisitorJob::LambdaExprPartsKind: {
2414 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2417 CEnd = E->explicit_capture_end();
2418 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002419 // FIXME: Lambda init-captures.
2420 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002422
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2424 C->getLocation(),
2425 TU)))
2426 return true;
2427 }
2428
2429 // Visit parameters and return type, if present.
2430 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2431 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2432 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2433 // Visit the whole type.
2434 if (Visit(TL))
2435 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002436 } else if (FunctionProtoTypeLoc Proto =
2437 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 if (E->hasExplicitParameters()) {
2439 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002440 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2441 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 return true;
2443 } else {
2444 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002445 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 return true;
2447 }
2448 }
2449 }
2450 break;
2451 }
2452
2453 case VisitorJob::PostChildrenVisitKind:
2454 if (PostChildrenVisitor(Parent, ClientData))
2455 return true;
2456 break;
2457 }
2458 }
2459 return false;
2460}
2461
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 VisitorWorkList *WL = 0;
2464 if (!WorkListFreeList.empty()) {
2465 WL = WorkListFreeList.back();
2466 WL->clear();
2467 WorkListFreeList.pop_back();
2468 }
2469 else {
2470 WL = new VisitorWorkList();
2471 WorkListCache.push_back(WL);
2472 }
2473 EnqueueWorkList(*WL, S);
2474 bool result = RunVisitorWorkList(*WL);
2475 WorkListFreeList.push_back(WL);
2476 return result;
2477}
2478
2479namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002480typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002481RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2482 const DeclarationNameInfo &NI,
2483 const SourceRange &QLoc,
2484 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2485 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2486 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2487 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2488
2489 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2490
2491 RefNamePieces Pieces;
2492
2493 if (WantQualifier && QLoc.isValid())
2494 Pieces.push_back(QLoc);
2495
2496 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2497 Pieces.push_back(NI.getLoc());
2498
2499 if (WantTemplateArgs && TemplateArgs)
2500 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2501 TemplateArgs->RAngleLoc));
2502
2503 if (Kind == DeclarationName::CXXOperatorName) {
2504 Pieces.push_back(SourceLocation::getFromRawEncoding(
2505 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2506 Pieces.push_back(SourceLocation::getFromRawEncoding(
2507 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2508 }
2509
2510 if (WantSinglePiece) {
2511 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2512 Pieces.clear();
2513 Pieces.push_back(R);
2514 }
2515
2516 return Pieces;
2517}
2518}
2519
2520//===----------------------------------------------------------------------===//
2521// Misc. API hooks.
2522//===----------------------------------------------------------------------===//
2523
2524static llvm::sys::Mutex EnableMultithreadingMutex;
2525static bool EnabledMultithreading;
2526
Chad Rosier05c71aa2013-03-27 18:28:23 +00002527static void fatal_error_handler(void *user_data, const std::string& reason,
2528 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 // Write the result out to stderr avoiding errs() because raw_ostreams can
2530 // call report_fatal_error.
2531 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2532 ::abort();
2533}
2534
2535extern "C" {
2536CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2537 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 // We use crash recovery to make some of our APIs more reliable, implicitly
2539 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002540 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2541 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002542
2543 // Enable support for multithreading in LLVM.
2544 {
2545 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2546 if (!EnabledMultithreading) {
2547 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2548 llvm::llvm_start_multithreaded();
2549 EnabledMultithreading = true;
2550 }
2551 }
2552
2553 CIndexer *CIdxr = new CIndexer();
2554 if (excludeDeclarationsFromPCH)
2555 CIdxr->setOnlyLocalDecls();
2556 if (displayDiagnostics)
2557 CIdxr->setDisplayDiagnostics();
2558
2559 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2560 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2561 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2562 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2563 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2564 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2565
2566 return CIdxr;
2567}
2568
2569void clang_disposeIndex(CXIndex CIdx) {
2570 if (CIdx)
2571 delete static_cast<CIndexer *>(CIdx);
2572}
2573
2574void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2575 if (CIdx)
2576 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2577}
2578
2579unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2580 if (CIdx)
2581 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2582 return 0;
2583}
2584
2585void clang_toggleCrashRecovery(unsigned isEnabled) {
2586 if (isEnabled)
2587 llvm::CrashRecoveryContext::Enable();
2588 else
2589 llvm::CrashRecoveryContext::Disable();
2590}
2591
2592CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2593 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002594 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 return 0;
2596
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002597 LOG_FUNC_SECTION {
2598 *Log << ast_filename;
2599 }
2600
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2602 FileSystemOptions FileSystemOpts;
2603
2604 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2605 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2606 CXXIdx->getOnlyLocalDecls(),
2607 0, 0,
2608 /*CaptureDiagnostics=*/true,
2609 /*AllowPCHWithCompilerErrors=*/true,
2610 /*UserFilesAreVolatile=*/true);
2611 return MakeCXTranslationUnit(CXXIdx, TU);
2612}
2613
2614unsigned clang_defaultEditingTranslationUnitOptions() {
2615 return CXTranslationUnit_PrecompiledPreamble |
2616 CXTranslationUnit_CacheCompletionResults;
2617}
2618
2619CXTranslationUnit
2620clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2621 const char *source_filename,
2622 int num_command_line_args,
2623 const char * const *command_line_args,
2624 unsigned num_unsaved_files,
2625 struct CXUnsavedFile *unsaved_files) {
2626 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2627 return clang_parseTranslationUnit(CIdx, source_filename,
2628 command_line_args, num_command_line_args,
2629 unsaved_files, num_unsaved_files,
2630 Options);
2631}
2632
2633struct ParseTranslationUnitInfo {
2634 CXIndex CIdx;
2635 const char *source_filename;
2636 const char *const *command_line_args;
2637 int num_command_line_args;
2638 struct CXUnsavedFile *unsaved_files;
2639 unsigned num_unsaved_files;
2640 unsigned options;
2641 CXTranslationUnit result;
2642};
2643static void clang_parseTranslationUnit_Impl(void *UserData) {
2644 ParseTranslationUnitInfo *PTUI =
2645 static_cast<ParseTranslationUnitInfo*>(UserData);
2646 CXIndex CIdx = PTUI->CIdx;
2647 const char *source_filename = PTUI->source_filename;
2648 const char * const *command_line_args = PTUI->command_line_args;
2649 int num_command_line_args = PTUI->num_command_line_args;
2650 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2651 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2652 unsigned options = PTUI->options;
2653 PTUI->result = 0;
2654
2655 if (!CIdx)
2656 return;
2657
2658 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2659
2660 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2661 setThreadBackgroundPriority();
2662
2663 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2664 // FIXME: Add a flag for modules.
2665 TranslationUnitKind TUKind
2666 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002667 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 = options & CXTranslationUnit_CacheCompletionResults;
2669 bool IncludeBriefCommentsInCodeCompletion
2670 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2671 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2672 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2673
2674 // Configure the diagnostics.
2675 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002676 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002677
2678 // Recover resources if we crash before exiting this function.
2679 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2680 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2681 DiagCleanup(Diags.getPtr());
2682
2683 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2684 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2685
2686 // Recover resources if we crash before exiting this function.
2687 llvm::CrashRecoveryContextCleanupRegistrar<
2688 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2689
2690 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2691 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2692 const llvm::MemoryBuffer *Buffer
2693 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2694 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2695 Buffer));
2696 }
2697
2698 OwningPtr<std::vector<const char *> >
2699 Args(new std::vector<const char*>());
2700
2701 // Recover resources if we crash before exiting this method.
2702 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2703 ArgsCleanup(Args.get());
2704
2705 // Since the Clang C library is primarily used by batch tools dealing with
2706 // (often very broken) source code, where spell-checking can have a
2707 // significant negative impact on performance (particularly when
2708 // precompiled headers are involved), we disable it by default.
2709 // Only do this if we haven't found a spell-checking-related argument.
2710 bool FoundSpellCheckingArgument = false;
2711 for (int I = 0; I != num_command_line_args; ++I) {
2712 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2713 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2714 FoundSpellCheckingArgument = true;
2715 break;
2716 }
2717 }
2718 if (!FoundSpellCheckingArgument)
2719 Args->push_back("-fno-spell-checking");
2720
2721 Args->insert(Args->end(), command_line_args,
2722 command_line_args + num_command_line_args);
2723
2724 // The 'source_filename' argument is optional. If the caller does not
2725 // specify it then it is assumed that the source file is specified
2726 // in the actual argument list.
2727 // Put the source file after command_line_args otherwise if '-x' flag is
2728 // present it will be unused.
2729 if (source_filename)
2730 Args->push_back(source_filename);
2731
2732 // Do we need the detailed preprocessing record?
2733 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2734 Args->push_back("-Xclang");
2735 Args->push_back("-detailed-preprocessing-record");
2736 }
2737
2738 unsigned NumErrors = Diags->getClient()->getNumErrors();
2739 OwningPtr<ASTUnit> ErrUnit;
2740 OwningPtr<ASTUnit> Unit(
2741 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2742 /* vector::data() not portable */,
2743 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2744 Diags,
2745 CXXIdx->getClangResourcesPath(),
2746 CXXIdx->getOnlyLocalDecls(),
2747 /*CaptureDiagnostics=*/true,
2748 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2749 RemappedFiles->size(),
2750 /*RemappedFilesKeepOriginalName=*/true,
2751 PrecompilePreamble,
2752 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002753 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 IncludeBriefCommentsInCodeCompletion,
2755 /*AllowPCHWithCompilerErrors=*/true,
2756 SkipFunctionBodies,
2757 /*UserFilesAreVolatile=*/true,
2758 ForSerialization,
2759 &ErrUnit));
2760
2761 if (NumErrors != Diags->getClient()->getNumErrors()) {
2762 // Make sure to check that 'Unit' is non-NULL.
2763 if (CXXIdx->getDisplayDiagnostics())
2764 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2765 }
2766
2767 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2768}
2769CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2770 const char *source_filename,
2771 const char * const *command_line_args,
2772 int num_command_line_args,
2773 struct CXUnsavedFile *unsaved_files,
2774 unsigned num_unsaved_files,
2775 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002776 LOG_FUNC_SECTION {
2777 *Log << source_filename << ": ";
2778 for (int i = 0; i != num_command_line_args; ++i)
2779 *Log << command_line_args[i] << " ";
2780 }
2781
Guy Benyei11169dd2012-12-18 14:30:41 +00002782 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2783 num_command_line_args, unsaved_files,
2784 num_unsaved_files, options, 0 };
2785 llvm::CrashRecoveryContext CRC;
2786
2787 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2788 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2789 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2790 fprintf(stderr, " 'command_line_args' : [");
2791 for (int i = 0; i != num_command_line_args; ++i) {
2792 if (i)
2793 fprintf(stderr, ", ");
2794 fprintf(stderr, "'%s'", command_line_args[i]);
2795 }
2796 fprintf(stderr, "],\n");
2797 fprintf(stderr, " 'unsaved_files' : [");
2798 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2799 if (i)
2800 fprintf(stderr, ", ");
2801 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2802 unsaved_files[i].Length);
2803 }
2804 fprintf(stderr, "],\n");
2805 fprintf(stderr, " 'options' : %d,\n", options);
2806 fprintf(stderr, "}\n");
2807
2808 return 0;
2809 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2810 PrintLibclangResourceUsage(PTUI.result);
2811 }
2812
2813 return PTUI.result;
2814}
2815
2816unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2817 return CXSaveTranslationUnit_None;
2818}
2819
2820namespace {
2821
2822struct SaveTranslationUnitInfo {
2823 CXTranslationUnit TU;
2824 const char *FileName;
2825 unsigned options;
2826 CXSaveError result;
2827};
2828
2829}
2830
2831static void clang_saveTranslationUnit_Impl(void *UserData) {
2832 SaveTranslationUnitInfo *STUI =
2833 static_cast<SaveTranslationUnitInfo*>(UserData);
2834
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002835 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002836 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2837 setThreadBackgroundPriority();
2838
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002839 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2841}
2842
2843int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2844 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002845 LOG_FUNC_SECTION {
2846 *Log << TU << ' ' << FileName;
2847 }
2848
Guy Benyei11169dd2012-12-18 14:30:41 +00002849 if (!TU)
2850 return CXSaveError_InvalidTU;
2851
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002852 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002853 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2854 if (!CXXUnit->hasSema())
2855 return CXSaveError_InvalidTU;
2856
2857 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2858
2859 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2860 getenv("LIBCLANG_NOTHREADS")) {
2861 clang_saveTranslationUnit_Impl(&STUI);
2862
2863 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2864 PrintLibclangResourceUsage(TU);
2865
2866 return STUI.result;
2867 }
2868
2869 // We have an AST that has invalid nodes due to compiler errors.
2870 // Use a crash recovery thread for protection.
2871
2872 llvm::CrashRecoveryContext CRC;
2873
2874 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2875 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2876 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2877 fprintf(stderr, " 'options' : %d,\n", options);
2878 fprintf(stderr, "}\n");
2879
2880 return CXSaveError_Unknown;
2881
2882 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2883 PrintLibclangResourceUsage(TU);
2884 }
2885
2886 return STUI.result;
2887}
2888
2889void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2890 if (CTUnit) {
2891 // If the translation unit has been marked as unsafe to free, just discard
2892 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002893 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002894 return;
2895
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002896 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002897 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2899 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002900 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 delete CTUnit;
2902 }
2903}
2904
2905unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2906 return CXReparse_None;
2907}
2908
2909struct ReparseTranslationUnitInfo {
2910 CXTranslationUnit TU;
2911 unsigned num_unsaved_files;
2912 struct CXUnsavedFile *unsaved_files;
2913 unsigned options;
2914 int result;
2915};
2916
2917static void clang_reparseTranslationUnit_Impl(void *UserData) {
2918 ReparseTranslationUnitInfo *RTUI =
2919 static_cast<ReparseTranslationUnitInfo*>(UserData);
2920 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002921 if (!TU)
2922 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002923
2924 // Reset the associated diagnostics.
2925 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2926 TU->Diagnostics = 0;
2927
2928 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2929 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2930 unsigned options = RTUI->options;
2931 (void) options;
2932 RTUI->result = 1;
2933
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002934 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002935 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2936 setThreadBackgroundPriority();
2937
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002938 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002939 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2940
2941 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2942 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2943
2944 // Recover resources if we crash before exiting this function.
2945 llvm::CrashRecoveryContextCleanupRegistrar<
2946 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2947
2948 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2949 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2950 const llvm::MemoryBuffer *Buffer
2951 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2952 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2953 Buffer));
2954 }
2955
2956 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2957 RemappedFiles->size()))
2958 RTUI->result = 0;
2959}
2960
2961int clang_reparseTranslationUnit(CXTranslationUnit TU,
2962 unsigned num_unsaved_files,
2963 struct CXUnsavedFile *unsaved_files,
2964 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002965 LOG_FUNC_SECTION {
2966 *Log << TU;
2967 }
2968
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2970 options, 0 };
2971
2972 if (getenv("LIBCLANG_NOTHREADS")) {
2973 clang_reparseTranslationUnit_Impl(&RTUI);
2974 return RTUI.result;
2975 }
2976
2977 llvm::CrashRecoveryContext CRC;
2978
2979 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2980 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002981 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 return 1;
2983 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2984 PrintLibclangResourceUsage(TU);
2985
2986 return RTUI.result;
2987}
2988
2989
2990CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2991 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002992 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00002993
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002994 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00002995 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00002996}
2997
2998CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00002999 if (!TU)
3000 return clang_getNullCursor();
3001
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003002 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3004}
3005
3006} // end: extern "C"
3007
3008//===----------------------------------------------------------------------===//
3009// CXFile Operations.
3010//===----------------------------------------------------------------------===//
3011
3012extern "C" {
3013CXString clang_getFileName(CXFile SFile) {
3014 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003015 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003016
3017 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003018 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003019}
3020
3021time_t clang_getFileTime(CXFile SFile) {
3022 if (!SFile)
3023 return 0;
3024
3025 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3026 return FEnt->getModificationTime();
3027}
3028
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003029CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3030 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003031 return 0;
3032
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003033 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003034
3035 FileManager &FMgr = CXXUnit->getFileManager();
3036 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3037}
3038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003039unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3040 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 return 0;
3042
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003043 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 FileEntry *FEnt = static_cast<FileEntry *>(file);
3045 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3046 .isFileMultipleIncludeGuarded(FEnt);
3047}
3048
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003049int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3050 if (!file || !outID)
3051 return 1;
3052
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003053 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003054 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3055 outID->data[0] = ID.getDevice();
3056 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003057 outID->data[2] = FEnt->getModificationTime();
3058 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003059}
3060
Guy Benyei11169dd2012-12-18 14:30:41 +00003061} // end: extern "C"
3062
3063//===----------------------------------------------------------------------===//
3064// CXCursor Operations.
3065//===----------------------------------------------------------------------===//
3066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003067static const Decl *getDeclFromExpr(const Stmt *E) {
3068 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 return getDeclFromExpr(CE->getSubExpr());
3070
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003071 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003073 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003075 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003077 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 if (PRE->isExplicitProperty())
3079 return PRE->getExplicitProperty();
3080 // It could be messaging both getter and setter as in:
3081 // ++myobj.myprop;
3082 // in which case prefer to associate the setter since it is less obvious
3083 // from inspecting the source that the setter is going to get called.
3084 if (PRE->isMessagingSetter())
3085 return PRE->getImplicitPropertySetter();
3086 return PRE->getImplicitPropertyGetter();
3087 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003088 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003090 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003091 if (Expr *Src = OVE->getSourceExpr())
3092 return getDeclFromExpr(Src);
3093
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003094 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003096 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 if (!CE->isElidable())
3098 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003099 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 return OME->getMethodDecl();
3101
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003102 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003104 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3106 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003107 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3109 isa<ParmVarDecl>(SizeOfPack->getPack()))
3110 return SizeOfPack->getPack();
3111
3112 return 0;
3113}
3114
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003115static SourceLocation getLocationFromExpr(const Expr *E) {
3116 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 return getLocationFromExpr(CE->getSubExpr());
3118
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003119 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003121 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003123 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003125 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003127 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003129 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 return PropRef->getLocation();
3131
3132 return E->getLocStart();
3133}
3134
3135extern "C" {
3136
3137unsigned clang_visitChildren(CXCursor parent,
3138 CXCursorVisitor visitor,
3139 CXClientData client_data) {
3140 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3141 /*VisitPreprocessorLast=*/false);
3142 return CursorVis.VisitChildren(parent);
3143}
3144
3145#ifndef __has_feature
3146#define __has_feature(x) 0
3147#endif
3148#if __has_feature(blocks)
3149typedef enum CXChildVisitResult
3150 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3151
3152static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3153 CXClientData client_data) {
3154 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3155 return block(cursor, parent);
3156}
3157#else
3158// If we are compiled with a compiler that doesn't have native blocks support,
3159// define and call the block manually, so the
3160typedef struct _CXChildVisitResult
3161{
3162 void *isa;
3163 int flags;
3164 int reserved;
3165 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3166 CXCursor);
3167} *CXCursorVisitorBlock;
3168
3169static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3170 CXClientData client_data) {
3171 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3172 return block->invoke(block, cursor, parent);
3173}
3174#endif
3175
3176
3177unsigned clang_visitChildrenWithBlock(CXCursor parent,
3178 CXCursorVisitorBlock block) {
3179 return clang_visitChildren(parent, visitWithBlock, block);
3180}
3181
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003184 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003185
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const ObjCPropertyImplDecl *PropImpl =
3189 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003191 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003195 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003196
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003197 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 }
3199
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003201 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3205 // and returns different names. NamedDecl returns the class name and
3206 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003207 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
3209 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003210 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003211
3212 SmallString<1024> S;
3213 llvm::raw_svector_ostream os(S);
3214 ND->printName(os);
3215
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003216 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003217}
3218
3219CXString clang_getCursorSpelling(CXCursor C) {
3220 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003221 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003222
3223 if (clang_isReference(C.kind)) {
3224 switch (C.kind) {
3225 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003226 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003227 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 }
3229 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003230 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003231 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 }
3233 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003234 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003236 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 }
3238 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003239 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003240 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 }
3242 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003243 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 assert(Type && "Missing type decl");
3245
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003246 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 getAsString());
3248 }
3249 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003250 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 assert(Template && "Missing template decl");
3252
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003253 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 }
3255
3256 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003257 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 assert(NS && "Missing namespace decl");
3259
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003260 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 }
3262
3263 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003264 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 assert(Field && "Missing member decl");
3266
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003267 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 }
3269
3270 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003271 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 assert(Label && "Missing label");
3273
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003274 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 }
3276
3277 case CXCursor_OverloadedDeclRef: {
3278 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003279 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3280 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003281 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003282 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003285 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 OverloadedTemplateStorage *Ovl
3287 = Storage.get<OverloadedTemplateStorage*>();
3288 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003289 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 }
3292
3293 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003294 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 assert(Var && "Missing variable decl");
3296
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003297 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 }
3299
3300 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003301 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 }
3303 }
3304
3305 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003306 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 if (D)
3308 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003309 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 }
3311
3312 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003313 const Stmt *S = getCursorStmt(C);
3314 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003315 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003316
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003317 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 }
3319
3320 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 ->getNameStart());
3323
3324 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003325 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 ->getNameStart());
3327
3328 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003329 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003330
3331 if (clang_isDeclaration(C.kind))
3332 return getDeclSpelling(getCursorDecl(C));
3333
3334 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003335 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003336 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 }
3338
3339 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003340 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
3343
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003344 if (C.kind == CXCursor_PackedAttr) {
3345 return cxstring::createRef("packed");
3346 }
3347
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003348 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003349}
3350
3351CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3352 unsigned pieceIndex,
3353 unsigned options) {
3354 if (clang_Cursor_isNull(C))
3355 return clang_getNullRange();
3356
3357 ASTContext &Ctx = getCursorContext(C);
3358
3359 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003360 const Stmt *S = getCursorStmt(C);
3361 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 if (pieceIndex > 0)
3363 return clang_getNullRange();
3364 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3365 }
3366
3367 return clang_getNullRange();
3368 }
3369
3370 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003371 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3373 if (pieceIndex >= ME->getNumSelectorLocs())
3374 return clang_getNullRange();
3375 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3376 }
3377 }
3378
3379 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3380 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003381 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3383 if (pieceIndex >= MD->getNumSelectorLocs())
3384 return clang_getNullRange();
3385 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3386 }
3387 }
3388
3389 if (C.kind == CXCursor_ObjCCategoryDecl ||
3390 C.kind == CXCursor_ObjCCategoryImplDecl) {
3391 if (pieceIndex > 0)
3392 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3395 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3398 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3399 }
3400
3401 if (C.kind == CXCursor_ModuleImportDecl) {
3402 if (pieceIndex > 0)
3403 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 if (const ImportDecl *ImportD =
3405 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3407 if (!Locs.empty())
3408 return cxloc::translateSourceRange(Ctx,
3409 SourceRange(Locs.front(), Locs.back()));
3410 }
3411 return clang_getNullRange();
3412 }
3413
3414 // FIXME: A CXCursor_InclusionDirective should give the location of the
3415 // filename, but we don't keep track of this.
3416
3417 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3418 // but we don't keep track of this.
3419
3420 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3421 // but we don't keep track of this.
3422
3423 // Default handling, give the location of the cursor.
3424
3425 if (pieceIndex > 0)
3426 return clang_getNullRange();
3427
3428 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3429 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3430 return cxloc::translateSourceRange(Ctx, Loc);
3431}
3432
3433CXString clang_getCursorDisplayName(CXCursor C) {
3434 if (!clang_isDeclaration(C.kind))
3435 return clang_getCursorSpelling(C);
3436
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003437 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003439 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003440
3441 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003442 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 D = FunTmpl->getTemplatedDecl();
3444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003445 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 SmallString<64> Str;
3447 llvm::raw_svector_ostream OS(Str);
3448 OS << *Function;
3449 if (Function->getPrimaryTemplate())
3450 OS << "<>";
3451 OS << "(";
3452 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3453 if (I)
3454 OS << ", ";
3455 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3456 }
3457
3458 if (Function->isVariadic()) {
3459 if (Function->getNumParams())
3460 OS << ", ";
3461 OS << "...";
3462 }
3463 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003464 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 }
3466
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003467 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 SmallString<64> Str;
3469 llvm::raw_svector_ostream OS(Str);
3470 OS << *ClassTemplate;
3471 OS << "<";
3472 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3473 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3474 if (I)
3475 OS << ", ";
3476
3477 NamedDecl *Param = Params->getParam(I);
3478 if (Param->getIdentifier()) {
3479 OS << Param->getIdentifier()->getName();
3480 continue;
3481 }
3482
3483 // There is no parameter name, which makes this tricky. Try to come up
3484 // with something useful that isn't too long.
3485 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3486 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3487 else if (NonTypeTemplateParmDecl *NTTP
3488 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3489 OS << NTTP->getType().getAsString(Policy);
3490 else
3491 OS << "template<...> class";
3492 }
3493
3494 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003495 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 }
3497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3500 // If the type was explicitly written, use that.
3501 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003502 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003503
Benjamin Kramer9170e912013-02-22 15:46:01 +00003504 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 llvm::raw_svector_ostream OS(Str);
3506 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003507 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 ClassSpec->getTemplateArgs().data(),
3509 ClassSpec->getTemplateArgs().size(),
3510 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003511 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 }
3513
3514 return clang_getCursorSpelling(C);
3515}
3516
3517CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3518 switch (Kind) {
3519 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003520 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003522 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003524 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003528 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003530 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003536 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003540 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003546 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003564 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003568 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003572 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003576 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003580 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003586 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003588 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003592 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003596 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003598 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003600 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003604 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003606 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003608 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003647 case CXCursor_ObjCSelfExpr:
3648 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003765 case CXCursor_PackedAttr:
3766 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003815 case CXCursor_OMPParallelDirective:
3816 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 }
3818
3819 llvm_unreachable("Unhandled CXCursorKind");
3820}
3821
3822struct GetCursorData {
3823 SourceLocation TokenBeginLoc;
3824 bool PointsAtMacroArgExpansion;
3825 bool VisitedObjCPropertyImplDecl;
3826 SourceLocation VisitedDeclaratorDeclStartLoc;
3827 CXCursor &BestCursor;
3828
3829 GetCursorData(SourceManager &SM,
3830 SourceLocation tokenBegin, CXCursor &outputCursor)
3831 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3832 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3833 VisitedObjCPropertyImplDecl = false;
3834 }
3835};
3836
3837static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3838 CXCursor parent,
3839 CXClientData client_data) {
3840 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3841 CXCursor *BestCursor = &Data->BestCursor;
3842
3843 // If we point inside a macro argument we should provide info of what the
3844 // token is so use the actual cursor, don't replace it with a macro expansion
3845 // cursor.
3846 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3847 return CXChildVisit_Recurse;
3848
3849 if (clang_isDeclaration(cursor.kind)) {
3850 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003851 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3853 if (MD->isImplicit())
3854 return CXChildVisit_Break;
3855
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003856 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3858 // Check that when we have multiple @class references in the same line,
3859 // that later ones do not override the previous ones.
3860 // If we have:
3861 // @class Foo, Bar;
3862 // source ranges for both start at '@', so 'Bar' will end up overriding
3863 // 'Foo' even though the cursor location was at 'Foo'.
3864 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3865 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003866 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3868 if (PrevID != ID &&
3869 !PrevID->isThisDeclarationADefinition() &&
3870 !ID->isThisDeclarationADefinition())
3871 return CXChildVisit_Break;
3872 }
3873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003874 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3876 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3877 // Check that when we have multiple declarators in the same line,
3878 // that later ones do not override the previous ones.
3879 // If we have:
3880 // int Foo, Bar;
3881 // source ranges for both start at 'int', so 'Bar' will end up overriding
3882 // 'Foo' even though the cursor location was at 'Foo'.
3883 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3884 return CXChildVisit_Break;
3885 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3886
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003887 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3889 (void)PropImp;
3890 // Check that when we have multiple @synthesize in the same line,
3891 // that later ones do not override the previous ones.
3892 // If we have:
3893 // @synthesize Foo, Bar;
3894 // source ranges for both start at '@', so 'Bar' will end up overriding
3895 // 'Foo' even though the cursor location was at 'Foo'.
3896 if (Data->VisitedObjCPropertyImplDecl)
3897 return CXChildVisit_Break;
3898 Data->VisitedObjCPropertyImplDecl = true;
3899 }
3900 }
3901
3902 if (clang_isExpression(cursor.kind) &&
3903 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003904 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 // Avoid having the cursor of an expression replace the declaration cursor
3906 // when the expression source range overlaps the declaration range.
3907 // This can happen for C++ constructor expressions whose range generally
3908 // include the variable declaration, e.g.:
3909 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3910 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3911 D->getLocation() == Data->TokenBeginLoc)
3912 return CXChildVisit_Break;
3913 }
3914 }
3915
3916 // If our current best cursor is the construction of a temporary object,
3917 // don't replace that cursor with a type reference, because we want
3918 // clang_getCursor() to point at the constructor.
3919 if (clang_isExpression(BestCursor->kind) &&
3920 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3921 cursor.kind == CXCursor_TypeRef) {
3922 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3923 // as having the actual point on the type reference.
3924 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3925 return CXChildVisit_Recurse;
3926 }
3927
3928 *BestCursor = cursor;
3929 return CXChildVisit_Recurse;
3930}
3931
3932CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3933 if (!TU)
3934 return clang_getNullCursor();
3935
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003936 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3938
3939 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3940 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3941
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003942 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 CXFile SearchFile;
3944 unsigned SearchLine, SearchColumn;
3945 CXFile ResultFile;
3946 unsigned ResultLine, ResultColumn;
3947 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3948 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3949 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3950
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003951 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3952 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 &ResultColumn, 0);
3954 SearchFileName = clang_getFileName(SearchFile);
3955 ResultFileName = clang_getFileName(ResultFile);
3956 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3957 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003958 *Log << llvm::format("(%s:%d:%d) = %s",
3959 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3960 clang_getCString(KindSpelling))
3961 << llvm::format("(%s:%d:%d):%s%s",
3962 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3963 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 clang_disposeString(SearchFileName);
3965 clang_disposeString(ResultFileName);
3966 clang_disposeString(KindSpelling);
3967 clang_disposeString(USR);
3968
3969 CXCursor Definition = clang_getCursorDefinition(Result);
3970 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3971 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3972 CXString DefinitionKindSpelling
3973 = clang_getCursorKindSpelling(Definition.kind);
3974 CXFile DefinitionFile;
3975 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003976 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 &DefinitionLine, &DefinitionColumn, 0);
3978 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003979 *Log << llvm::format(" -> %s(%s:%d:%d)",
3980 clang_getCString(DefinitionKindSpelling),
3981 clang_getCString(DefinitionFileName),
3982 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 clang_disposeString(DefinitionFileName);
3984 clang_disposeString(DefinitionKindSpelling);
3985 }
3986 }
3987
3988 return Result;
3989}
3990
3991CXCursor clang_getNullCursor(void) {
3992 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3993}
3994
3995unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00003996 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3997 // can't set consistently. For example, when visiting a DeclStmt we will set
3998 // it but we don't set it on the result of clang_getCursorDefinition for
3999 // a reference of the same declaration.
4000 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4001 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4002 // to provide that kind of info.
4003 if (clang_isDeclaration(X.kind))
4004 X.data[1] = 0;
4005 if (clang_isDeclaration(Y.kind))
4006 Y.data[1] = 0;
4007
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 return X == Y;
4009}
4010
4011unsigned clang_hashCursor(CXCursor C) {
4012 unsigned Index = 0;
4013 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4014 Index = 1;
4015
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004016 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 std::make_pair(C.kind, C.data[Index]));
4018}
4019
4020unsigned clang_isInvalid(enum CXCursorKind K) {
4021 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4022}
4023
4024unsigned clang_isDeclaration(enum CXCursorKind K) {
4025 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4026 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4027}
4028
4029unsigned clang_isReference(enum CXCursorKind K) {
4030 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4031}
4032
4033unsigned clang_isExpression(enum CXCursorKind K) {
4034 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4035}
4036
4037unsigned clang_isStatement(enum CXCursorKind K) {
4038 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4039}
4040
4041unsigned clang_isAttribute(enum CXCursorKind K) {
4042 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4043}
4044
4045unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4046 return K == CXCursor_TranslationUnit;
4047}
4048
4049unsigned clang_isPreprocessing(enum CXCursorKind K) {
4050 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4051}
4052
4053unsigned clang_isUnexposed(enum CXCursorKind K) {
4054 switch (K) {
4055 case CXCursor_UnexposedDecl:
4056 case CXCursor_UnexposedExpr:
4057 case CXCursor_UnexposedStmt:
4058 case CXCursor_UnexposedAttr:
4059 return true;
4060 default:
4061 return false;
4062 }
4063}
4064
4065CXCursorKind clang_getCursorKind(CXCursor C) {
4066 return C.kind;
4067}
4068
4069CXSourceLocation clang_getCursorLocation(CXCursor C) {
4070 if (clang_isReference(C.kind)) {
4071 switch (C.kind) {
4072 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004073 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 = getCursorObjCSuperClassRef(C);
4075 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4076 }
4077
4078 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004079 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 = getCursorObjCProtocolRef(C);
4081 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4082 }
4083
4084 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004085 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 = getCursorObjCClassRef(C);
4087 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4088 }
4089
4090 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004091 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4093 }
4094
4095 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004096 std::pair<const TemplateDecl *, SourceLocation> P =
4097 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4104 }
4105
4106 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004107 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4109 }
4110
4111 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004112 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4114 }
4115
4116 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004117 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 if (!BaseSpec)
4119 return clang_getNullLocation();
4120
4121 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4122 return cxloc::translateSourceLocation(getCursorContext(C),
4123 TSInfo->getTypeLoc().getBeginLoc());
4124
4125 return cxloc::translateSourceLocation(getCursorContext(C),
4126 BaseSpec->getLocStart());
4127 }
4128
4129 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004130 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4132 }
4133
4134 case CXCursor_OverloadedDeclRef:
4135 return cxloc::translateSourceLocation(getCursorContext(C),
4136 getCursorOverloadedDeclRef(C).second);
4137
4138 default:
4139 // FIXME: Need a way to enumerate all non-reference cases.
4140 llvm_unreachable("Missed a reference kind");
4141 }
4142 }
4143
4144 if (clang_isExpression(C.kind))
4145 return cxloc::translateSourceLocation(getCursorContext(C),
4146 getLocationFromExpr(getCursorExpr(C)));
4147
4148 if (clang_isStatement(C.kind))
4149 return cxloc::translateSourceLocation(getCursorContext(C),
4150 getCursorStmt(C)->getLocStart());
4151
4152 if (C.kind == CXCursor_PreprocessingDirective) {
4153 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4154 return cxloc::translateSourceLocation(getCursorContext(C), L);
4155 }
4156
4157 if (C.kind == CXCursor_MacroExpansion) {
4158 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004159 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 return cxloc::translateSourceLocation(getCursorContext(C), L);
4161 }
4162
4163 if (C.kind == CXCursor_MacroDefinition) {
4164 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4165 return cxloc::translateSourceLocation(getCursorContext(C), L);
4166 }
4167
4168 if (C.kind == CXCursor_InclusionDirective) {
4169 SourceLocation L
4170 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004174 if (clang_isAttribute(C.kind)) {
4175 SourceLocation L
4176 = cxcursor::getCursorAttr(C)->getLocation();
4177 return cxloc::translateSourceLocation(getCursorContext(C), L);
4178 }
4179
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 if (!clang_isDeclaration(C.kind))
4181 return clang_getNullLocation();
4182
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004183 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 if (!D)
4185 return clang_getNullLocation();
4186
4187 SourceLocation Loc = D->getLocation();
4188 // FIXME: Multiple variables declared in a single declaration
4189 // currently lack the information needed to correctly determine their
4190 // ranges when accounting for the type-specifier. We use context
4191 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4192 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004193 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 if (!cxcursor::isFirstInDeclGroup(C))
4195 Loc = VD->getLocation();
4196 }
4197
4198 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004199 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 Loc = MD->getSelectorStartLoc();
4201
4202 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4203}
4204
4205} // end extern "C"
4206
4207CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4208 assert(TU);
4209
4210 // Guard against an invalid SourceLocation, or we may assert in one
4211 // of the following calls.
4212 if (SLoc.isInvalid())
4213 return clang_getNullCursor();
4214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216
4217 // Translate the given source location to make it point at the beginning of
4218 // the token under the cursor.
4219 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4220 CXXUnit->getASTContext().getLangOpts());
4221
4222 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4223 if (SLoc.isValid()) {
4224 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4225 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4226 /*VisitPreprocessorLast=*/true,
4227 /*VisitIncludedEntities=*/false,
4228 SourceLocation(SLoc));
4229 CursorVis.visitFileRegion();
4230 }
4231
4232 return Result;
4233}
4234
4235static SourceRange getRawCursorExtent(CXCursor C) {
4236 if (clang_isReference(C.kind)) {
4237 switch (C.kind) {
4238 case CXCursor_ObjCSuperClassRef:
4239 return getCursorObjCSuperClassRef(C).second;
4240
4241 case CXCursor_ObjCProtocolRef:
4242 return getCursorObjCProtocolRef(C).second;
4243
4244 case CXCursor_ObjCClassRef:
4245 return getCursorObjCClassRef(C).second;
4246
4247 case CXCursor_TypeRef:
4248 return getCursorTypeRef(C).second;
4249
4250 case CXCursor_TemplateRef:
4251 return getCursorTemplateRef(C).second;
4252
4253 case CXCursor_NamespaceRef:
4254 return getCursorNamespaceRef(C).second;
4255
4256 case CXCursor_MemberRef:
4257 return getCursorMemberRef(C).second;
4258
4259 case CXCursor_CXXBaseSpecifier:
4260 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4261
4262 case CXCursor_LabelRef:
4263 return getCursorLabelRef(C).second;
4264
4265 case CXCursor_OverloadedDeclRef:
4266 return getCursorOverloadedDeclRef(C).second;
4267
4268 case CXCursor_VariableRef:
4269 return getCursorVariableRef(C).second;
4270
4271 default:
4272 // FIXME: Need a way to enumerate all non-reference cases.
4273 llvm_unreachable("Missed a reference kind");
4274 }
4275 }
4276
4277 if (clang_isExpression(C.kind))
4278 return getCursorExpr(C)->getSourceRange();
4279
4280 if (clang_isStatement(C.kind))
4281 return getCursorStmt(C)->getSourceRange();
4282
4283 if (clang_isAttribute(C.kind))
4284 return getCursorAttr(C)->getRange();
4285
4286 if (C.kind == CXCursor_PreprocessingDirective)
4287 return cxcursor::getCursorPreprocessingDirective(C);
4288
4289 if (C.kind == CXCursor_MacroExpansion) {
4290 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004291 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 return TU->mapRangeFromPreamble(Range);
4293 }
4294
4295 if (C.kind == CXCursor_MacroDefinition) {
4296 ASTUnit *TU = getCursorASTUnit(C);
4297 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4298 return TU->mapRangeFromPreamble(Range);
4299 }
4300
4301 if (C.kind == CXCursor_InclusionDirective) {
4302 ASTUnit *TU = getCursorASTUnit(C);
4303 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4304 return TU->mapRangeFromPreamble(Range);
4305 }
4306
4307 if (C.kind == CXCursor_TranslationUnit) {
4308 ASTUnit *TU = getCursorASTUnit(C);
4309 FileID MainID = TU->getSourceManager().getMainFileID();
4310 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4311 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4312 return SourceRange(Start, End);
4313 }
4314
4315 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004316 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 if (!D)
4318 return SourceRange();
4319
4320 SourceRange R = D->getSourceRange();
4321 // FIXME: Multiple variables declared in a single declaration
4322 // currently lack the information needed to correctly determine their
4323 // ranges when accounting for the type-specifier. We use context
4324 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4325 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004326 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 if (!cxcursor::isFirstInDeclGroup(C))
4328 R.setBegin(VD->getLocation());
4329 }
4330 return R;
4331 }
4332 return SourceRange();
4333}
4334
4335/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4336/// the decl-specifier-seq for declarations.
4337static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4338 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004339 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 if (!D)
4341 return SourceRange();
4342
4343 SourceRange R = D->getSourceRange();
4344
4345 // Adjust the start of the location for declarations preceded by
4346 // declaration specifiers.
4347 SourceLocation StartLoc;
4348 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4349 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4350 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004351 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4353 StartLoc = TI->getTypeLoc().getLocStart();
4354 }
4355
4356 if (StartLoc.isValid() && R.getBegin().isValid() &&
4357 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4358 R.setBegin(StartLoc);
4359
4360 // FIXME: Multiple variables declared in a single declaration
4361 // currently lack the information needed to correctly determine their
4362 // ranges when accounting for the type-specifier. We use context
4363 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4364 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004365 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 if (!cxcursor::isFirstInDeclGroup(C))
4367 R.setBegin(VD->getLocation());
4368 }
4369
4370 return R;
4371 }
4372
4373 return getRawCursorExtent(C);
4374}
4375
4376extern "C" {
4377
4378CXSourceRange clang_getCursorExtent(CXCursor C) {
4379 SourceRange R = getRawCursorExtent(C);
4380 if (R.isInvalid())
4381 return clang_getNullRange();
4382
4383 return cxloc::translateSourceRange(getCursorContext(C), R);
4384}
4385
4386CXCursor clang_getCursorReferenced(CXCursor C) {
4387 if (clang_isInvalid(C.kind))
4388 return clang_getNullCursor();
4389
4390 CXTranslationUnit tu = getCursorTU(C);
4391 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004392 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 if (!D)
4394 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004395 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004397 if (const ObjCPropertyImplDecl *PropImpl =
4398 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4400 return MakeCXCursor(Property, tu);
4401
4402 return C;
4403 }
4404
4405 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 const Expr *E = getCursorExpr(C);
4407 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 if (D) {
4409 CXCursor declCursor = MakeCXCursor(D, tu);
4410 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4411 declCursor);
4412 return declCursor;
4413 }
4414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004415 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 return MakeCursorOverloadedDeclRef(Ovl, tu);
4417
4418 return clang_getNullCursor();
4419 }
4420
4421 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004422 const Stmt *S = getCursorStmt(C);
4423 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 if (LabelDecl *label = Goto->getLabel())
4425 if (LabelStmt *labelS = label->getStmt())
4426 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4427
4428 return clang_getNullCursor();
4429 }
4430
4431 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004432 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 return MakeMacroDefinitionCursor(Def, tu);
4434 }
4435
4436 if (!clang_isReference(C.kind))
4437 return clang_getNullCursor();
4438
4439 switch (C.kind) {
4440 case CXCursor_ObjCSuperClassRef:
4441 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4442
4443 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004444 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4445 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 return MakeCXCursor(Def, tu);
4447
4448 return MakeCXCursor(Prot, tu);
4449 }
4450
4451 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004452 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4453 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 return MakeCXCursor(Def, tu);
4455
4456 return MakeCXCursor(Class, tu);
4457 }
4458
4459 case CXCursor_TypeRef:
4460 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4461
4462 case CXCursor_TemplateRef:
4463 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4464
4465 case CXCursor_NamespaceRef:
4466 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4467
4468 case CXCursor_MemberRef:
4469 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4470
4471 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004472 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4474 tu ));
4475 }
4476
4477 case CXCursor_LabelRef:
4478 // FIXME: We end up faking the "parent" declaration here because we
4479 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004480 return MakeCXCursor(getCursorLabelRef(C).first,
4481 cxtu::getASTUnit(tu)->getASTContext()
4482 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 tu);
4484
4485 case CXCursor_OverloadedDeclRef:
4486 return C;
4487
4488 case CXCursor_VariableRef:
4489 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4490
4491 default:
4492 // We would prefer to enumerate all non-reference cursor kinds here.
4493 llvm_unreachable("Unhandled reference cursor kind");
4494 }
4495}
4496
4497CXCursor clang_getCursorDefinition(CXCursor C) {
4498 if (clang_isInvalid(C.kind))
4499 return clang_getNullCursor();
4500
4501 CXTranslationUnit TU = getCursorTU(C);
4502
4503 bool WasReference = false;
4504 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4505 C = clang_getCursorReferenced(C);
4506 WasReference = true;
4507 }
4508
4509 if (C.kind == CXCursor_MacroExpansion)
4510 return clang_getCursorReferenced(C);
4511
4512 if (!clang_isDeclaration(C.kind))
4513 return clang_getNullCursor();
4514
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004515 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 if (!D)
4517 return clang_getNullCursor();
4518
4519 switch (D->getKind()) {
4520 // Declaration kinds that don't really separate the notions of
4521 // declaration and definition.
4522 case Decl::Namespace:
4523 case Decl::Typedef:
4524 case Decl::TypeAlias:
4525 case Decl::TypeAliasTemplate:
4526 case Decl::TemplateTypeParm:
4527 case Decl::EnumConstant:
4528 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004529 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 case Decl::IndirectField:
4531 case Decl::ObjCIvar:
4532 case Decl::ObjCAtDefsField:
4533 case Decl::ImplicitParam:
4534 case Decl::ParmVar:
4535 case Decl::NonTypeTemplateParm:
4536 case Decl::TemplateTemplateParm:
4537 case Decl::ObjCCategoryImpl:
4538 case Decl::ObjCImplementation:
4539 case Decl::AccessSpec:
4540 case Decl::LinkageSpec:
4541 case Decl::ObjCPropertyImpl:
4542 case Decl::FileScopeAsm:
4543 case Decl::StaticAssert:
4544 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004545 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 case Decl::Label: // FIXME: Is this right??
4547 case Decl::ClassScopeFunctionSpecialization:
4548 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004549 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 return C;
4551
4552 // Declaration kinds that don't make any sense here, but are
4553 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004554 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case Decl::TranslationUnit:
4556 break;
4557
4558 // Declaration kinds for which the definition is not resolvable.
4559 case Decl::UnresolvedUsingTypename:
4560 case Decl::UnresolvedUsingValue:
4561 break;
4562
4563 case Decl::UsingDirective:
4564 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4565 TU);
4566
4567 case Decl::NamespaceAlias:
4568 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4569
4570 case Decl::Enum:
4571 case Decl::Record:
4572 case Decl::CXXRecord:
4573 case Decl::ClassTemplateSpecialization:
4574 case Decl::ClassTemplatePartialSpecialization:
4575 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4576 return MakeCXCursor(Def, TU);
4577 return clang_getNullCursor();
4578
4579 case Decl::Function:
4580 case Decl::CXXMethod:
4581 case Decl::CXXConstructor:
4582 case Decl::CXXDestructor:
4583 case Decl::CXXConversion: {
4584 const FunctionDecl *Def = 0;
4585 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004586 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 return clang_getNullCursor();
4588 }
4589
Larisse Voufo39a1e502013-08-06 01:03:05 +00004590 case Decl::Var:
4591 case Decl::VarTemplateSpecialization:
4592 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 return MakeCXCursor(Def, TU);
4596 return clang_getNullCursor();
4597 }
4598
4599 case Decl::FunctionTemplate: {
4600 const FunctionDecl *Def = 0;
4601 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4602 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4603 return clang_getNullCursor();
4604 }
4605
4606 case Decl::ClassTemplate: {
4607 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4608 ->getDefinition())
4609 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4610 TU);
4611 return clang_getNullCursor();
4612 }
4613
Larisse Voufo39a1e502013-08-06 01:03:05 +00004614 case Decl::VarTemplate: {
4615 if (VarDecl *Def =
4616 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4617 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4618 return clang_getNullCursor();
4619 }
4620
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case Decl::Using:
4622 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4623 D->getLocation(), TU);
4624
4625 case Decl::UsingShadow:
4626 return clang_getCursorDefinition(
4627 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4628 TU));
4629
4630 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004631 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 if (Method->isThisDeclarationADefinition())
4633 return C;
4634
4635 // Dig out the method definition in the associated
4636 // @implementation, if we have it.
4637 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004638 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4640 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4641 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4642 Method->isInstanceMethod()))
4643 if (Def->isThisDeclarationADefinition())
4644 return MakeCXCursor(Def, TU);
4645
4646 return clang_getNullCursor();
4647 }
4648
4649 case Decl::ObjCCategory:
4650 if (ObjCCategoryImplDecl *Impl
4651 = cast<ObjCCategoryDecl>(D)->getImplementation())
4652 return MakeCXCursor(Impl, TU);
4653 return clang_getNullCursor();
4654
4655 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004656 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 return MakeCXCursor(Def, TU);
4658 return clang_getNullCursor();
4659
4660 case Decl::ObjCInterface: {
4661 // There are two notions of a "definition" for an Objective-C
4662 // class: the interface and its implementation. When we resolved a
4663 // reference to an Objective-C class, produce the @interface as
4664 // the definition; when we were provided with the interface,
4665 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004666 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004668 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 return MakeCXCursor(Def, TU);
4670 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4671 return MakeCXCursor(Impl, TU);
4672 return clang_getNullCursor();
4673 }
4674
4675 case Decl::ObjCProperty:
4676 // FIXME: We don't really know where to find the
4677 // ObjCPropertyImplDecls that implement this property.
4678 return clang_getNullCursor();
4679
4680 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004681 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004683 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 return MakeCXCursor(Def, TU);
4685
4686 return clang_getNullCursor();
4687
4688 case Decl::Friend:
4689 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4690 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4691 return clang_getNullCursor();
4692
4693 case Decl::FriendTemplate:
4694 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4695 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4696 return clang_getNullCursor();
4697 }
4698
4699 return clang_getNullCursor();
4700}
4701
4702unsigned clang_isCursorDefinition(CXCursor C) {
4703 if (!clang_isDeclaration(C.kind))
4704 return 0;
4705
4706 return clang_getCursorDefinition(C) == C;
4707}
4708
4709CXCursor clang_getCanonicalCursor(CXCursor C) {
4710 if (!clang_isDeclaration(C.kind))
4711 return C;
4712
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004713 if (const Decl *D = getCursorDecl(C)) {
4714 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4716 return MakeCXCursor(CatD, getCursorTU(C));
4717
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004718 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4719 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 return MakeCXCursor(IFD, getCursorTU(C));
4721
4722 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4723 }
4724
4725 return C;
4726}
4727
4728int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4729 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4730}
4731
4732unsigned clang_getNumOverloadedDecls(CXCursor C) {
4733 if (C.kind != CXCursor_OverloadedDeclRef)
4734 return 0;
4735
4736 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 return E->getNumDecls();
4739
4740 if (OverloadedTemplateStorage *S
4741 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4742 return S->size();
4743
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 const Decl *D = Storage.get<const Decl *>();
4745 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 return Using->shadow_size();
4747
4748 return 0;
4749}
4750
4751CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4752 if (cursor.kind != CXCursor_OverloadedDeclRef)
4753 return clang_getNullCursor();
4754
4755 if (index >= clang_getNumOverloadedDecls(cursor))
4756 return clang_getNullCursor();
4757
4758 CXTranslationUnit TU = getCursorTU(cursor);
4759 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004760 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return MakeCXCursor(E->decls_begin()[index], TU);
4762
4763 if (OverloadedTemplateStorage *S
4764 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4765 return MakeCXCursor(S->begin()[index], TU);
4766
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004767 const Decl *D = Storage.get<const Decl *>();
4768 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 // FIXME: This is, unfortunately, linear time.
4770 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4771 std::advance(Pos, index);
4772 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4773 }
4774
4775 return clang_getNullCursor();
4776}
4777
4778void clang_getDefinitionSpellingAndExtent(CXCursor C,
4779 const char **startBuf,
4780 const char **endBuf,
4781 unsigned *startLine,
4782 unsigned *startColumn,
4783 unsigned *endLine,
4784 unsigned *endColumn) {
4785 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4788
4789 SourceManager &SM = FD->getASTContext().getSourceManager();
4790 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4791 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4792 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4793 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4794 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4795 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4796}
4797
4798
4799CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4800 unsigned PieceIndex) {
4801 RefNamePieces Pieces;
4802
4803 switch (C.kind) {
4804 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004805 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4807 E->getQualifierLoc().getSourceRange());
4808 break;
4809
4810 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004811 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4813 E->getQualifierLoc().getSourceRange(),
4814 E->getOptionalExplicitTemplateArgs());
4815 break;
4816
4817 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004818 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004820 const Expr *Callee = OCE->getCallee();
4821 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 Callee = ICE->getSubExpr();
4823
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004824 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4826 DRE->getQualifierLoc().getSourceRange());
4827 }
4828 break;
4829
4830 default:
4831 break;
4832 }
4833
4834 if (Pieces.empty()) {
4835 if (PieceIndex == 0)
4836 return clang_getCursorExtent(C);
4837 } else if (PieceIndex < Pieces.size()) {
4838 SourceRange R = Pieces[PieceIndex];
4839 if (R.isValid())
4840 return cxloc::translateSourceRange(getCursorContext(C), R);
4841 }
4842
4843 return clang_getNullRange();
4844}
4845
4846void clang_enableStackTraces(void) {
4847 llvm::sys::PrintStackTraceOnErrorSignal();
4848}
4849
4850void clang_executeOnThread(void (*fn)(void*), void *user_data,
4851 unsigned stack_size) {
4852 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4853}
4854
4855} // end: extern "C"
4856
4857//===----------------------------------------------------------------------===//
4858// Token-based Operations.
4859//===----------------------------------------------------------------------===//
4860
4861/* CXToken layout:
4862 * int_data[0]: a CXTokenKind
4863 * int_data[1]: starting token location
4864 * int_data[2]: token length
4865 * int_data[3]: reserved
4866 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4867 * otherwise unused.
4868 */
4869extern "C" {
4870
4871CXTokenKind clang_getTokenKind(CXToken CXTok) {
4872 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4873}
4874
4875CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4876 switch (clang_getTokenKind(CXTok)) {
4877 case CXToken_Identifier:
4878 case CXToken_Keyword:
4879 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004880 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 ->getNameStart());
4882
4883 case CXToken_Literal: {
4884 // We have stashed the starting pointer in the ptr_data field. Use it.
4885 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004886 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 }
4888
4889 case CXToken_Punctuation:
4890 case CXToken_Comment:
4891 break;
4892 }
4893
4894 // We have to find the starting buffer pointer the hard way, by
4895 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004896 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004898 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004899
4900 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4901 std::pair<FileID, unsigned> LocInfo
4902 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4903 bool Invalid = false;
4904 StringRef Buffer
4905 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4906 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004907 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004908
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004909 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004910}
4911
4912CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004913 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 if (!CXXUnit)
4915 return clang_getNullLocation();
4916
4917 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4918 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4919}
4920
4921CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004922 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 if (!CXXUnit)
4924 return clang_getNullRange();
4925
4926 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4927 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4928}
4929
4930static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4931 SmallVectorImpl<CXToken> &CXTokens) {
4932 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4933 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004934 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004936 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004937
4938 // Cannot tokenize across files.
4939 if (BeginLocInfo.first != EndLocInfo.first)
4940 return;
4941
4942 // Create a lexer
4943 bool Invalid = false;
4944 StringRef Buffer
4945 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4946 if (Invalid)
4947 return;
4948
4949 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4950 CXXUnit->getASTContext().getLangOpts(),
4951 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4952 Lex.SetCommentRetentionState(true);
4953
4954 // Lex tokens until we hit the end of the range.
4955 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4956 Token Tok;
4957 bool previousWasAt = false;
4958 do {
4959 // Lex the next token
4960 Lex.LexFromRawLexer(Tok);
4961 if (Tok.is(tok::eof))
4962 break;
4963
4964 // Initialize the CXToken.
4965 CXToken CXTok;
4966
4967 // - Common fields
4968 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4969 CXTok.int_data[2] = Tok.getLength();
4970 CXTok.int_data[3] = 0;
4971
4972 // - Kind-specific fields
4973 if (Tok.isLiteral()) {
4974 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004975 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 } else if (Tok.is(tok::raw_identifier)) {
4977 // Lookup the identifier to determine whether we have a keyword.
4978 IdentifierInfo *II
4979 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4980
4981 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4982 CXTok.int_data[0] = CXToken_Keyword;
4983 }
4984 else {
4985 CXTok.int_data[0] = Tok.is(tok::identifier)
4986 ? CXToken_Identifier
4987 : CXToken_Keyword;
4988 }
4989 CXTok.ptr_data = II;
4990 } else if (Tok.is(tok::comment)) {
4991 CXTok.int_data[0] = CXToken_Comment;
4992 CXTok.ptr_data = 0;
4993 } else {
4994 CXTok.int_data[0] = CXToken_Punctuation;
4995 CXTok.ptr_data = 0;
4996 }
4997 CXTokens.push_back(CXTok);
4998 previousWasAt = Tok.is(tok::at);
4999 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5000}
5001
5002void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5003 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005004 LOG_FUNC_SECTION {
5005 *Log << TU << ' ' << Range;
5006 }
5007
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 if (Tokens)
5009 *Tokens = 0;
5010 if (NumTokens)
5011 *NumTokens = 0;
5012
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005013 if (!TU)
5014 return;
5015
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005016 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 if (!CXXUnit || !Tokens || !NumTokens)
5018 return;
5019
5020 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5021
5022 SourceRange R = cxloc::translateCXSourceRange(Range);
5023 if (R.isInvalid())
5024 return;
5025
5026 SmallVector<CXToken, 32> CXTokens;
5027 getTokens(CXXUnit, R, CXTokens);
5028
5029 if (CXTokens.empty())
5030 return;
5031
5032 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5033 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5034 *NumTokens = CXTokens.size();
5035}
5036
5037void clang_disposeTokens(CXTranslationUnit TU,
5038 CXToken *Tokens, unsigned NumTokens) {
5039 free(Tokens);
5040}
5041
5042} // end: extern "C"
5043
5044//===----------------------------------------------------------------------===//
5045// Token annotation APIs.
5046//===----------------------------------------------------------------------===//
5047
Guy Benyei11169dd2012-12-18 14:30:41 +00005048static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5049 CXCursor parent,
5050 CXClientData client_data);
5051static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5052 CXClientData client_data);
5053
5054namespace {
5055class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 CXToken *Tokens;
5057 CXCursor *Cursors;
5058 unsigned NumTokens;
5059 unsigned TokIdx;
5060 unsigned PreprocessingTokIdx;
5061 CursorVisitor AnnotateVis;
5062 SourceManager &SrcMgr;
5063 bool HasContextSensitiveKeywords;
5064
5065 struct PostChildrenInfo {
5066 CXCursor Cursor;
5067 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005068 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 unsigned BeforeChildrenTokenIdx;
5070 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005071 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005072
5073 CXToken &getTok(unsigned Idx) {
5074 assert(Idx < NumTokens);
5075 return Tokens[Idx];
5076 }
5077 const CXToken &getTok(unsigned Idx) const {
5078 assert(Idx < NumTokens);
5079 return Tokens[Idx];
5080 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 bool MoreTokens() const { return TokIdx < NumTokens; }
5082 unsigned NextToken() const { return TokIdx; }
5083 void AdvanceToken() { ++TokIdx; }
5084 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005085 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 }
5087 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005088 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 }
5090 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005091 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 }
5093
5094 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005095 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 SourceRange);
5097
5098public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005099 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005100 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005101 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005103 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 AnnotateTokensVisitor, this,
5105 /*VisitPreprocessorLast=*/true,
5106 /*VisitIncludedEntities=*/false,
5107 RegionOfInterest,
5108 /*VisitDeclsOnly=*/false,
5109 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005110 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 HasContextSensitiveKeywords(false) { }
5112
5113 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5114 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5115 bool postVisitChildren(CXCursor cursor);
5116 void AnnotateTokens();
5117
5118 /// \brief Determine whether the annotator saw any cursors that have
5119 /// context-sensitive keywords.
5120 bool hasContextSensitiveKeywords() const {
5121 return HasContextSensitiveKeywords;
5122 }
5123
5124 ~AnnotateTokensWorker() {
5125 assert(PostChildrenInfos.empty());
5126 }
5127};
5128}
5129
5130void AnnotateTokensWorker::AnnotateTokens() {
5131 // Walk the AST within the region of interest, annotating tokens
5132 // along the way.
5133 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005134}
Guy Benyei11169dd2012-12-18 14:30:41 +00005135
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005136static inline void updateCursorAnnotation(CXCursor &Cursor,
5137 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005138 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005140 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005141}
5142
5143/// \brief It annotates and advances tokens with a cursor until the comparison
5144//// between the cursor location and the source range is the same as
5145/// \arg compResult.
5146///
5147/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5148/// Pass RangeOverlap to annotate tokens inside a range.
5149void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5150 RangeComparisonResult compResult,
5151 SourceRange range) {
5152 while (MoreTokens()) {
5153 const unsigned I = NextToken();
5154 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005155 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5156 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005157
5158 SourceLocation TokLoc = GetTokenLoc(I);
5159 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005160 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 AdvanceToken();
5162 continue;
5163 }
5164 break;
5165 }
5166}
5167
5168/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005169/// \returns true if it advanced beyond all macro tokens, false otherwise.
5170bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005171 CXCursor updateC,
5172 RangeComparisonResult compResult,
5173 SourceRange range) {
5174 assert(MoreTokens());
5175 assert(isFunctionMacroToken(NextToken()) &&
5176 "Should be called only for macro arg tokens");
5177
5178 // This works differently than annotateAndAdvanceTokens; because expanded
5179 // macro arguments can have arbitrary translation-unit source order, we do not
5180 // advance the token index one by one until a token fails the range test.
5181 // We only advance once past all of the macro arg tokens if all of them
5182 // pass the range test. If one of them fails we keep the token index pointing
5183 // at the start of the macro arg tokens so that the failing token will be
5184 // annotated by a subsequent annotation try.
5185
5186 bool atLeastOneCompFail = false;
5187
5188 unsigned I = NextToken();
5189 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5190 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5191 if (TokLoc.isFileID())
5192 continue; // not macro arg token, it's parens or comma.
5193 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5194 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5195 Cursors[I] = updateC;
5196 } else
5197 atLeastOneCompFail = true;
5198 }
5199
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005200 if (atLeastOneCompFail)
5201 return false;
5202
5203 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5204 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005205}
5206
5207enum CXChildVisitResult
5208AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 SourceRange cursorRange = getRawCursorExtent(cursor);
5210 if (cursorRange.isInvalid())
5211 return CXChildVisit_Recurse;
5212
5213 if (!HasContextSensitiveKeywords) {
5214 // Objective-C properties can have context-sensitive keywords.
5215 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005216 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5218 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5219 }
5220 // Objective-C methods can have context-sensitive keywords.
5221 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5222 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005223 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5225 if (Method->getObjCDeclQualifier())
5226 HasContextSensitiveKeywords = true;
5227 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005228 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5229 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 P != PEnd; ++P) {
5231 if ((*P)->getObjCDeclQualifier()) {
5232 HasContextSensitiveKeywords = true;
5233 break;
5234 }
5235 }
5236 }
5237 }
5238 }
5239 // C++ methods can have context-sensitive keywords.
5240 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005241 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5243 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5244 HasContextSensitiveKeywords = true;
5245 }
5246 }
5247 // C++ classes can have context-sensitive keywords.
5248 else if (cursor.kind == CXCursor_StructDecl ||
5249 cursor.kind == CXCursor_ClassDecl ||
5250 cursor.kind == CXCursor_ClassTemplate ||
5251 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005252 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 if (D->hasAttr<FinalAttr>())
5254 HasContextSensitiveKeywords = true;
5255 }
5256 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005257
5258 // Don't override a property annotation with its getter/setter method.
5259 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5260 parent.kind == CXCursor_ObjCPropertyDecl)
5261 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005262
5263 if (clang_isPreprocessing(cursor.kind)) {
5264 // Items in the preprocessing record are kept separate from items in
5265 // declarations, so we keep a separate token index.
5266 unsigned SavedTokIdx = TokIdx;
5267 TokIdx = PreprocessingTokIdx;
5268
5269 // Skip tokens up until we catch up to the beginning of the preprocessing
5270 // entry.
5271 while (MoreTokens()) {
5272 const unsigned I = NextToken();
5273 SourceLocation TokLoc = GetTokenLoc(I);
5274 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5275 case RangeBefore:
5276 AdvanceToken();
5277 continue;
5278 case RangeAfter:
5279 case RangeOverlap:
5280 break;
5281 }
5282 break;
5283 }
5284
5285 // Look at all of the tokens within this range.
5286 while (MoreTokens()) {
5287 const unsigned I = NextToken();
5288 SourceLocation TokLoc = GetTokenLoc(I);
5289 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5290 case RangeBefore:
5291 llvm_unreachable("Infeasible");
5292 case RangeAfter:
5293 break;
5294 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005295 // For macro expansions, just note where the beginning of the macro
5296 // expansion occurs.
5297 if (cursor.kind == CXCursor_MacroExpansion) {
5298 if (TokLoc == cursorRange.getBegin())
5299 Cursors[I] = cursor;
5300 AdvanceToken();
5301 break;
5302 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005303 // We may have already annotated macro names inside macro definitions.
5304 if (Cursors[I].kind != CXCursor_MacroExpansion)
5305 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 continue;
5308 }
5309 break;
5310 }
5311
5312 // Save the preprocessing token index; restore the non-preprocessing
5313 // token index.
5314 PreprocessingTokIdx = TokIdx;
5315 TokIdx = SavedTokIdx;
5316 return CXChildVisit_Recurse;
5317 }
5318
5319 if (cursorRange.isInvalid())
5320 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005321
5322 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 const enum CXCursorKind K = clang_getCursorKind(parent);
5325 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005326 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5327 // Attributes are annotated out-of-order, skip tokens until we reach it.
5328 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 ? clang_getNullCursor() : parent;
5330
5331 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5332
5333 // Avoid having the cursor of an expression "overwrite" the annotation of the
5334 // variable declaration that it belongs to.
5335 // This can happen for C++ constructor expressions whose range generally
5336 // include the variable declaration, e.g.:
5337 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005338 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005339 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005340 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 const unsigned I = NextToken();
5342 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5343 E->getLocStart() == D->getLocation() &&
5344 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005345 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 AdvanceToken();
5347 }
5348 }
5349 }
5350
5351 // Before recursing into the children keep some state that we are going
5352 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5353 // extra work after the child nodes are visited.
5354 // Note that we don't call VisitChildren here to avoid traversing statements
5355 // code-recursively which can blow the stack.
5356
5357 PostChildrenInfo Info;
5358 Info.Cursor = cursor;
5359 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005360 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 Info.BeforeChildrenTokenIdx = NextToken();
5362 PostChildrenInfos.push_back(Info);
5363
5364 return CXChildVisit_Recurse;
5365}
5366
5367bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5368 if (PostChildrenInfos.empty())
5369 return false;
5370 const PostChildrenInfo &Info = PostChildrenInfos.back();
5371 if (!clang_equalCursors(Info.Cursor, cursor))
5372 return false;
5373
5374 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5375 const unsigned AfterChildren = NextToken();
5376 SourceRange cursorRange = Info.CursorRange;
5377
5378 // Scan the tokens that are at the end of the cursor, but are not captured
5379 // but the child cursors.
5380 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5381
5382 // Scan the tokens that are at the beginning of the cursor, but are not
5383 // capture by the child cursors.
5384 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5385 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5386 break;
5387
5388 Cursors[I] = cursor;
5389 }
5390
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005391 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5392 // encountered the attribute cursor.
5393 if (clang_isAttribute(cursor.kind))
5394 TokIdx = Info.BeforeReachingCursorIdx;
5395
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 PostChildrenInfos.pop_back();
5397 return false;
5398}
5399
5400static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5401 CXCursor parent,
5402 CXClientData client_data) {
5403 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5404}
5405
5406static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5407 CXClientData client_data) {
5408 return static_cast<AnnotateTokensWorker*>(client_data)->
5409 postVisitChildren(cursor);
5410}
5411
5412namespace {
5413
5414/// \brief Uses the macro expansions in the preprocessing record to find
5415/// and mark tokens that are macro arguments. This info is used by the
5416/// AnnotateTokensWorker.
5417class MarkMacroArgTokensVisitor {
5418 SourceManager &SM;
5419 CXToken *Tokens;
5420 unsigned NumTokens;
5421 unsigned CurIdx;
5422
5423public:
5424 MarkMacroArgTokensVisitor(SourceManager &SM,
5425 CXToken *tokens, unsigned numTokens)
5426 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5427
5428 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5429 if (cursor.kind != CXCursor_MacroExpansion)
5430 return CXChildVisit_Continue;
5431
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005432 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 if (macroRange.getBegin() == macroRange.getEnd())
5434 return CXChildVisit_Continue; // it's not a function macro.
5435
5436 for (; CurIdx < NumTokens; ++CurIdx) {
5437 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5438 macroRange.getBegin()))
5439 break;
5440 }
5441
5442 if (CurIdx == NumTokens)
5443 return CXChildVisit_Break;
5444
5445 for (; CurIdx < NumTokens; ++CurIdx) {
5446 SourceLocation tokLoc = getTokenLoc(CurIdx);
5447 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5448 break;
5449
5450 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5451 }
5452
5453 if (CurIdx == NumTokens)
5454 return CXChildVisit_Break;
5455
5456 return CXChildVisit_Continue;
5457 }
5458
5459private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005460 CXToken &getTok(unsigned Idx) {
5461 assert(Idx < NumTokens);
5462 return Tokens[Idx];
5463 }
5464 const CXToken &getTok(unsigned Idx) const {
5465 assert(Idx < NumTokens);
5466 return Tokens[Idx];
5467 }
5468
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005470 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 }
5472
5473 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5474 // The third field is reserved and currently not used. Use it here
5475 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005476 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 }
5478};
5479
5480} // end anonymous namespace
5481
5482static CXChildVisitResult
5483MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5484 CXClientData client_data) {
5485 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5486 parent);
5487}
5488
5489namespace {
5490 struct clang_annotateTokens_Data {
5491 CXTranslationUnit TU;
5492 ASTUnit *CXXUnit;
5493 CXToken *Tokens;
5494 unsigned NumTokens;
5495 CXCursor *Cursors;
5496 };
5497}
5498
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005499/// \brief Used by \c annotatePreprocessorTokens.
5500/// \returns true if lexing was finished, false otherwise.
5501static bool lexNext(Lexer &Lex, Token &Tok,
5502 unsigned &NextIdx, unsigned NumTokens) {
5503 if (NextIdx >= NumTokens)
5504 return true;
5505
5506 ++NextIdx;
5507 Lex.LexFromRawLexer(Tok);
5508 if (Tok.is(tok::eof))
5509 return true;
5510
5511 return false;
5512}
5513
Guy Benyei11169dd2012-12-18 14:30:41 +00005514static void annotatePreprocessorTokens(CXTranslationUnit TU,
5515 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005516 CXCursor *Cursors,
5517 CXToken *Tokens,
5518 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005520
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005521 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5523 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005524 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005526 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005527
5528 if (BeginLocInfo.first != EndLocInfo.first)
5529 return;
5530
5531 StringRef Buffer;
5532 bool Invalid = false;
5533 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5534 if (Buffer.empty() || Invalid)
5535 return;
5536
5537 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5538 CXXUnit->getASTContext().getLangOpts(),
5539 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5540 Buffer.end());
5541 Lex.SetCommentRetentionState(true);
5542
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005543 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 // Lex tokens in raw mode until we hit the end of the range, to avoid
5545 // entering #includes or expanding macros.
5546 while (true) {
5547 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005548 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5549 break;
5550 unsigned TokIdx = NextIdx-1;
5551 assert(Tok.getLocation() ==
5552 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005553
5554 reprocess:
5555 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005556 // We have found a preprocessing directive. Annotate the tokens
5557 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 //
5559 // FIXME: Some simple tests here could identify macro definitions and
5560 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005561
5562 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005563 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5564 break;
5565
5566 MacroInfo *MI = 0;
5567 if (Tok.is(tok::raw_identifier) &&
5568 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5569 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5570 break;
5571
5572 if (Tok.is(tok::raw_identifier)) {
5573 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5574 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5575 SourceLocation MappedTokLoc =
5576 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5577 MI = getMacroInfo(II, MappedTokLoc, TU);
5578 }
5579 }
5580
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005581 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005583 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5584 finished = true;
5585 break;
5586 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005587 // If we are in a macro definition, check if the token was ever a
5588 // macro name and annotate it if that's the case.
5589 if (MI) {
5590 SourceLocation SaveLoc = Tok.getLocation();
5591 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5592 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5593 Tok.setLocation(SaveLoc);
5594 if (MacroDef)
5595 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5596 Tok.getLocation(), TU);
5597 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005598 } while (!Tok.isAtStartOfLine());
5599
5600 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5601 assert(TokIdx <= LastIdx);
5602 SourceLocation EndLoc =
5603 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5604 CXCursor Cursor =
5605 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5606
5607 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005608 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005609
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005610 if (finished)
5611 break;
5612 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005613 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005614 }
5615}
5616
5617// This gets run a separate thread to avoid stack blowout.
5618static void clang_annotateTokensImpl(void *UserData) {
5619 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5620 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5621 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5622 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5623 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5624
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005625 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5627 setThreadBackgroundPriority();
5628
5629 // Determine the region of interest, which contains all of the tokens.
5630 SourceRange RegionOfInterest;
5631 RegionOfInterest.setBegin(
5632 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5633 RegionOfInterest.setEnd(
5634 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5635 Tokens[NumTokens-1])));
5636
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 // Relex the tokens within the source range to look for preprocessing
5638 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005639 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005640
5641 // If begin location points inside a macro argument, set it to the expansion
5642 // location so we can have the full context when annotating semantically.
5643 {
5644 SourceManager &SM = CXXUnit->getSourceManager();
5645 SourceLocation Loc =
5646 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5647 if (Loc.isMacroID())
5648 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5649 }
5650
Guy Benyei11169dd2012-12-18 14:30:41 +00005651 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5652 // Search and mark tokens that are macro argument expansions.
5653 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5654 Tokens, NumTokens);
5655 CursorVisitor MacroArgMarker(TU,
5656 MarkMacroArgTokensVisitorDelegate, &Visitor,
5657 /*VisitPreprocessorLast=*/true,
5658 /*VisitIncludedEntities=*/false,
5659 RegionOfInterest);
5660 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5661 }
5662
5663 // Annotate all of the source locations in the region of interest that map to
5664 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005665 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005666
5667 // FIXME: We use a ridiculous stack size here because the data-recursion
5668 // algorithm uses a large stack frame than the non-data recursive version,
5669 // and AnnotationTokensWorker currently transforms the data-recursion
5670 // algorithm back into a traditional recursion by explicitly calling
5671 // VisitChildren(). We will need to remove this explicit recursive call.
5672 W.AnnotateTokens();
5673
5674 // If we ran into any entities that involve context-sensitive keywords,
5675 // take another pass through the tokens to mark them as such.
5676 if (W.hasContextSensitiveKeywords()) {
5677 for (unsigned I = 0; I != NumTokens; ++I) {
5678 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5679 continue;
5680
5681 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5682 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005683 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5685 if (Property->getPropertyAttributesAsWritten() != 0 &&
5686 llvm::StringSwitch<bool>(II->getName())
5687 .Case("readonly", true)
5688 .Case("assign", true)
5689 .Case("unsafe_unretained", true)
5690 .Case("readwrite", true)
5691 .Case("retain", true)
5692 .Case("copy", true)
5693 .Case("nonatomic", true)
5694 .Case("atomic", true)
5695 .Case("getter", true)
5696 .Case("setter", true)
5697 .Case("strong", true)
5698 .Case("weak", true)
5699 .Default(false))
5700 Tokens[I].int_data[0] = CXToken_Keyword;
5701 }
5702 continue;
5703 }
5704
5705 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5706 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5707 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5708 if (llvm::StringSwitch<bool>(II->getName())
5709 .Case("in", true)
5710 .Case("out", true)
5711 .Case("inout", true)
5712 .Case("oneway", true)
5713 .Case("bycopy", true)
5714 .Case("byref", true)
5715 .Default(false))
5716 Tokens[I].int_data[0] = CXToken_Keyword;
5717 continue;
5718 }
5719
5720 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5721 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5722 Tokens[I].int_data[0] = CXToken_Keyword;
5723 continue;
5724 }
5725 }
5726 }
5727}
5728
5729extern "C" {
5730
5731void clang_annotateTokens(CXTranslationUnit TU,
5732 CXToken *Tokens, unsigned NumTokens,
5733 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005734 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005735 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005737 }
5738
5739 LOG_FUNC_SECTION {
5740 *Log << TU << ' ';
5741 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5742 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5743 *Log << clang_getRange(bloc, eloc);
5744 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005745
5746 // Any token we don't specifically annotate will have a NULL cursor.
5747 CXCursor C = clang_getNullCursor();
5748 for (unsigned I = 0; I != NumTokens; ++I)
5749 Cursors[I] = C;
5750
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005751 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 if (!CXXUnit)
5753 return;
5754
5755 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5756
5757 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5758 llvm::CrashRecoveryContext CRC;
5759 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5760 GetSafetyThreadStackSize() * 2)) {
5761 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5762 }
5763}
5764
5765} // end: extern "C"
5766
5767//===----------------------------------------------------------------------===//
5768// Operations for querying linkage of a cursor.
5769//===----------------------------------------------------------------------===//
5770
5771extern "C" {
5772CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5773 if (!clang_isDeclaration(cursor.kind))
5774 return CXLinkage_Invalid;
5775
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005776 const Decl *D = cxcursor::getCursorDecl(cursor);
5777 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005778 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005779 case NoLinkage:
5780 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 case InternalLinkage: return CXLinkage_Internal;
5782 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5783 case ExternalLinkage: return CXLinkage_External;
5784 };
5785
5786 return CXLinkage_Invalid;
5787}
5788} // end: extern "C"
5789
5790//===----------------------------------------------------------------------===//
5791// Operations for querying language of a cursor.
5792//===----------------------------------------------------------------------===//
5793
5794static CXLanguageKind getDeclLanguage(const Decl *D) {
5795 if (!D)
5796 return CXLanguage_C;
5797
5798 switch (D->getKind()) {
5799 default:
5800 break;
5801 case Decl::ImplicitParam:
5802 case Decl::ObjCAtDefsField:
5803 case Decl::ObjCCategory:
5804 case Decl::ObjCCategoryImpl:
5805 case Decl::ObjCCompatibleAlias:
5806 case Decl::ObjCImplementation:
5807 case Decl::ObjCInterface:
5808 case Decl::ObjCIvar:
5809 case Decl::ObjCMethod:
5810 case Decl::ObjCProperty:
5811 case Decl::ObjCPropertyImpl:
5812 case Decl::ObjCProtocol:
5813 return CXLanguage_ObjC;
5814 case Decl::CXXConstructor:
5815 case Decl::CXXConversion:
5816 case Decl::CXXDestructor:
5817 case Decl::CXXMethod:
5818 case Decl::CXXRecord:
5819 case Decl::ClassTemplate:
5820 case Decl::ClassTemplatePartialSpecialization:
5821 case Decl::ClassTemplateSpecialization:
5822 case Decl::Friend:
5823 case Decl::FriendTemplate:
5824 case Decl::FunctionTemplate:
5825 case Decl::LinkageSpec:
5826 case Decl::Namespace:
5827 case Decl::NamespaceAlias:
5828 case Decl::NonTypeTemplateParm:
5829 case Decl::StaticAssert:
5830 case Decl::TemplateTemplateParm:
5831 case Decl::TemplateTypeParm:
5832 case Decl::UnresolvedUsingTypename:
5833 case Decl::UnresolvedUsingValue:
5834 case Decl::Using:
5835 case Decl::UsingDirective:
5836 case Decl::UsingShadow:
5837 return CXLanguage_CPlusPlus;
5838 }
5839
5840 return CXLanguage_C;
5841}
5842
5843extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005844
5845static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5846 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5847 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005848
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005849 switch (D->getAvailability()) {
5850 case AR_Available:
5851 case AR_NotYetIntroduced:
5852 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005853 return getCursorAvailabilityForDecl(
5854 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005855 return CXAvailability_Available;
5856
5857 case AR_Deprecated:
5858 return CXAvailability_Deprecated;
5859
5860 case AR_Unavailable:
5861 return CXAvailability_NotAvailable;
5862 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005863
5864 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005865}
5866
Guy Benyei11169dd2012-12-18 14:30:41 +00005867enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5868 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005869 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5870 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005871
5872 return CXAvailability_Available;
5873}
5874
5875static CXVersion convertVersion(VersionTuple In) {
5876 CXVersion Out = { -1, -1, -1 };
5877 if (In.empty())
5878 return Out;
5879
5880 Out.Major = In.getMajor();
5881
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005882 Optional<unsigned> Minor = In.getMinor();
5883 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 Out.Minor = *Minor;
5885 else
5886 return Out;
5887
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005888 Optional<unsigned> Subminor = In.getSubminor();
5889 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 Out.Subminor = *Subminor;
5891
5892 return Out;
5893}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005894
5895static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5896 int *always_deprecated,
5897 CXString *deprecated_message,
5898 int *always_unavailable,
5899 CXString *unavailable_message,
5900 CXPlatformAvailability *availability,
5901 int availability_size) {
5902 bool HadAvailAttr = false;
5903 int N = 0;
5904 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5905 ++A) {
5906 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5907 HadAvailAttr = true;
5908 if (always_deprecated)
5909 *always_deprecated = 1;
5910 if (deprecated_message)
5911 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5912 continue;
5913 }
5914
5915 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5916 HadAvailAttr = true;
5917 if (always_unavailable)
5918 *always_unavailable = 1;
5919 if (unavailable_message) {
5920 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5921 }
5922 continue;
5923 }
5924
5925 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5926 HadAvailAttr = true;
5927 if (N < availability_size) {
5928 availability[N].Platform
5929 = cxstring::createDup(Avail->getPlatform()->getName());
5930 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5931 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5932 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5933 availability[N].Unavailable = Avail->getUnavailable();
5934 availability[N].Message = cxstring::createDup(Avail->getMessage());
5935 }
5936 ++N;
5937 }
5938 }
5939
5940 if (!HadAvailAttr)
5941 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5942 return getCursorPlatformAvailabilityForDecl(
5943 cast<Decl>(EnumConst->getDeclContext()),
5944 always_deprecated,
5945 deprecated_message,
5946 always_unavailable,
5947 unavailable_message,
5948 availability,
5949 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005950
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005951 return N;
5952}
5953
Guy Benyei11169dd2012-12-18 14:30:41 +00005954int clang_getCursorPlatformAvailability(CXCursor cursor,
5955 int *always_deprecated,
5956 CXString *deprecated_message,
5957 int *always_unavailable,
5958 CXString *unavailable_message,
5959 CXPlatformAvailability *availability,
5960 int availability_size) {
5961 if (always_deprecated)
5962 *always_deprecated = 0;
5963 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005964 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 if (always_unavailable)
5966 *always_unavailable = 0;
5967 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005968 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005969
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 if (!clang_isDeclaration(cursor.kind))
5971 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005972
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005973 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 if (!D)
5975 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005976
5977 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5978 deprecated_message,
5979 always_unavailable,
5980 unavailable_message,
5981 availability,
5982 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005983}
5984
5985void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5986 clang_disposeString(availability->Platform);
5987 clang_disposeString(availability->Message);
5988}
5989
5990CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5991 if (clang_isDeclaration(cursor.kind))
5992 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5993
5994 return CXLanguage_Invalid;
5995}
5996
5997 /// \brief If the given cursor is the "templated" declaration
5998 /// descibing a class or function template, return the class or
5999 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006000static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006001 if (!D)
6002 return 0;
6003
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006004 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6006 return FunTmpl;
6007
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006008 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006009 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6010 return ClassTmpl;
6011
6012 return D;
6013}
6014
6015CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6016 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006017 if (const Decl *D = getCursorDecl(cursor)) {
6018 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 if (!DC)
6020 return clang_getNullCursor();
6021
6022 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6023 getCursorTU(cursor));
6024 }
6025 }
6026
6027 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006028 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006029 return MakeCXCursor(D, getCursorTU(cursor));
6030 }
6031
6032 return clang_getNullCursor();
6033}
6034
6035CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6036 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006037 if (const Decl *D = getCursorDecl(cursor)) {
6038 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006039 if (!DC)
6040 return clang_getNullCursor();
6041
6042 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6043 getCursorTU(cursor));
6044 }
6045 }
6046
6047 // FIXME: Note that we can't easily compute the lexical context of a
6048 // statement or expression, so we return nothing.
6049 return clang_getNullCursor();
6050}
6051
6052CXFile clang_getIncludedFile(CXCursor cursor) {
6053 if (cursor.kind != CXCursor_InclusionDirective)
6054 return 0;
6055
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006056 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006057 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006058}
6059
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006060unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6061 if (C.kind != CXCursor_ObjCPropertyDecl)
6062 return CXObjCPropertyAttr_noattr;
6063
6064 unsigned Result = CXObjCPropertyAttr_noattr;
6065 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6066 ObjCPropertyDecl::PropertyAttributeKind Attr =
6067 PD->getPropertyAttributesAsWritten();
6068
6069#define SET_CXOBJCPROP_ATTR(A) \
6070 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6071 Result |= CXObjCPropertyAttr_##A
6072 SET_CXOBJCPROP_ATTR(readonly);
6073 SET_CXOBJCPROP_ATTR(getter);
6074 SET_CXOBJCPROP_ATTR(assign);
6075 SET_CXOBJCPROP_ATTR(readwrite);
6076 SET_CXOBJCPROP_ATTR(retain);
6077 SET_CXOBJCPROP_ATTR(copy);
6078 SET_CXOBJCPROP_ATTR(nonatomic);
6079 SET_CXOBJCPROP_ATTR(setter);
6080 SET_CXOBJCPROP_ATTR(atomic);
6081 SET_CXOBJCPROP_ATTR(weak);
6082 SET_CXOBJCPROP_ATTR(strong);
6083 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6084#undef SET_CXOBJCPROP_ATTR
6085
6086 return Result;
6087}
6088
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006089unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6090 if (!clang_isDeclaration(C.kind))
6091 return CXObjCDeclQualifier_None;
6092
6093 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6094 const Decl *D = getCursorDecl(C);
6095 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6096 QT = MD->getObjCDeclQualifier();
6097 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6098 QT = PD->getObjCDeclQualifier();
6099 if (QT == Decl::OBJC_TQ_None)
6100 return CXObjCDeclQualifier_None;
6101
6102 unsigned Result = CXObjCDeclQualifier_None;
6103 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6104 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6105 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6106 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6107 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6108 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6109
6110 return Result;
6111}
6112
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006113unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6114 if (!clang_isDeclaration(C.kind))
6115 return 0;
6116
6117 const Decl *D = getCursorDecl(C);
6118 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6119 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6120 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6121 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6122
6123 return 0;
6124}
6125
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006126unsigned clang_Cursor_isVariadic(CXCursor C) {
6127 if (!clang_isDeclaration(C.kind))
6128 return 0;
6129
6130 const Decl *D = getCursorDecl(C);
6131 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6132 return FD->isVariadic();
6133 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6134 return MD->isVariadic();
6135
6136 return 0;
6137}
6138
Guy Benyei11169dd2012-12-18 14:30:41 +00006139CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6140 if (!clang_isDeclaration(C.kind))
6141 return clang_getNullRange();
6142
6143 const Decl *D = getCursorDecl(C);
6144 ASTContext &Context = getCursorContext(C);
6145 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6146 if (!RC)
6147 return clang_getNullRange();
6148
6149 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6150}
6151
6152CXString clang_Cursor_getRawCommentText(CXCursor C) {
6153 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006154 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006155
6156 const Decl *D = getCursorDecl(C);
6157 ASTContext &Context = getCursorContext(C);
6158 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6159 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6160 StringRef();
6161
6162 // Don't duplicate the string because RawText points directly into source
6163 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006164 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006165}
6166
6167CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6168 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006169 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006170
6171 const Decl *D = getCursorDecl(C);
6172 const ASTContext &Context = getCursorContext(C);
6173 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6174
6175 if (RC) {
6176 StringRef BriefText = RC->getBriefText(Context);
6177
6178 // Don't duplicate the string because RawComment ensures that this memory
6179 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006180 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006181 }
6182
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006183 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006184}
6185
6186CXComment clang_Cursor_getParsedComment(CXCursor C) {
6187 if (!clang_isDeclaration(C.kind))
6188 return cxcomment::createCXComment(NULL, NULL);
6189
6190 const Decl *D = getCursorDecl(C);
6191 const ASTContext &Context = getCursorContext(C);
6192 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6193
6194 return cxcomment::createCXComment(FC, getCursorTU(C));
6195}
6196
6197CXModule clang_Cursor_getModule(CXCursor C) {
6198 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006199 if (const ImportDecl *ImportD =
6200 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 return ImportD->getImportedModule();
6202 }
6203
6204 return 0;
6205}
6206
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006207CXFile clang_Module_getASTFile(CXModule CXMod) {
6208 if (!CXMod)
6209 return 0;
6210 Module *Mod = static_cast<Module*>(CXMod);
6211 return const_cast<FileEntry *>(Mod->getASTFile());
6212}
6213
Guy Benyei11169dd2012-12-18 14:30:41 +00006214CXModule clang_Module_getParent(CXModule CXMod) {
6215 if (!CXMod)
6216 return 0;
6217 Module *Mod = static_cast<Module*>(CXMod);
6218 return Mod->Parent;
6219}
6220
6221CXString clang_Module_getName(CXModule CXMod) {
6222 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006223 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006225 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006226}
6227
6228CXString clang_Module_getFullName(CXModule CXMod) {
6229 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006230 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006232 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006233}
6234
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006235unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6236 CXModule CXMod) {
6237 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006238 return 0;
6239 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006240 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6241 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6242 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006243}
6244
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006245CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6246 CXModule CXMod, unsigned Index) {
6247 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 return 0;
6249 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006250 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006251
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006252 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6253 if (Index < TopHeaders.size())
6254 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006255
6256 return 0;
6257}
6258
6259} // end: extern "C"
6260
6261//===----------------------------------------------------------------------===//
6262// C++ AST instrospection.
6263//===----------------------------------------------------------------------===//
6264
6265extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006266unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6267 if (!clang_isDeclaration(C.kind))
6268 return 0;
6269
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006270 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006271 const CXXMethodDecl *Method =
6272 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006273 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6274}
6275
Guy Benyei11169dd2012-12-18 14:30:41 +00006276unsigned clang_CXXMethod_isStatic(CXCursor C) {
6277 if (!clang_isDeclaration(C.kind))
6278 return 0;
6279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006280 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006281 const CXXMethodDecl *Method =
6282 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 return (Method && Method->isStatic()) ? 1 : 0;
6284}
6285
6286unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6287 if (!clang_isDeclaration(C.kind))
6288 return 0;
6289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006290 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006291 const CXXMethodDecl *Method =
6292 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 return (Method && Method->isVirtual()) ? 1 : 0;
6294}
6295} // end: extern "C"
6296
6297//===----------------------------------------------------------------------===//
6298// Attribute introspection.
6299//===----------------------------------------------------------------------===//
6300
6301extern "C" {
6302CXType clang_getIBOutletCollectionType(CXCursor C) {
6303 if (C.kind != CXCursor_IBOutletCollectionAttr)
6304 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6305
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006306 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006307 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6308
6309 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6310}
6311} // end: extern "C"
6312
6313//===----------------------------------------------------------------------===//
6314// Inspecting memory usage.
6315//===----------------------------------------------------------------------===//
6316
6317typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6318
6319static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6320 enum CXTUResourceUsageKind k,
6321 unsigned long amount) {
6322 CXTUResourceUsageEntry entry = { k, amount };
6323 entries.push_back(entry);
6324}
6325
6326extern "C" {
6327
6328const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6329 const char *str = "";
6330 switch (kind) {
6331 case CXTUResourceUsage_AST:
6332 str = "ASTContext: expressions, declarations, and types";
6333 break;
6334 case CXTUResourceUsage_Identifiers:
6335 str = "ASTContext: identifiers";
6336 break;
6337 case CXTUResourceUsage_Selectors:
6338 str = "ASTContext: selectors";
6339 break;
6340 case CXTUResourceUsage_GlobalCompletionResults:
6341 str = "Code completion: cached global results";
6342 break;
6343 case CXTUResourceUsage_SourceManagerContentCache:
6344 str = "SourceManager: content cache allocator";
6345 break;
6346 case CXTUResourceUsage_AST_SideTables:
6347 str = "ASTContext: side tables";
6348 break;
6349 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6350 str = "SourceManager: malloc'ed memory buffers";
6351 break;
6352 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6353 str = "SourceManager: mmap'ed memory buffers";
6354 break;
6355 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6356 str = "ExternalASTSource: malloc'ed memory buffers";
6357 break;
6358 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6359 str = "ExternalASTSource: mmap'ed memory buffers";
6360 break;
6361 case CXTUResourceUsage_Preprocessor:
6362 str = "Preprocessor: malloc'ed memory";
6363 break;
6364 case CXTUResourceUsage_PreprocessingRecord:
6365 str = "Preprocessor: PreprocessingRecord";
6366 break;
6367 case CXTUResourceUsage_SourceManager_DataStructures:
6368 str = "SourceManager: data structures and tables";
6369 break;
6370 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6371 str = "Preprocessor: header search tables";
6372 break;
6373 }
6374 return str;
6375}
6376
6377CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6378 if (!TU) {
6379 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6380 return usage;
6381 }
6382
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006383 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6385 ASTContext &astContext = astUnit->getASTContext();
6386
6387 // How much memory is used by AST nodes and types?
6388 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6389 (unsigned long) astContext.getASTAllocatedMemory());
6390
6391 // How much memory is used by identifiers?
6392 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6393 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6394
6395 // How much memory is used for selectors?
6396 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6397 (unsigned long) astContext.Selectors.getTotalMemory());
6398
6399 // How much memory is used by ASTContext's side tables?
6400 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6401 (unsigned long) astContext.getSideTableAllocatedMemory());
6402
6403 // How much memory is used for caching global code completion results?
6404 unsigned long completionBytes = 0;
6405 if (GlobalCodeCompletionAllocator *completionAllocator =
6406 astUnit->getCachedCompletionAllocator().getPtr()) {
6407 completionBytes = completionAllocator->getTotalMemory();
6408 }
6409 createCXTUResourceUsageEntry(*entries,
6410 CXTUResourceUsage_GlobalCompletionResults,
6411 completionBytes);
6412
6413 // How much memory is being used by SourceManager's content cache?
6414 createCXTUResourceUsageEntry(*entries,
6415 CXTUResourceUsage_SourceManagerContentCache,
6416 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6417
6418 // How much memory is being used by the MemoryBuffer's in SourceManager?
6419 const SourceManager::MemoryBufferSizes &srcBufs =
6420 astUnit->getSourceManager().getMemoryBufferSizes();
6421
6422 createCXTUResourceUsageEntry(*entries,
6423 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6424 (unsigned long) srcBufs.malloc_bytes);
6425 createCXTUResourceUsageEntry(*entries,
6426 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6427 (unsigned long) srcBufs.mmap_bytes);
6428 createCXTUResourceUsageEntry(*entries,
6429 CXTUResourceUsage_SourceManager_DataStructures,
6430 (unsigned long) astContext.getSourceManager()
6431 .getDataStructureSizes());
6432
6433 // How much memory is being used by the ExternalASTSource?
6434 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6435 const ExternalASTSource::MemoryBufferSizes &sizes =
6436 esrc->getMemoryBufferSizes();
6437
6438 createCXTUResourceUsageEntry(*entries,
6439 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6440 (unsigned long) sizes.malloc_bytes);
6441 createCXTUResourceUsageEntry(*entries,
6442 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6443 (unsigned long) sizes.mmap_bytes);
6444 }
6445
6446 // How much memory is being used by the Preprocessor?
6447 Preprocessor &pp = astUnit->getPreprocessor();
6448 createCXTUResourceUsageEntry(*entries,
6449 CXTUResourceUsage_Preprocessor,
6450 pp.getTotalMemory());
6451
6452 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6453 createCXTUResourceUsageEntry(*entries,
6454 CXTUResourceUsage_PreprocessingRecord,
6455 pRec->getTotalMemory());
6456 }
6457
6458 createCXTUResourceUsageEntry(*entries,
6459 CXTUResourceUsage_Preprocessor_HeaderSearch,
6460 pp.getHeaderSearchInfo().getTotalMemory());
6461
6462 CXTUResourceUsage usage = { (void*) entries.get(),
6463 (unsigned) entries->size(),
6464 entries->size() ? &(*entries)[0] : 0 };
6465 entries.take();
6466 return usage;
6467}
6468
6469void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6470 if (usage.data)
6471 delete (MemUsageEntries*) usage.data;
6472}
6473
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006474CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6475 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006476 skipped->count = 0;
6477 skipped->ranges = 0;
6478
6479 if (!file)
6480 return skipped;
6481
6482 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6483 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6484 if (!ppRec)
6485 return skipped;
6486
6487 ASTContext &Ctx = astUnit->getASTContext();
6488 SourceManager &sm = Ctx.getSourceManager();
6489 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6490 FileID wantedFileID = sm.translateFile(fileEntry);
6491
6492 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6493 std::vector<SourceRange> wantedRanges;
6494 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6495 i != ei; ++i) {
6496 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6497 wantedRanges.push_back(*i);
6498 }
6499
6500 skipped->count = wantedRanges.size();
6501 skipped->ranges = new CXSourceRange[skipped->count];
6502 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6503 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6504
6505 return skipped;
6506}
6507
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006508void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6509 if (ranges) {
6510 delete[] ranges->ranges;
6511 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006512 }
6513}
6514
Guy Benyei11169dd2012-12-18 14:30:41 +00006515} // end extern "C"
6516
6517void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6518 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6519 for (unsigned I = 0; I != Usage.numEntries; ++I)
6520 fprintf(stderr, " %s: %lu\n",
6521 clang_getTUResourceUsageName(Usage.entries[I].kind),
6522 Usage.entries[I].amount);
6523
6524 clang_disposeCXTUResourceUsage(Usage);
6525}
6526
6527//===----------------------------------------------------------------------===//
6528// Misc. utility functions.
6529//===----------------------------------------------------------------------===//
6530
6531/// Default to using an 8 MB stack size on "safety" threads.
6532static unsigned SafetyStackThreadSize = 8 << 20;
6533
6534namespace clang {
6535
6536bool RunSafely(llvm::CrashRecoveryContext &CRC,
6537 void (*Fn)(void*), void *UserData,
6538 unsigned Size) {
6539 if (!Size)
6540 Size = GetSafetyThreadStackSize();
6541 if (Size)
6542 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6543 return CRC.RunSafely(Fn, UserData);
6544}
6545
6546unsigned GetSafetyThreadStackSize() {
6547 return SafetyStackThreadSize;
6548}
6549
6550void SetSafetyThreadStackSize(unsigned Value) {
6551 SafetyStackThreadSize = Value;
6552}
6553
6554}
6555
6556void clang::setThreadBackgroundPriority() {
6557 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6558 return;
6559
6560 // FIXME: Move to llvm/Support and make it cross-platform.
6561#ifdef __APPLE__
6562 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6563#endif
6564}
6565
6566void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6567 if (!Unit)
6568 return;
6569
6570 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6571 DEnd = Unit->stored_diag_end();
6572 D != DEnd; ++D) {
6573 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6574 CXString Msg = clang_formatDiagnostic(&Diag,
6575 clang_defaultDiagnosticDisplayOptions());
6576 fprintf(stderr, "%s\n", clang_getCString(Msg));
6577 clang_disposeString(Msg);
6578 }
6579#ifdef LLVM_ON_WIN32
6580 // On Windows, force a flush, since there may be multiple copies of
6581 // stderr and stdout in the file system, all with different buffers
6582 // but writing to the same device.
6583 fflush(stderr);
6584#endif
6585}
6586
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006587MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6588 SourceLocation MacroDefLoc,
6589 CXTranslationUnit TU){
6590 if (MacroDefLoc.isInvalid() || !TU)
6591 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006592 if (!II.hadMacroDefinition())
6593 return 0;
6594
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006595 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006596 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006597 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006598 if (MD) {
6599 for (MacroDirective::DefInfo
6600 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6601 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6602 return Def.getMacroInfo();
6603 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006604 }
6605
6606 return 0;
6607}
6608
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006609const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6610 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006611 if (!MacroDef || !TU)
6612 return 0;
6613 const IdentifierInfo *II = MacroDef->getName();
6614 if (!II)
6615 return 0;
6616
6617 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6618}
6619
6620MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6621 const Token &Tok,
6622 CXTranslationUnit TU) {
6623 if (!MI || !TU)
6624 return 0;
6625 if (Tok.isNot(tok::raw_identifier))
6626 return 0;
6627
6628 if (MI->getNumTokens() == 0)
6629 return 0;
6630 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6631 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006632 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006633
6634 // Check that the token is inside the definition and not its argument list.
6635 SourceManager &SM = Unit->getSourceManager();
6636 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6637 return 0;
6638 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6639 return 0;
6640
6641 Preprocessor &PP = Unit->getPreprocessor();
6642 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6643 if (!PPRec)
6644 return 0;
6645
6646 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6647 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6648 if (!II.hadMacroDefinition())
6649 return 0;
6650
6651 // Check that the identifier is not one of the macro arguments.
6652 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6653 return 0;
6654
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006655 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6656 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006657 return 0;
6658
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006659 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006660}
6661
6662MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6663 SourceLocation Loc,
6664 CXTranslationUnit TU) {
6665 if (Loc.isInvalid() || !MI || !TU)
6666 return 0;
6667
6668 if (MI->getNumTokens() == 0)
6669 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006670 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006671 Preprocessor &PP = Unit->getPreprocessor();
6672 if (!PP.getPreprocessingRecord())
6673 return 0;
6674 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6675 Token Tok;
6676 if (PP.getRawToken(Loc, Tok))
6677 return 0;
6678
6679 return checkForMacroInMacroDefinition(MI, Tok, TU);
6680}
6681
Guy Benyei11169dd2012-12-18 14:30:41 +00006682extern "C" {
6683
6684CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006685 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006686}
6687
6688} // end: extern "C"
6689
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006690Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6691 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006692 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006693 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006694 if (Unit->isMainFileAST())
6695 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006696 return *this;
6697 }
6698 }
6699
6700 LogOS << "<NULL TU>";
6701 return *this;
6702}
6703
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006704Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6705 *this << FE->getName();
6706 return *this;
6707}
6708
6709Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6710 CXString cursorName = clang_getCursorDisplayName(cursor);
6711 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6712 clang_disposeString(cursorName);
6713 return *this;
6714}
6715
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006716Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6717 CXFile File;
6718 unsigned Line, Column;
6719 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6720 CXString FileName = clang_getFileName(File);
6721 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6722 clang_disposeString(FileName);
6723 return *this;
6724}
6725
6726Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6727 CXSourceLocation BLoc = clang_getRangeStart(range);
6728 CXSourceLocation ELoc = clang_getRangeEnd(range);
6729
6730 CXFile BFile;
6731 unsigned BLine, BColumn;
6732 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6733
6734 CXFile EFile;
6735 unsigned ELine, EColumn;
6736 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6737
6738 CXString BFileName = clang_getFileName(BFile);
6739 if (BFile == EFile) {
6740 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6741 BLine, BColumn, ELine, EColumn);
6742 } else {
6743 CXString EFileName = clang_getFileName(EFile);
6744 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6745 BLine, BColumn)
6746 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6747 ELine, EColumn);
6748 clang_disposeString(EFileName);
6749 }
6750 clang_disposeString(BFileName);
6751 return *this;
6752}
6753
6754Logger &cxindex::Logger::operator<<(CXString Str) {
6755 *this << clang_getCString(Str);
6756 return *this;
6757}
6758
6759Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6760 LogOS << Fmt;
6761 return *this;
6762}
6763
6764cxindex::Logger::~Logger() {
6765 LogOS.flush();
6766
6767 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6768
6769 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6770
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006771 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006772 OS << "[libclang:" << Name << ':';
6773
6774 // FIXME: Portability.
6775#if HAVE_PTHREAD_H && __APPLE__
6776 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6777 OS << tid << ':';
6778#endif
6779
6780 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6781 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6782 OS << Msg.str() << '\n';
6783
6784 if (Trace) {
6785 llvm::sys::PrintStackTrace(stderr);
6786 OS << "--------------------------------------------------\n";
6787 }
6788}