blob: be29939b62d23b8c8ec6a734a53a497d32756a4f [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.
David Blaikie6adc78e2013-02-18 22:06:02 +0000772 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
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) {
898 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
899 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) {
1520 if (!SkipResultType && Visit(TL.getResultLoc()))
1521 return true;
1522
1523 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1524 if (Decl *D = TL.getArg(I))
1525 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
Guy Benyei11169dd2012-12-18 14:30:41 +00001545bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1546 TemplateSpecializationTypeLoc TL) {
1547 // Visit the template name.
1548 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1549 TL.getTemplateNameLoc()))
1550 return true;
1551
1552 // Visit the template arguments.
1553 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1554 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1555 return true;
1556
1557 return false;
1558}
1559
1560bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1561 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1562}
1563
1564bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1565 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1566 return Visit(TSInfo->getTypeLoc());
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1579 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1580 return true;
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1586 DependentTemplateSpecializationTypeLoc TL) {
1587 // Visit the nested-name-specifier, if there is one.
1588 if (TL.getQualifierLoc() &&
1589 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1590 return true;
1591
1592 // Visit the template arguments.
1593 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1594 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1601 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1602 return true;
1603
1604 return Visit(TL.getNamedTypeLoc());
1605}
1606
1607bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1608 return Visit(TL.getPatternLoc());
1609}
1610
1611bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1612 if (Expr *E = TL.getUnderlyingExpr())
1613 return Visit(MakeCXCursor(E, StmtParent, TU));
1614
1615 return false;
1616}
1617
1618bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1619 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1620}
1621
1622bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1623 return Visit(TL.getValueLoc());
1624}
1625
1626#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1627bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1628 return Visit##PARENT##Loc(TL); \
1629}
1630
1631DEFAULT_TYPELOC_IMPL(Complex, Type)
1632DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1633DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1634DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1635DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1636DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1637DEFAULT_TYPELOC_IMPL(Vector, Type)
1638DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1639DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1640DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1641DEFAULT_TYPELOC_IMPL(Record, TagType)
1642DEFAULT_TYPELOC_IMPL(Enum, TagType)
1643DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1644DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1645DEFAULT_TYPELOC_IMPL(Auto, Type)
1646
1647bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1648 // Visit the nested-name-specifier, if present.
1649 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1650 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1651 return true;
1652
1653 if (D->isCompleteDefinition()) {
1654 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1655 E = D->bases_end(); I != E; ++I) {
1656 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1657 return true;
1658 }
1659 }
1660
1661 return VisitTagDecl(D);
1662}
1663
1664bool CursorVisitor::VisitAttributes(Decl *D) {
1665 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1666 i != e; ++i)
1667 if (Visit(MakeCXCursor(*i, D, TU)))
1668 return true;
1669
1670 return false;
1671}
1672
1673//===----------------------------------------------------------------------===//
1674// Data-recursive visitor methods.
1675//===----------------------------------------------------------------------===//
1676
1677namespace {
1678#define DEF_JOB(NAME, DATA, KIND)\
1679class NAME : public VisitorJob {\
1680public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001681 NAME(const DATA *d, CXCursor parent) : \
1682 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001683 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001684 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001685};
1686
1687DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1688DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1689DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1690DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1691DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1692 ExplicitTemplateArgsVisitKind)
1693DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1694DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1695DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1696#undef DEF_JOB
1697
1698class DeclVisit : public VisitorJob {
1699public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001700 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001701 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001702 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001703 static bool classof(const VisitorJob *VJ) {
1704 return VJ->getKind() == DeclVisitKind;
1705 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001706 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 bool isFirst() const { return data[1] ? true : false; }
1708};
1709class TypeLocVisit : public VisitorJob {
1710public:
1711 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1712 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1713 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1714
1715 static bool classof(const VisitorJob *VJ) {
1716 return VJ->getKind() == TypeLocVisitKind;
1717 }
1718
1719 TypeLoc get() const {
1720 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 }
1723};
1724
1725class LabelRefVisit : public VisitorJob {
1726public:
1727 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1728 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1729 labelLoc.getPtrEncoding()) {}
1730
1731 static bool classof(const VisitorJob *VJ) {
1732 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1733 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 const LabelDecl *get() const {
1735 return static_cast<const LabelDecl *>(data[0]);
1736 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001737 SourceLocation getLoc() const {
1738 return SourceLocation::getFromPtrEncoding(data[1]); }
1739};
1740
1741class NestedNameSpecifierLocVisit : public VisitorJob {
1742public:
1743 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1744 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1745 Qualifier.getNestedNameSpecifier(),
1746 Qualifier.getOpaqueData()) { }
1747
1748 static bool classof(const VisitorJob *VJ) {
1749 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1750 }
1751
1752 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001753 return NestedNameSpecifierLoc(
1754 const_cast<NestedNameSpecifier *>(
1755 static_cast<const NestedNameSpecifier *>(data[0])),
1756 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 }
1758};
1759
1760class DeclarationNameInfoVisit : public VisitorJob {
1761public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001763 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001764 static bool classof(const VisitorJob *VJ) {
1765 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1766 }
1767 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001768 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 switch (S->getStmtClass()) {
1770 default:
1771 llvm_unreachable("Unhandled Stmt");
1772 case clang::Stmt::MSDependentExistsStmtClass:
1773 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1774 case Stmt::CXXDependentScopeMemberExprClass:
1775 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1776 case Stmt::DependentScopeDeclRefExprClass:
1777 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1778 }
1779 }
1780};
1781class MemberRefVisit : public VisitorJob {
1782public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001784 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1785 L.getPtrEncoding()) {}
1786 static bool classof(const VisitorJob *VJ) {
1787 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1788 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001789 const FieldDecl *get() const {
1790 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001791 }
1792 SourceLocation getLoc() const {
1793 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1794 }
1795};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001796class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001797 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001798 VisitorWorkList &WL;
1799 CXCursor Parent;
1800public:
1801 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1802 : WL(wl), Parent(parent) {}
1803
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1805 void VisitBlockExpr(const BlockExpr *B);
1806 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1807 void VisitCompoundStmt(const CompoundStmt *S);
1808 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1809 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1810 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1811 void VisitCXXNewExpr(const CXXNewExpr *E);
1812 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1813 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1814 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1815 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1816 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1817 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1818 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1819 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1820 void VisitDeclRefExpr(const DeclRefExpr *D);
1821 void VisitDeclStmt(const DeclStmt *S);
1822 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1823 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1824 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1825 void VisitForStmt(const ForStmt *FS);
1826 void VisitGotoStmt(const GotoStmt *GS);
1827 void VisitIfStmt(const IfStmt *If);
1828 void VisitInitListExpr(const InitListExpr *IE);
1829 void VisitMemberExpr(const MemberExpr *M);
1830 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1831 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1832 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1833 void VisitOverloadExpr(const OverloadExpr *E);
1834 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1835 void VisitStmt(const Stmt *S);
1836 void VisitSwitchStmt(const SwitchStmt *S);
1837 void VisitWhileStmt(const WhileStmt *W);
1838 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1839 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1840 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1841 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1842 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1843 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1844 void VisitVAArgExpr(const VAArgExpr *E);
1845 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1846 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1847 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1848 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001849 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1850 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851
Guy Benyei11169dd2012-12-18 14:30:41 +00001852private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001854 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1855 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1857 void AddStmt(const Stmt *S);
1858 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001861 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862};
1863} // end anonyous namespace
1864
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 // 'S' should always be non-null, since it comes from the
1867 // statement we are visiting.
1868 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1869}
1870
1871void
1872EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1873 if (Qualifier)
1874 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1875}
1876
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 if (S)
1879 WL.push_back(StmtVisit(S, Parent));
1880}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (D)
1883 WL.push_back(DeclVisit(D, Parent, isFirst));
1884}
1885void EnqueueVisitor::
1886 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1887 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001889}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 if (D)
1892 WL.push_back(MemberRefVisit(D, L, Parent));
1893}
1894void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1895 if (TI)
1896 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1897 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 AddStmt(*Child);
1902 }
1903 if (size == WL.size())
1904 return;
1905 // Now reverse the entries we just added. This will match the DFS
1906 // ordering performed by the worklist.
1907 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1908 std::reverse(I, E);
1909}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001910namespace {
1911class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1912 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001913 /// \brief Process clauses with list of variables.
1914 template <typename T>
1915 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001916public:
1917 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1918#define OPENMP_CLAUSE(Name, Class) \
1919 void Visit##Class(const Class *C);
1920#include "clang/Basic/OpenMPKinds.def"
1921};
1922
1923void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001924
1925template<typename T>
1926void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1927 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1928 E = Node->varlist_end();
1929 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001930 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001931}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932
1933void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001934 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001936void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1937 const OMPFirstprivateClause *C) {
1938 VisitOMPClauseList(C);
1939}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001940void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001941 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001942}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001943}
Alexey Bataev756c1962013-09-24 03:17:45 +00001944
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1946 unsigned size = WL.size();
1947 OMPClauseEnqueue Visitor(this);
1948 Visitor.Visit(S);
1949 if (size == WL.size())
1950 return;
1951 // Now reverse the entries we just added. This will match the DFS
1952 // ordering performed by the worklist.
1953 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1954 std::reverse(I, E);
1955}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001956void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001957 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1958}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001959void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 AddDecl(B->getBlockDecl());
1961}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 EnqueueChildren(E);
1964 AddTypeLoc(E->getTypeSourceInfo());
1965}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001966void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1967 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001968 E = S->body_rend(); I != E; ++I) {
1969 AddStmt(*I);
1970 }
1971}
1972void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 AddStmt(S->getSubStmt());
1975 AddDeclarationNameInfo(S);
1976 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1977 AddNestedNameSpecifierLoc(QualifierLoc);
1978}
1979
1980void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1983 AddDeclarationNameInfo(E);
1984 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1985 AddNestedNameSpecifierLoc(QualifierLoc);
1986 if (!E->isImplicitAccess())
1987 AddStmt(E->getBase());
1988}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 // Enqueue the initializer , if any.
1991 AddStmt(E->getInitializer());
1992 // Enqueue the array size, if any.
1993 AddStmt(E->getArraySize());
1994 // Enqueue the allocated type.
1995 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1996 // Enqueue the placement arguments.
1997 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1998 AddStmt(E->getPlacementArg(I-1));
1999}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002001 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2002 AddStmt(CE->getArg(I-1));
2003 AddStmt(CE->getCallee());
2004 AddStmt(CE->getArg(0));
2005}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002006void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2007 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 // Visit the name of the type being destroyed.
2009 AddTypeLoc(E->getDestroyedTypeInfo());
2010 // Visit the scope type that looks disturbingly like the nested-name-specifier
2011 // but isn't.
2012 AddTypeLoc(E->getScopeTypeInfo());
2013 // Visit the nested-name-specifier.
2014 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2015 AddNestedNameSpecifierLoc(QualifierLoc);
2016 // Visit base expression.
2017 AddStmt(E->getBase());
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2020 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 AddTypeLoc(E->getTypeSourceInfo());
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2024 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 EnqueueChildren(E);
2026 AddTypeLoc(E->getTypeSourceInfo());
2027}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 EnqueueChildren(E);
2030 if (E->isTypeOperand())
2031 AddTypeLoc(E->getTypeOperandSourceInfo());
2032}
2033
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2035 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 EnqueueChildren(E);
2037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 EnqueueChildren(E);
2041 if (E->isTypeOperand())
2042 AddTypeLoc(E->getTypeOperandSourceInfo());
2043}
2044
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 EnqueueChildren(S);
2047 AddDecl(S->getExceptionDecl());
2048}
2049
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 if (DR->hasExplicitTemplateArgs()) {
2052 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2053 }
2054 WL.push_back(DeclRefExprParts(DR, Parent));
2055}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2057 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2059 AddDeclarationNameInfo(E);
2060 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 unsigned size = WL.size();
2064 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 D != DEnd; ++D) {
2067 AddDecl(*D, isFirst);
2068 isFirst = false;
2069 }
2070 if (size == WL.size())
2071 return;
2072 // Now reverse the entries we just added. This will match the DFS
2073 // ordering performed by the worklist.
2074 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2075 std::reverse(I, E);
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 D = E->designators_rbegin(), DEnd = E->designators_rend();
2081 D != DEnd; ++D) {
2082 if (D->isFieldDesignator()) {
2083 if (FieldDecl *Field = D->getField())
2084 AddMemberRef(Field, D->getFieldLoc());
2085 continue;
2086 }
2087 if (D->isArrayDesignator()) {
2088 AddStmt(E->getArrayIndex(*D));
2089 continue;
2090 }
2091 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2092 AddStmt(E->getArrayRangeEnd(*D));
2093 AddStmt(E->getArrayRangeStart(*D));
2094 }
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 AddTypeLoc(E->getTypeInfoAsWritten());
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 AddStmt(FS->getBody());
2102 AddStmt(FS->getInc());
2103 AddStmt(FS->getCond());
2104 AddDecl(FS->getConditionVariable());
2105 AddStmt(FS->getInit());
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddStmt(If->getElse());
2112 AddStmt(If->getThen());
2113 AddStmt(If->getCond());
2114 AddDecl(If->getConditionVariable());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 // We care about the syntactic form of the initializer list, only.
2118 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2119 IE = Syntactic;
2120 EnqueueChildren(IE);
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 WL.push_back(MemberExprParts(M, Parent));
2124
2125 // If the base of the member access expression is an implicit 'this', don't
2126 // visit it.
2127 // FIXME: If we ever want to show these implicit accesses, this will be
2128 // unfortunate. However, clang_getCursor() relies on this behavior.
2129 if (!M->isImplicitAccess())
2130 AddStmt(M->getBase());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 AddTypeLoc(E->getEncodedTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(M);
2137 AddTypeLoc(M->getClassReceiverTypeInfo());
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 // Visit the components of the offsetof expression.
2141 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2142 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2143 const OffsetOfNode &Node = E->getComponent(I-1);
2144 switch (Node.getKind()) {
2145 case OffsetOfNode::Array:
2146 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2147 break;
2148 case OffsetOfNode::Field:
2149 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2150 break;
2151 case OffsetOfNode::Identifier:
2152 case OffsetOfNode::Base:
2153 continue;
2154 }
2155 }
2156 // Visit the type into which we're computing the offset.
2157 AddTypeLoc(E->getTypeSourceInfo());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2161 WL.push_back(OverloadExprParts(E, Parent));
2162}
2163void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 EnqueueChildren(E);
2166 if (E->isArgumentType())
2167 AddTypeLoc(E->getArgumentTypeInfo());
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 EnqueueChildren(S);
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 AddStmt(S->getBody());
2174 AddStmt(S->getCond());
2175 AddDecl(S->getConditionVariable());
2176}
2177
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddStmt(W->getBody());
2180 AddStmt(W->getCond());
2181 AddDecl(W->getConditionVariable());
2182}
2183
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 AddTypeLoc(E->getQueriedTypeSourceInfo());
2186}
2187
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddTypeLoc(E->getRhsTypeSourceInfo());
2190 AddTypeLoc(E->getLhsTypeSourceInfo());
2191}
2192
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 for (unsigned I = E->getNumArgs(); I > 0; --I)
2195 AddTypeLoc(E->getArg(I-1));
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddTypeLoc(E->getQueriedTypeSourceInfo());
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(E);
2204}
2205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 VisitOverloadExpr(U);
2208 if (!U->isImplicitAccess())
2209 AddStmt(U->getBase());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddStmt(E->getSubExpr());
2213 AddTypeLoc(E->getWrittenTypeInfo());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 WL.push_back(SizeOfPackExprParts(E, Parent));
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // If the opaque value has a source expression, just transparently
2220 // visit that. This is useful for (e.g.) pseudo-object expressions.
2221 if (Expr *SourceExpr = E->getSourceExpr())
2222 return Visit(SourceExpr);
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddStmt(E->getBody());
2226 WL.push_back(LambdaExprParts(E, Parent));
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // Treat the expression like its syntactic form.
2230 Visit(E->getSyntacticForm());
2231}
2232
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002233void EnqueueVisitor::VisitOMPExecutableDirective(
2234 const OMPExecutableDirective *D) {
2235 EnqueueChildren(D);
2236 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2237 E = D->clauses().end();
2238 I != E; ++I)
2239 EnqueueChildren(*I);
2240}
2241
2242void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2243 VisitOMPExecutableDirective(D);
2244}
2245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2248}
2249
2250bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2251 if (RegionOfInterest.isValid()) {
2252 SourceRange Range = getRawCursorExtent(C);
2253 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2254 return false;
2255 }
2256 return true;
2257}
2258
2259bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2260 while (!WL.empty()) {
2261 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002262 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002263
2264 // Set the Parent field, then back to its old value once we're done.
2265 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2266
2267 switch (LI.getKind()) {
2268 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 if (!D)
2271 continue;
2272
2273 // For now, perform default visitation for Decls.
2274 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2275 cast<DeclVisit>(&LI)->isFirst())))
2276 return true;
2277
2278 continue;
2279 }
2280 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2281 const ASTTemplateArgumentListInfo *ArgList =
2282 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2283 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2284 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2285 Arg != ArgEnd; ++Arg) {
2286 if (VisitTemplateArgumentLoc(*Arg))
2287 return true;
2288 }
2289 continue;
2290 }
2291 case VisitorJob::TypeLocVisitKind: {
2292 // Perform default visitation for TypeLocs.
2293 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2294 return true;
2295 continue;
2296 }
2297 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 if (LabelStmt *stmt = LS->getStmt()) {
2300 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2301 TU))) {
2302 return true;
2303 }
2304 }
2305 continue;
2306 }
2307
2308 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2309 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2310 if (VisitNestedNameSpecifierLoc(V->get()))
2311 return true;
2312 continue;
2313 }
2314
2315 case VisitorJob::DeclarationNameInfoVisitKind: {
2316 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2317 ->get()))
2318 return true;
2319 continue;
2320 }
2321 case VisitorJob::MemberRefVisitKind: {
2322 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2323 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2324 return true;
2325 continue;
2326 }
2327 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 if (!S)
2330 continue;
2331
2332 // Update the current cursor.
2333 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2334 if (!IsInRegionOfInterest(Cursor))
2335 continue;
2336 switch (Visitor(Cursor, Parent, ClientData)) {
2337 case CXChildVisit_Break: return true;
2338 case CXChildVisit_Continue: break;
2339 case CXChildVisit_Recurse:
2340 if (PostChildrenVisitor)
2341 WL.push_back(PostChildrenVisit(0, Cursor));
2342 EnqueueWorkList(WL, S);
2343 break;
2344 }
2345 continue;
2346 }
2347 case VisitorJob::MemberExprPartsKind: {
2348 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002349 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002350
2351 // Visit the nested-name-specifier
2352 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2353 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2354 return true;
2355
2356 // Visit the declaration name.
2357 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2358 return true;
2359
2360 // Visit the explicitly-specified template arguments, if any.
2361 if (M->hasExplicitTemplateArgs()) {
2362 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2363 *ArgEnd = Arg + M->getNumTemplateArgs();
2364 Arg != ArgEnd; ++Arg) {
2365 if (VisitTemplateArgumentLoc(*Arg))
2366 return true;
2367 }
2368 }
2369 continue;
2370 }
2371 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 // Visit nested-name-specifier, if present.
2374 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2375 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2376 return true;
2377 // Visit declaration name.
2378 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2379 return true;
2380 continue;
2381 }
2382 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit the nested-name-specifier.
2385 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit the declaration name.
2389 if (VisitDeclarationNameInfo(O->getNameInfo()))
2390 return true;
2391 // Visit the overloaded declaration reference.
2392 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2393 return true;
2394 continue;
2395 }
2396 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 NamedDecl *Pack = E->getPack();
2399 if (isa<TemplateTypeParmDecl>(Pack)) {
2400 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2401 E->getPackLoc(), TU)))
2402 return true;
2403
2404 continue;
2405 }
2406
2407 if (isa<TemplateTemplateParmDecl>(Pack)) {
2408 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2409 E->getPackLoc(), TU)))
2410 return true;
2411
2412 continue;
2413 }
2414
2415 // Non-type template parameter packs and function parameter packs are
2416 // treated like DeclRefExpr cursors.
2417 continue;
2418 }
2419
2420 case VisitorJob::LambdaExprPartsKind: {
2421 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2424 CEnd = E->explicit_capture_end();
2425 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002426 // FIXME: Lambda init-captures.
2427 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002429
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2431 C->getLocation(),
2432 TU)))
2433 return true;
2434 }
2435
2436 // Visit parameters and return type, if present.
2437 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2438 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2439 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2440 // Visit the whole type.
2441 if (Visit(TL))
2442 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002443 } else if (FunctionProtoTypeLoc Proto =
2444 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 if (E->hasExplicitParameters()) {
2446 // Visit parameters.
2447 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2448 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2449 return true;
2450 } else {
2451 // Visit result type.
2452 if (Visit(Proto.getResultLoc()))
2453 return true;
2454 }
2455 }
2456 }
2457 break;
2458 }
2459
2460 case VisitorJob::PostChildrenVisitKind:
2461 if (PostChildrenVisitor(Parent, ClientData))
2462 return true;
2463 break;
2464 }
2465 }
2466 return false;
2467}
2468
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 VisitorWorkList *WL = 0;
2471 if (!WorkListFreeList.empty()) {
2472 WL = WorkListFreeList.back();
2473 WL->clear();
2474 WorkListFreeList.pop_back();
2475 }
2476 else {
2477 WL = new VisitorWorkList();
2478 WorkListCache.push_back(WL);
2479 }
2480 EnqueueWorkList(*WL, S);
2481 bool result = RunVisitorWorkList(*WL);
2482 WorkListFreeList.push_back(WL);
2483 return result;
2484}
2485
2486namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002487typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002488RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2489 const DeclarationNameInfo &NI,
2490 const SourceRange &QLoc,
2491 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2492 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2493 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2494 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2495
2496 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2497
2498 RefNamePieces Pieces;
2499
2500 if (WantQualifier && QLoc.isValid())
2501 Pieces.push_back(QLoc);
2502
2503 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2504 Pieces.push_back(NI.getLoc());
2505
2506 if (WantTemplateArgs && TemplateArgs)
2507 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2508 TemplateArgs->RAngleLoc));
2509
2510 if (Kind == DeclarationName::CXXOperatorName) {
2511 Pieces.push_back(SourceLocation::getFromRawEncoding(
2512 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2513 Pieces.push_back(SourceLocation::getFromRawEncoding(
2514 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2515 }
2516
2517 if (WantSinglePiece) {
2518 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2519 Pieces.clear();
2520 Pieces.push_back(R);
2521 }
2522
2523 return Pieces;
2524}
2525}
2526
2527//===----------------------------------------------------------------------===//
2528// Misc. API hooks.
2529//===----------------------------------------------------------------------===//
2530
2531static llvm::sys::Mutex EnableMultithreadingMutex;
2532static bool EnabledMultithreading;
2533
Chad Rosier05c71aa2013-03-27 18:28:23 +00002534static void fatal_error_handler(void *user_data, const std::string& reason,
2535 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 // Write the result out to stderr avoiding errs() because raw_ostreams can
2537 // call report_fatal_error.
2538 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2539 ::abort();
2540}
2541
2542extern "C" {
2543CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2544 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 // We use crash recovery to make some of our APIs more reliable, implicitly
2546 // enable it.
2547 llvm::CrashRecoveryContext::Enable();
2548
2549 // Enable support for multithreading in LLVM.
2550 {
2551 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2552 if (!EnabledMultithreading) {
2553 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2554 llvm::llvm_start_multithreaded();
2555 EnabledMultithreading = true;
2556 }
2557 }
2558
2559 CIndexer *CIdxr = new CIndexer();
2560 if (excludeDeclarationsFromPCH)
2561 CIdxr->setOnlyLocalDecls();
2562 if (displayDiagnostics)
2563 CIdxr->setDisplayDiagnostics();
2564
2565 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2566 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2567 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2568 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2569 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2570 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2571
2572 return CIdxr;
2573}
2574
2575void clang_disposeIndex(CXIndex CIdx) {
2576 if (CIdx)
2577 delete static_cast<CIndexer *>(CIdx);
2578}
2579
2580void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2581 if (CIdx)
2582 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2583}
2584
2585unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2586 if (CIdx)
2587 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2588 return 0;
2589}
2590
2591void clang_toggleCrashRecovery(unsigned isEnabled) {
2592 if (isEnabled)
2593 llvm::CrashRecoveryContext::Enable();
2594 else
2595 llvm::CrashRecoveryContext::Disable();
2596}
2597
2598CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2599 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002600 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 return 0;
2602
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002603 LOG_FUNC_SECTION {
2604 *Log << ast_filename;
2605 }
2606
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2608 FileSystemOptions FileSystemOpts;
2609
2610 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2611 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2612 CXXIdx->getOnlyLocalDecls(),
2613 0, 0,
2614 /*CaptureDiagnostics=*/true,
2615 /*AllowPCHWithCompilerErrors=*/true,
2616 /*UserFilesAreVolatile=*/true);
2617 return MakeCXTranslationUnit(CXXIdx, TU);
2618}
2619
2620unsigned clang_defaultEditingTranslationUnitOptions() {
2621 return CXTranslationUnit_PrecompiledPreamble |
2622 CXTranslationUnit_CacheCompletionResults;
2623}
2624
2625CXTranslationUnit
2626clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2627 const char *source_filename,
2628 int num_command_line_args,
2629 const char * const *command_line_args,
2630 unsigned num_unsaved_files,
2631 struct CXUnsavedFile *unsaved_files) {
2632 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2633 return clang_parseTranslationUnit(CIdx, source_filename,
2634 command_line_args, num_command_line_args,
2635 unsaved_files, num_unsaved_files,
2636 Options);
2637}
2638
2639struct ParseTranslationUnitInfo {
2640 CXIndex CIdx;
2641 const char *source_filename;
2642 const char *const *command_line_args;
2643 int num_command_line_args;
2644 struct CXUnsavedFile *unsaved_files;
2645 unsigned num_unsaved_files;
2646 unsigned options;
2647 CXTranslationUnit result;
2648};
2649static void clang_parseTranslationUnit_Impl(void *UserData) {
2650 ParseTranslationUnitInfo *PTUI =
2651 static_cast<ParseTranslationUnitInfo*>(UserData);
2652 CXIndex CIdx = PTUI->CIdx;
2653 const char *source_filename = PTUI->source_filename;
2654 const char * const *command_line_args = PTUI->command_line_args;
2655 int num_command_line_args = PTUI->num_command_line_args;
2656 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2657 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2658 unsigned options = PTUI->options;
2659 PTUI->result = 0;
2660
2661 if (!CIdx)
2662 return;
2663
2664 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2665
2666 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2667 setThreadBackgroundPriority();
2668
2669 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2670 // FIXME: Add a flag for modules.
2671 TranslationUnitKind TUKind
2672 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2673 bool CacheCodeCompetionResults
2674 = options & CXTranslationUnit_CacheCompletionResults;
2675 bool IncludeBriefCommentsInCodeCompletion
2676 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2677 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2678 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2679
2680 // Configure the diagnostics.
2681 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002682 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002683
2684 // Recover resources if we crash before exiting this function.
2685 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2686 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2687 DiagCleanup(Diags.getPtr());
2688
2689 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2690 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2691
2692 // Recover resources if we crash before exiting this function.
2693 llvm::CrashRecoveryContextCleanupRegistrar<
2694 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2695
2696 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2697 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2698 const llvm::MemoryBuffer *Buffer
2699 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2700 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2701 Buffer));
2702 }
2703
2704 OwningPtr<std::vector<const char *> >
2705 Args(new std::vector<const char*>());
2706
2707 // Recover resources if we crash before exiting this method.
2708 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2709 ArgsCleanup(Args.get());
2710
2711 // Since the Clang C library is primarily used by batch tools dealing with
2712 // (often very broken) source code, where spell-checking can have a
2713 // significant negative impact on performance (particularly when
2714 // precompiled headers are involved), we disable it by default.
2715 // Only do this if we haven't found a spell-checking-related argument.
2716 bool FoundSpellCheckingArgument = false;
2717 for (int I = 0; I != num_command_line_args; ++I) {
2718 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2719 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2720 FoundSpellCheckingArgument = true;
2721 break;
2722 }
2723 }
2724 if (!FoundSpellCheckingArgument)
2725 Args->push_back("-fno-spell-checking");
2726
2727 Args->insert(Args->end(), command_line_args,
2728 command_line_args + num_command_line_args);
2729
2730 // The 'source_filename' argument is optional. If the caller does not
2731 // specify it then it is assumed that the source file is specified
2732 // in the actual argument list.
2733 // Put the source file after command_line_args otherwise if '-x' flag is
2734 // present it will be unused.
2735 if (source_filename)
2736 Args->push_back(source_filename);
2737
2738 // Do we need the detailed preprocessing record?
2739 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2740 Args->push_back("-Xclang");
2741 Args->push_back("-detailed-preprocessing-record");
2742 }
2743
2744 unsigned NumErrors = Diags->getClient()->getNumErrors();
2745 OwningPtr<ASTUnit> ErrUnit;
2746 OwningPtr<ASTUnit> Unit(
2747 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2748 /* vector::data() not portable */,
2749 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2750 Diags,
2751 CXXIdx->getClangResourcesPath(),
2752 CXXIdx->getOnlyLocalDecls(),
2753 /*CaptureDiagnostics=*/true,
2754 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2755 RemappedFiles->size(),
2756 /*RemappedFilesKeepOriginalName=*/true,
2757 PrecompilePreamble,
2758 TUKind,
2759 CacheCodeCompetionResults,
2760 IncludeBriefCommentsInCodeCompletion,
2761 /*AllowPCHWithCompilerErrors=*/true,
2762 SkipFunctionBodies,
2763 /*UserFilesAreVolatile=*/true,
2764 ForSerialization,
2765 &ErrUnit));
2766
2767 if (NumErrors != Diags->getClient()->getNumErrors()) {
2768 // Make sure to check that 'Unit' is non-NULL.
2769 if (CXXIdx->getDisplayDiagnostics())
2770 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2771 }
2772
2773 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2774}
2775CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2776 const char *source_filename,
2777 const char * const *command_line_args,
2778 int num_command_line_args,
2779 struct CXUnsavedFile *unsaved_files,
2780 unsigned num_unsaved_files,
2781 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002782 LOG_FUNC_SECTION {
2783 *Log << source_filename << ": ";
2784 for (int i = 0; i != num_command_line_args; ++i)
2785 *Log << command_line_args[i] << " ";
2786 }
2787
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2789 num_command_line_args, unsaved_files,
2790 num_unsaved_files, options, 0 };
2791 llvm::CrashRecoveryContext CRC;
2792
2793 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2794 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2795 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2796 fprintf(stderr, " 'command_line_args' : [");
2797 for (int i = 0; i != num_command_line_args; ++i) {
2798 if (i)
2799 fprintf(stderr, ", ");
2800 fprintf(stderr, "'%s'", command_line_args[i]);
2801 }
2802 fprintf(stderr, "],\n");
2803 fprintf(stderr, " 'unsaved_files' : [");
2804 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2805 if (i)
2806 fprintf(stderr, ", ");
2807 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2808 unsaved_files[i].Length);
2809 }
2810 fprintf(stderr, "],\n");
2811 fprintf(stderr, " 'options' : %d,\n", options);
2812 fprintf(stderr, "}\n");
2813
2814 return 0;
2815 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2816 PrintLibclangResourceUsage(PTUI.result);
2817 }
2818
2819 return PTUI.result;
2820}
2821
2822unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2823 return CXSaveTranslationUnit_None;
2824}
2825
2826namespace {
2827
2828struct SaveTranslationUnitInfo {
2829 CXTranslationUnit TU;
2830 const char *FileName;
2831 unsigned options;
2832 CXSaveError result;
2833};
2834
2835}
2836
2837static void clang_saveTranslationUnit_Impl(void *UserData) {
2838 SaveTranslationUnitInfo *STUI =
2839 static_cast<SaveTranslationUnitInfo*>(UserData);
2840
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002841 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2843 setThreadBackgroundPriority();
2844
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002845 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2847}
2848
2849int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2850 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002851 LOG_FUNC_SECTION {
2852 *Log << TU << ' ' << FileName;
2853 }
2854
Guy Benyei11169dd2012-12-18 14:30:41 +00002855 if (!TU)
2856 return CXSaveError_InvalidTU;
2857
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002858 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002859 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2860 if (!CXXUnit->hasSema())
2861 return CXSaveError_InvalidTU;
2862
2863 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2864
2865 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2866 getenv("LIBCLANG_NOTHREADS")) {
2867 clang_saveTranslationUnit_Impl(&STUI);
2868
2869 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2870 PrintLibclangResourceUsage(TU);
2871
2872 return STUI.result;
2873 }
2874
2875 // We have an AST that has invalid nodes due to compiler errors.
2876 // Use a crash recovery thread for protection.
2877
2878 llvm::CrashRecoveryContext CRC;
2879
2880 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2881 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2882 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2883 fprintf(stderr, " 'options' : %d,\n", options);
2884 fprintf(stderr, "}\n");
2885
2886 return CXSaveError_Unknown;
2887
2888 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2889 PrintLibclangResourceUsage(TU);
2890 }
2891
2892 return STUI.result;
2893}
2894
2895void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2896 if (CTUnit) {
2897 // If the translation unit has been marked as unsafe to free, just discard
2898 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002899 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 return;
2901
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002902 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002903 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2905 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002906 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002907 delete CTUnit;
2908 }
2909}
2910
2911unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2912 return CXReparse_None;
2913}
2914
2915struct ReparseTranslationUnitInfo {
2916 CXTranslationUnit TU;
2917 unsigned num_unsaved_files;
2918 struct CXUnsavedFile *unsaved_files;
2919 unsigned options;
2920 int result;
2921};
2922
2923static void clang_reparseTranslationUnit_Impl(void *UserData) {
2924 ReparseTranslationUnitInfo *RTUI =
2925 static_cast<ReparseTranslationUnitInfo*>(UserData);
2926 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002927 if (!TU)
2928 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002929
2930 // Reset the associated diagnostics.
2931 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2932 TU->Diagnostics = 0;
2933
2934 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2935 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2936 unsigned options = RTUI->options;
2937 (void) options;
2938 RTUI->result = 1;
2939
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002940 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002941 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2942 setThreadBackgroundPriority();
2943
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002944 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002945 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2946
2947 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2948 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2949
2950 // Recover resources if we crash before exiting this function.
2951 llvm::CrashRecoveryContextCleanupRegistrar<
2952 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2953
2954 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2955 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2956 const llvm::MemoryBuffer *Buffer
2957 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2958 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2959 Buffer));
2960 }
2961
2962 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2963 RemappedFiles->size()))
2964 RTUI->result = 0;
2965}
2966
2967int clang_reparseTranslationUnit(CXTranslationUnit TU,
2968 unsigned num_unsaved_files,
2969 struct CXUnsavedFile *unsaved_files,
2970 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << TU;
2973 }
2974
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2976 options, 0 };
2977
2978 if (getenv("LIBCLANG_NOTHREADS")) {
2979 clang_reparseTranslationUnit_Impl(&RTUI);
2980 return RTUI.result;
2981 }
2982
2983 llvm::CrashRecoveryContext CRC;
2984
2985 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2986 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002987 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 return 1;
2989 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2990 PrintLibclangResourceUsage(TU);
2991
2992 return RTUI.result;
2993}
2994
2995
2996CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2997 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00002998 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00002999
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003000 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003001 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003002}
3003
3004CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003005 if (!TU)
3006 return clang_getNullCursor();
3007
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3010}
3011
3012} // end: extern "C"
3013
3014//===----------------------------------------------------------------------===//
3015// CXFile Operations.
3016//===----------------------------------------------------------------------===//
3017
3018extern "C" {
3019CXString clang_getFileName(CXFile SFile) {
3020 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003021 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003022
3023 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003024 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003025}
3026
3027time_t clang_getFileTime(CXFile SFile) {
3028 if (!SFile)
3029 return 0;
3030
3031 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3032 return FEnt->getModificationTime();
3033}
3034
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003035CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3036 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 return 0;
3038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003039 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003040
3041 FileManager &FMgr = CXXUnit->getFileManager();
3042 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3043}
3044
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003045unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3046 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 return 0;
3048
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003049 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003050 FileEntry *FEnt = static_cast<FileEntry *>(file);
3051 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3052 .isFileMultipleIncludeGuarded(FEnt);
3053}
3054
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003055int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3056 if (!file || !outID)
3057 return 1;
3058
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003059 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003060 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3061 outID->data[0] = ID.getDevice();
3062 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003063 outID->data[2] = FEnt->getModificationTime();
3064 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003065}
3066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067} // end: extern "C"
3068
3069//===----------------------------------------------------------------------===//
3070// CXCursor Operations.
3071//===----------------------------------------------------------------------===//
3072
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003073static const Decl *getDeclFromExpr(const Stmt *E) {
3074 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 return getDeclFromExpr(CE->getSubExpr());
3076
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003077 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003079 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003081 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003083 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 if (PRE->isExplicitProperty())
3085 return PRE->getExplicitProperty();
3086 // It could be messaging both getter and setter as in:
3087 // ++myobj.myprop;
3088 // in which case prefer to associate the setter since it is less obvious
3089 // from inspecting the source that the setter is going to get called.
3090 if (PRE->isMessagingSetter())
3091 return PRE->getImplicitPropertySetter();
3092 return PRE->getImplicitPropertyGetter();
3093 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003094 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003096 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 if (Expr *Src = OVE->getSourceExpr())
3098 return getDeclFromExpr(Src);
3099
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003100 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003102 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 if (!CE->isElidable())
3104 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003105 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 return OME->getMethodDecl();
3107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003108 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003110 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3112 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003113 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3115 isa<ParmVarDecl>(SizeOfPack->getPack()))
3116 return SizeOfPack->getPack();
3117
3118 return 0;
3119}
3120
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003121static SourceLocation getLocationFromExpr(const Expr *E) {
3122 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 return getLocationFromExpr(CE->getSubExpr());
3124
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003125 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003127 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003129 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003131 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003133 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003135 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 return PropRef->getLocation();
3137
3138 return E->getLocStart();
3139}
3140
3141extern "C" {
3142
3143unsigned clang_visitChildren(CXCursor parent,
3144 CXCursorVisitor visitor,
3145 CXClientData client_data) {
3146 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3147 /*VisitPreprocessorLast=*/false);
3148 return CursorVis.VisitChildren(parent);
3149}
3150
3151#ifndef __has_feature
3152#define __has_feature(x) 0
3153#endif
3154#if __has_feature(blocks)
3155typedef enum CXChildVisitResult
3156 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3157
3158static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3159 CXClientData client_data) {
3160 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3161 return block(cursor, parent);
3162}
3163#else
3164// If we are compiled with a compiler that doesn't have native blocks support,
3165// define and call the block manually, so the
3166typedef struct _CXChildVisitResult
3167{
3168 void *isa;
3169 int flags;
3170 int reserved;
3171 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3172 CXCursor);
3173} *CXCursorVisitorBlock;
3174
3175static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3176 CXClientData client_data) {
3177 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3178 return block->invoke(block, cursor, parent);
3179}
3180#endif
3181
3182
3183unsigned clang_visitChildrenWithBlock(CXCursor parent,
3184 CXCursorVisitorBlock block) {
3185 return clang_visitChildren(parent, visitWithBlock, block);
3186}
3187
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003190 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const ObjCPropertyImplDecl *PropImpl =
3195 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003197 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003201 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003202
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003203 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 }
3205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003206 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003207 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003209 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3211 // and returns different names. NamedDecl returns the class name and
3212 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003213 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003214
3215 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003216 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003217
3218 SmallString<1024> S;
3219 llvm::raw_svector_ostream os(S);
3220 ND->printName(os);
3221
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003222 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003223}
3224
3225CXString clang_getCursorSpelling(CXCursor C) {
3226 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003227 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003228
3229 if (clang_isReference(C.kind)) {
3230 switch (C.kind) {
3231 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003232 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003233 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 }
3235 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003236 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003237 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 }
3239 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003240 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003242 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 }
3244 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003245 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003246 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 }
3248 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003249 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 assert(Type && "Missing type decl");
3251
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003252 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 getAsString());
3254 }
3255 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003256 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 assert(Template && "Missing template decl");
3258
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003259 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 }
3261
3262 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003263 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 assert(NS && "Missing namespace decl");
3265
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003266 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 }
3268
3269 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003270 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 assert(Field && "Missing member decl");
3272
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003273 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 }
3275
3276 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003277 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 assert(Label && "Missing label");
3279
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003280 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 }
3282
3283 case CXCursor_OverloadedDeclRef: {
3284 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3286 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003287 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003288 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003291 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 OverloadedTemplateStorage *Ovl
3293 = Storage.get<OverloadedTemplateStorage*>();
3294 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003295 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 }
3298
3299 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003300 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 assert(Var && "Missing variable decl");
3302
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003303 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 }
3305
3306 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003307 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 }
3309 }
3310
3311 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 if (D)
3314 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003315 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
3317
3318 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003319 const Stmt *S = getCursorStmt(C);
3320 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003323 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
3325
3326 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003327 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 ->getNameStart());
3329
3330 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003331 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 ->getNameStart());
3333
3334 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336
3337 if (clang_isDeclaration(C.kind))
3338 return getDeclSpelling(getCursorDecl(C));
3339
3340 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003341 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 }
3344
3345 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003346 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003350 if (C.kind == CXCursor_PackedAttr) {
3351 return cxstring::createRef("packed");
3352 }
3353
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003354 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003355}
3356
3357CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3358 unsigned pieceIndex,
3359 unsigned options) {
3360 if (clang_Cursor_isNull(C))
3361 return clang_getNullRange();
3362
3363 ASTContext &Ctx = getCursorContext(C);
3364
3365 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003366 const Stmt *S = getCursorStmt(C);
3367 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 if (pieceIndex > 0)
3369 return clang_getNullRange();
3370 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3371 }
3372
3373 return clang_getNullRange();
3374 }
3375
3376 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003377 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3379 if (pieceIndex >= ME->getNumSelectorLocs())
3380 return clang_getNullRange();
3381 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3382 }
3383 }
3384
3385 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3386 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003387 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3389 if (pieceIndex >= MD->getNumSelectorLocs())
3390 return clang_getNullRange();
3391 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3392 }
3393 }
3394
3395 if (C.kind == CXCursor_ObjCCategoryDecl ||
3396 C.kind == CXCursor_ObjCCategoryImplDecl) {
3397 if (pieceIndex > 0)
3398 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003399 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3401 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003402 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3404 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3405 }
3406
3407 if (C.kind == CXCursor_ModuleImportDecl) {
3408 if (pieceIndex > 0)
3409 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 if (const ImportDecl *ImportD =
3411 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3413 if (!Locs.empty())
3414 return cxloc::translateSourceRange(Ctx,
3415 SourceRange(Locs.front(), Locs.back()));
3416 }
3417 return clang_getNullRange();
3418 }
3419
3420 // FIXME: A CXCursor_InclusionDirective should give the location of the
3421 // filename, but we don't keep track of this.
3422
3423 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3424 // but we don't keep track of this.
3425
3426 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3427 // but we don't keep track of this.
3428
3429 // Default handling, give the location of the cursor.
3430
3431 if (pieceIndex > 0)
3432 return clang_getNullRange();
3433
3434 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3435 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3436 return cxloc::translateSourceRange(Ctx, Loc);
3437}
3438
3439CXString clang_getCursorDisplayName(CXCursor C) {
3440 if (!clang_isDeclaration(C.kind))
3441 return clang_getCursorSpelling(C);
3442
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003443 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003445 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003446
3447 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003448 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 D = FunTmpl->getTemplatedDecl();
3450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 SmallString<64> Str;
3453 llvm::raw_svector_ostream OS(Str);
3454 OS << *Function;
3455 if (Function->getPrimaryTemplate())
3456 OS << "<>";
3457 OS << "(";
3458 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3459 if (I)
3460 OS << ", ";
3461 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3462 }
3463
3464 if (Function->isVariadic()) {
3465 if (Function->getNumParams())
3466 OS << ", ";
3467 OS << "...";
3468 }
3469 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003470 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 }
3472
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 SmallString<64> Str;
3475 llvm::raw_svector_ostream OS(Str);
3476 OS << *ClassTemplate;
3477 OS << "<";
3478 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3479 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3480 if (I)
3481 OS << ", ";
3482
3483 NamedDecl *Param = Params->getParam(I);
3484 if (Param->getIdentifier()) {
3485 OS << Param->getIdentifier()->getName();
3486 continue;
3487 }
3488
3489 // There is no parameter name, which makes this tricky. Try to come up
3490 // with something useful that isn't too long.
3491 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3492 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3493 else if (NonTypeTemplateParmDecl *NTTP
3494 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3495 OS << NTTP->getType().getAsString(Policy);
3496 else
3497 OS << "template<...> class";
3498 }
3499
3500 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003501 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 }
3503
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3506 // If the type was explicitly written, use that.
3507 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003509
Benjamin Kramer9170e912013-02-22 15:46:01 +00003510 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 llvm::raw_svector_ostream OS(Str);
3512 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003513 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 ClassSpec->getTemplateArgs().data(),
3515 ClassSpec->getTemplateArgs().size(),
3516 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003517 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 }
3519
3520 return clang_getCursorSpelling(C);
3521}
3522
3523CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3524 switch (Kind) {
3525 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003528 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003530 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003536 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003540 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003546 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003564 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003568 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003572 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003576 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003580 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003586 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003588 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003592 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003596 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003598 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003600 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003604 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003606 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003608 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003653 case CXCursor_ObjCSelfExpr:
3654 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003771 case CXCursor_PackedAttr:
3772 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003821 case CXCursor_OMPParallelDirective:
3822 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 }
3824
3825 llvm_unreachable("Unhandled CXCursorKind");
3826}
3827
3828struct GetCursorData {
3829 SourceLocation TokenBeginLoc;
3830 bool PointsAtMacroArgExpansion;
3831 bool VisitedObjCPropertyImplDecl;
3832 SourceLocation VisitedDeclaratorDeclStartLoc;
3833 CXCursor &BestCursor;
3834
3835 GetCursorData(SourceManager &SM,
3836 SourceLocation tokenBegin, CXCursor &outputCursor)
3837 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3838 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3839 VisitedObjCPropertyImplDecl = false;
3840 }
3841};
3842
3843static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3844 CXCursor parent,
3845 CXClientData client_data) {
3846 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3847 CXCursor *BestCursor = &Data->BestCursor;
3848
3849 // If we point inside a macro argument we should provide info of what the
3850 // token is so use the actual cursor, don't replace it with a macro expansion
3851 // cursor.
3852 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3853 return CXChildVisit_Recurse;
3854
3855 if (clang_isDeclaration(cursor.kind)) {
3856 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003857 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3859 if (MD->isImplicit())
3860 return CXChildVisit_Break;
3861
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003862 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3864 // Check that when we have multiple @class references in the same line,
3865 // that later ones do not override the previous ones.
3866 // If we have:
3867 // @class Foo, Bar;
3868 // source ranges for both start at '@', so 'Bar' will end up overriding
3869 // 'Foo' even though the cursor location was at 'Foo'.
3870 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3871 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003872 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3874 if (PrevID != ID &&
3875 !PrevID->isThisDeclarationADefinition() &&
3876 !ID->isThisDeclarationADefinition())
3877 return CXChildVisit_Break;
3878 }
3879
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003880 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3882 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3883 // Check that when we have multiple declarators in the same line,
3884 // that later ones do not override the previous ones.
3885 // If we have:
3886 // int Foo, Bar;
3887 // source ranges for both start at 'int', so 'Bar' will end up overriding
3888 // 'Foo' even though the cursor location was at 'Foo'.
3889 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3890 return CXChildVisit_Break;
3891 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003893 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3895 (void)PropImp;
3896 // Check that when we have multiple @synthesize in the same line,
3897 // that later ones do not override the previous ones.
3898 // If we have:
3899 // @synthesize Foo, Bar;
3900 // source ranges for both start at '@', so 'Bar' will end up overriding
3901 // 'Foo' even though the cursor location was at 'Foo'.
3902 if (Data->VisitedObjCPropertyImplDecl)
3903 return CXChildVisit_Break;
3904 Data->VisitedObjCPropertyImplDecl = true;
3905 }
3906 }
3907
3908 if (clang_isExpression(cursor.kind) &&
3909 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003910 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 // Avoid having the cursor of an expression replace the declaration cursor
3912 // when the expression source range overlaps the declaration range.
3913 // This can happen for C++ constructor expressions whose range generally
3914 // include the variable declaration, e.g.:
3915 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3916 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3917 D->getLocation() == Data->TokenBeginLoc)
3918 return CXChildVisit_Break;
3919 }
3920 }
3921
3922 // If our current best cursor is the construction of a temporary object,
3923 // don't replace that cursor with a type reference, because we want
3924 // clang_getCursor() to point at the constructor.
3925 if (clang_isExpression(BestCursor->kind) &&
3926 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3927 cursor.kind == CXCursor_TypeRef) {
3928 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3929 // as having the actual point on the type reference.
3930 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3931 return CXChildVisit_Recurse;
3932 }
3933
3934 *BestCursor = cursor;
3935 return CXChildVisit_Recurse;
3936}
3937
3938CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3939 if (!TU)
3940 return clang_getNullCursor();
3941
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003942 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3944
3945 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3946 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3947
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003948 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 CXFile SearchFile;
3950 unsigned SearchLine, SearchColumn;
3951 CXFile ResultFile;
3952 unsigned ResultLine, ResultColumn;
3953 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3954 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3955 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3956
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003957 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3958 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 &ResultColumn, 0);
3960 SearchFileName = clang_getFileName(SearchFile);
3961 ResultFileName = clang_getFileName(ResultFile);
3962 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3963 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003964 *Log << llvm::format("(%s:%d:%d) = %s",
3965 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3966 clang_getCString(KindSpelling))
3967 << llvm::format("(%s:%d:%d):%s%s",
3968 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3969 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 clang_disposeString(SearchFileName);
3971 clang_disposeString(ResultFileName);
3972 clang_disposeString(KindSpelling);
3973 clang_disposeString(USR);
3974
3975 CXCursor Definition = clang_getCursorDefinition(Result);
3976 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3977 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3978 CXString DefinitionKindSpelling
3979 = clang_getCursorKindSpelling(Definition.kind);
3980 CXFile DefinitionFile;
3981 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003982 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 &DefinitionLine, &DefinitionColumn, 0);
3984 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003985 *Log << llvm::format(" -> %s(%s:%d:%d)",
3986 clang_getCString(DefinitionKindSpelling),
3987 clang_getCString(DefinitionFileName),
3988 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 clang_disposeString(DefinitionFileName);
3990 clang_disposeString(DefinitionKindSpelling);
3991 }
3992 }
3993
3994 return Result;
3995}
3996
3997CXCursor clang_getNullCursor(void) {
3998 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3999}
4000
4001unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004002 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4003 // can't set consistently. For example, when visiting a DeclStmt we will set
4004 // it but we don't set it on the result of clang_getCursorDefinition for
4005 // a reference of the same declaration.
4006 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4007 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4008 // to provide that kind of info.
4009 if (clang_isDeclaration(X.kind))
4010 X.data[1] = 0;
4011 if (clang_isDeclaration(Y.kind))
4012 Y.data[1] = 0;
4013
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 return X == Y;
4015}
4016
4017unsigned clang_hashCursor(CXCursor C) {
4018 unsigned Index = 0;
4019 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4020 Index = 1;
4021
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004022 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 std::make_pair(C.kind, C.data[Index]));
4024}
4025
4026unsigned clang_isInvalid(enum CXCursorKind K) {
4027 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4028}
4029
4030unsigned clang_isDeclaration(enum CXCursorKind K) {
4031 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4032 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4033}
4034
4035unsigned clang_isReference(enum CXCursorKind K) {
4036 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4037}
4038
4039unsigned clang_isExpression(enum CXCursorKind K) {
4040 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4041}
4042
4043unsigned clang_isStatement(enum CXCursorKind K) {
4044 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4045}
4046
4047unsigned clang_isAttribute(enum CXCursorKind K) {
4048 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4049}
4050
4051unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4052 return K == CXCursor_TranslationUnit;
4053}
4054
4055unsigned clang_isPreprocessing(enum CXCursorKind K) {
4056 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4057}
4058
4059unsigned clang_isUnexposed(enum CXCursorKind K) {
4060 switch (K) {
4061 case CXCursor_UnexposedDecl:
4062 case CXCursor_UnexposedExpr:
4063 case CXCursor_UnexposedStmt:
4064 case CXCursor_UnexposedAttr:
4065 return true;
4066 default:
4067 return false;
4068 }
4069}
4070
4071CXCursorKind clang_getCursorKind(CXCursor C) {
4072 return C.kind;
4073}
4074
4075CXSourceLocation clang_getCursorLocation(CXCursor C) {
4076 if (clang_isReference(C.kind)) {
4077 switch (C.kind) {
4078 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004079 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 = getCursorObjCSuperClassRef(C);
4081 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4082 }
4083
4084 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004085 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 = getCursorObjCProtocolRef(C);
4087 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4088 }
4089
4090 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004091 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 = getCursorObjCClassRef(C);
4093 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4094 }
4095
4096 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004097 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 std::pair<const TemplateDecl *, SourceLocation> P =
4103 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4105 }
4106
4107 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004108 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4110 }
4111
4112 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4115 }
4116
4117 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004118 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4120 }
4121
4122 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 if (!BaseSpec)
4125 return clang_getNullLocation();
4126
4127 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4128 return cxloc::translateSourceLocation(getCursorContext(C),
4129 TSInfo->getTypeLoc().getBeginLoc());
4130
4131 return cxloc::translateSourceLocation(getCursorContext(C),
4132 BaseSpec->getLocStart());
4133 }
4134
4135 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004136 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4138 }
4139
4140 case CXCursor_OverloadedDeclRef:
4141 return cxloc::translateSourceLocation(getCursorContext(C),
4142 getCursorOverloadedDeclRef(C).second);
4143
4144 default:
4145 // FIXME: Need a way to enumerate all non-reference cases.
4146 llvm_unreachable("Missed a reference kind");
4147 }
4148 }
4149
4150 if (clang_isExpression(C.kind))
4151 return cxloc::translateSourceLocation(getCursorContext(C),
4152 getLocationFromExpr(getCursorExpr(C)));
4153
4154 if (clang_isStatement(C.kind))
4155 return cxloc::translateSourceLocation(getCursorContext(C),
4156 getCursorStmt(C)->getLocStart());
4157
4158 if (C.kind == CXCursor_PreprocessingDirective) {
4159 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4160 return cxloc::translateSourceLocation(getCursorContext(C), L);
4161 }
4162
4163 if (C.kind == CXCursor_MacroExpansion) {
4164 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004165 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 return cxloc::translateSourceLocation(getCursorContext(C), L);
4167 }
4168
4169 if (C.kind == CXCursor_MacroDefinition) {
4170 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
4174 if (C.kind == CXCursor_InclusionDirective) {
4175 SourceLocation L
4176 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4177 return cxloc::translateSourceLocation(getCursorContext(C), L);
4178 }
4179
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004180 if (clang_isAttribute(C.kind)) {
4181 SourceLocation L
4182 = cxcursor::getCursorAttr(C)->getLocation();
4183 return cxloc::translateSourceLocation(getCursorContext(C), L);
4184 }
4185
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 if (!clang_isDeclaration(C.kind))
4187 return clang_getNullLocation();
4188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004189 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 if (!D)
4191 return clang_getNullLocation();
4192
4193 SourceLocation Loc = D->getLocation();
4194 // FIXME: Multiple variables declared in a single declaration
4195 // currently lack the information needed to correctly determine their
4196 // ranges when accounting for the type-specifier. We use context
4197 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4198 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004199 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 if (!cxcursor::isFirstInDeclGroup(C))
4201 Loc = VD->getLocation();
4202 }
4203
4204 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004205 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 Loc = MD->getSelectorStartLoc();
4207
4208 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4209}
4210
4211} // end extern "C"
4212
4213CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4214 assert(TU);
4215
4216 // Guard against an invalid SourceLocation, or we may assert in one
4217 // of the following calls.
4218 if (SLoc.isInvalid())
4219 return clang_getNullCursor();
4220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222
4223 // Translate the given source location to make it point at the beginning of
4224 // the token under the cursor.
4225 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4226 CXXUnit->getASTContext().getLangOpts());
4227
4228 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4229 if (SLoc.isValid()) {
4230 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4231 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4232 /*VisitPreprocessorLast=*/true,
4233 /*VisitIncludedEntities=*/false,
4234 SourceLocation(SLoc));
4235 CursorVis.visitFileRegion();
4236 }
4237
4238 return Result;
4239}
4240
4241static SourceRange getRawCursorExtent(CXCursor C) {
4242 if (clang_isReference(C.kind)) {
4243 switch (C.kind) {
4244 case CXCursor_ObjCSuperClassRef:
4245 return getCursorObjCSuperClassRef(C).second;
4246
4247 case CXCursor_ObjCProtocolRef:
4248 return getCursorObjCProtocolRef(C).second;
4249
4250 case CXCursor_ObjCClassRef:
4251 return getCursorObjCClassRef(C).second;
4252
4253 case CXCursor_TypeRef:
4254 return getCursorTypeRef(C).second;
4255
4256 case CXCursor_TemplateRef:
4257 return getCursorTemplateRef(C).second;
4258
4259 case CXCursor_NamespaceRef:
4260 return getCursorNamespaceRef(C).second;
4261
4262 case CXCursor_MemberRef:
4263 return getCursorMemberRef(C).second;
4264
4265 case CXCursor_CXXBaseSpecifier:
4266 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4267
4268 case CXCursor_LabelRef:
4269 return getCursorLabelRef(C).second;
4270
4271 case CXCursor_OverloadedDeclRef:
4272 return getCursorOverloadedDeclRef(C).second;
4273
4274 case CXCursor_VariableRef:
4275 return getCursorVariableRef(C).second;
4276
4277 default:
4278 // FIXME: Need a way to enumerate all non-reference cases.
4279 llvm_unreachable("Missed a reference kind");
4280 }
4281 }
4282
4283 if (clang_isExpression(C.kind))
4284 return getCursorExpr(C)->getSourceRange();
4285
4286 if (clang_isStatement(C.kind))
4287 return getCursorStmt(C)->getSourceRange();
4288
4289 if (clang_isAttribute(C.kind))
4290 return getCursorAttr(C)->getRange();
4291
4292 if (C.kind == CXCursor_PreprocessingDirective)
4293 return cxcursor::getCursorPreprocessingDirective(C);
4294
4295 if (C.kind == CXCursor_MacroExpansion) {
4296 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004297 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 return TU->mapRangeFromPreamble(Range);
4299 }
4300
4301 if (C.kind == CXCursor_MacroDefinition) {
4302 ASTUnit *TU = getCursorASTUnit(C);
4303 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4304 return TU->mapRangeFromPreamble(Range);
4305 }
4306
4307 if (C.kind == CXCursor_InclusionDirective) {
4308 ASTUnit *TU = getCursorASTUnit(C);
4309 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4310 return TU->mapRangeFromPreamble(Range);
4311 }
4312
4313 if (C.kind == CXCursor_TranslationUnit) {
4314 ASTUnit *TU = getCursorASTUnit(C);
4315 FileID MainID = TU->getSourceManager().getMainFileID();
4316 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4317 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4318 return SourceRange(Start, End);
4319 }
4320
4321 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 if (!D)
4324 return SourceRange();
4325
4326 SourceRange R = D->getSourceRange();
4327 // FIXME: Multiple variables declared in a single declaration
4328 // currently lack the information needed to correctly determine their
4329 // ranges when accounting for the type-specifier. We use context
4330 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4331 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004332 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 if (!cxcursor::isFirstInDeclGroup(C))
4334 R.setBegin(VD->getLocation());
4335 }
4336 return R;
4337 }
4338 return SourceRange();
4339}
4340
4341/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4342/// the decl-specifier-seq for declarations.
4343static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4344 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004345 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 if (!D)
4347 return SourceRange();
4348
4349 SourceRange R = D->getSourceRange();
4350
4351 // Adjust the start of the location for declarations preceded by
4352 // declaration specifiers.
4353 SourceLocation StartLoc;
4354 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4355 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4356 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004357 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004358 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4359 StartLoc = TI->getTypeLoc().getLocStart();
4360 }
4361
4362 if (StartLoc.isValid() && R.getBegin().isValid() &&
4363 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4364 R.setBegin(StartLoc);
4365
4366 // FIXME: Multiple variables declared in a single declaration
4367 // currently lack the information needed to correctly determine their
4368 // ranges when accounting for the type-specifier. We use context
4369 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4370 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004371 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 if (!cxcursor::isFirstInDeclGroup(C))
4373 R.setBegin(VD->getLocation());
4374 }
4375
4376 return R;
4377 }
4378
4379 return getRawCursorExtent(C);
4380}
4381
4382extern "C" {
4383
4384CXSourceRange clang_getCursorExtent(CXCursor C) {
4385 SourceRange R = getRawCursorExtent(C);
4386 if (R.isInvalid())
4387 return clang_getNullRange();
4388
4389 return cxloc::translateSourceRange(getCursorContext(C), R);
4390}
4391
4392CXCursor clang_getCursorReferenced(CXCursor C) {
4393 if (clang_isInvalid(C.kind))
4394 return clang_getNullCursor();
4395
4396 CXTranslationUnit tu = getCursorTU(C);
4397 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004398 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 if (!D)
4400 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004401 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 if (const ObjCPropertyImplDecl *PropImpl =
4404 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4406 return MakeCXCursor(Property, tu);
4407
4408 return C;
4409 }
4410
4411 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 const Expr *E = getCursorExpr(C);
4413 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 if (D) {
4415 CXCursor declCursor = MakeCXCursor(D, tu);
4416 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4417 declCursor);
4418 return declCursor;
4419 }
4420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004421 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 return MakeCursorOverloadedDeclRef(Ovl, tu);
4423
4424 return clang_getNullCursor();
4425 }
4426
4427 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004428 const Stmt *S = getCursorStmt(C);
4429 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 if (LabelDecl *label = Goto->getLabel())
4431 if (LabelStmt *labelS = label->getStmt())
4432 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4433
4434 return clang_getNullCursor();
4435 }
4436
4437 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004438 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return MakeMacroDefinitionCursor(Def, tu);
4440 }
4441
4442 if (!clang_isReference(C.kind))
4443 return clang_getNullCursor();
4444
4445 switch (C.kind) {
4446 case CXCursor_ObjCSuperClassRef:
4447 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4448
4449 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004450 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4451 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 return MakeCXCursor(Def, tu);
4453
4454 return MakeCXCursor(Prot, tu);
4455 }
4456
4457 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004458 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4459 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 return MakeCXCursor(Def, tu);
4461
4462 return MakeCXCursor(Class, tu);
4463 }
4464
4465 case CXCursor_TypeRef:
4466 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4467
4468 case CXCursor_TemplateRef:
4469 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4470
4471 case CXCursor_NamespaceRef:
4472 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4473
4474 case CXCursor_MemberRef:
4475 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4476
4477 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004478 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4480 tu ));
4481 }
4482
4483 case CXCursor_LabelRef:
4484 // FIXME: We end up faking the "parent" declaration here because we
4485 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004486 return MakeCXCursor(getCursorLabelRef(C).first,
4487 cxtu::getASTUnit(tu)->getASTContext()
4488 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 tu);
4490
4491 case CXCursor_OverloadedDeclRef:
4492 return C;
4493
4494 case CXCursor_VariableRef:
4495 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4496
4497 default:
4498 // We would prefer to enumerate all non-reference cursor kinds here.
4499 llvm_unreachable("Unhandled reference cursor kind");
4500 }
4501}
4502
4503CXCursor clang_getCursorDefinition(CXCursor C) {
4504 if (clang_isInvalid(C.kind))
4505 return clang_getNullCursor();
4506
4507 CXTranslationUnit TU = getCursorTU(C);
4508
4509 bool WasReference = false;
4510 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4511 C = clang_getCursorReferenced(C);
4512 WasReference = true;
4513 }
4514
4515 if (C.kind == CXCursor_MacroExpansion)
4516 return clang_getCursorReferenced(C);
4517
4518 if (!clang_isDeclaration(C.kind))
4519 return clang_getNullCursor();
4520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 if (!D)
4523 return clang_getNullCursor();
4524
4525 switch (D->getKind()) {
4526 // Declaration kinds that don't really separate the notions of
4527 // declaration and definition.
4528 case Decl::Namespace:
4529 case Decl::Typedef:
4530 case Decl::TypeAlias:
4531 case Decl::TypeAliasTemplate:
4532 case Decl::TemplateTypeParm:
4533 case Decl::EnumConstant:
4534 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004535 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 case Decl::IndirectField:
4537 case Decl::ObjCIvar:
4538 case Decl::ObjCAtDefsField:
4539 case Decl::ImplicitParam:
4540 case Decl::ParmVar:
4541 case Decl::NonTypeTemplateParm:
4542 case Decl::TemplateTemplateParm:
4543 case Decl::ObjCCategoryImpl:
4544 case Decl::ObjCImplementation:
4545 case Decl::AccessSpec:
4546 case Decl::LinkageSpec:
4547 case Decl::ObjCPropertyImpl:
4548 case Decl::FileScopeAsm:
4549 case Decl::StaticAssert:
4550 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004551 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case Decl::Label: // FIXME: Is this right??
4553 case Decl::ClassScopeFunctionSpecialization:
4554 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004555 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 return C;
4557
4558 // Declaration kinds that don't make any sense here, but are
4559 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004560 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case Decl::TranslationUnit:
4562 break;
4563
4564 // Declaration kinds for which the definition is not resolvable.
4565 case Decl::UnresolvedUsingTypename:
4566 case Decl::UnresolvedUsingValue:
4567 break;
4568
4569 case Decl::UsingDirective:
4570 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4571 TU);
4572
4573 case Decl::NamespaceAlias:
4574 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4575
4576 case Decl::Enum:
4577 case Decl::Record:
4578 case Decl::CXXRecord:
4579 case Decl::ClassTemplateSpecialization:
4580 case Decl::ClassTemplatePartialSpecialization:
4581 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4582 return MakeCXCursor(Def, TU);
4583 return clang_getNullCursor();
4584
4585 case Decl::Function:
4586 case Decl::CXXMethod:
4587 case Decl::CXXConstructor:
4588 case Decl::CXXDestructor:
4589 case Decl::CXXConversion: {
4590 const FunctionDecl *Def = 0;
4591 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004592 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 return clang_getNullCursor();
4594 }
4595
Larisse Voufo39a1e502013-08-06 01:03:05 +00004596 case Decl::Var:
4597 case Decl::VarTemplateSpecialization:
4598 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004600 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 return MakeCXCursor(Def, TU);
4602 return clang_getNullCursor();
4603 }
4604
4605 case Decl::FunctionTemplate: {
4606 const FunctionDecl *Def = 0;
4607 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4608 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4609 return clang_getNullCursor();
4610 }
4611
4612 case Decl::ClassTemplate: {
4613 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4614 ->getDefinition())
4615 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4616 TU);
4617 return clang_getNullCursor();
4618 }
4619
Larisse Voufo39a1e502013-08-06 01:03:05 +00004620 case Decl::VarTemplate: {
4621 if (VarDecl *Def =
4622 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4623 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4624 return clang_getNullCursor();
4625 }
4626
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case Decl::Using:
4628 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4629 D->getLocation(), TU);
4630
4631 case Decl::UsingShadow:
4632 return clang_getCursorDefinition(
4633 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4634 TU));
4635
4636 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004637 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 if (Method->isThisDeclarationADefinition())
4639 return C;
4640
4641 // Dig out the method definition in the associated
4642 // @implementation, if we have it.
4643 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004644 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4646 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4647 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4648 Method->isInstanceMethod()))
4649 if (Def->isThisDeclarationADefinition())
4650 return MakeCXCursor(Def, TU);
4651
4652 return clang_getNullCursor();
4653 }
4654
4655 case Decl::ObjCCategory:
4656 if (ObjCCategoryImplDecl *Impl
4657 = cast<ObjCCategoryDecl>(D)->getImplementation())
4658 return MakeCXCursor(Impl, TU);
4659 return clang_getNullCursor();
4660
4661 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004662 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 return MakeCXCursor(Def, TU);
4664 return clang_getNullCursor();
4665
4666 case Decl::ObjCInterface: {
4667 // There are two notions of a "definition" for an Objective-C
4668 // class: the interface and its implementation. When we resolved a
4669 // reference to an Objective-C class, produce the @interface as
4670 // the definition; when we were provided with the interface,
4671 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004672 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004674 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 return MakeCXCursor(Def, TU);
4676 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4677 return MakeCXCursor(Impl, TU);
4678 return clang_getNullCursor();
4679 }
4680
4681 case Decl::ObjCProperty:
4682 // FIXME: We don't really know where to find the
4683 // ObjCPropertyImplDecls that implement this property.
4684 return clang_getNullCursor();
4685
4686 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004687 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004689 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return MakeCXCursor(Def, TU);
4691
4692 return clang_getNullCursor();
4693
4694 case Decl::Friend:
4695 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4696 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4697 return clang_getNullCursor();
4698
4699 case Decl::FriendTemplate:
4700 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4701 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4702 return clang_getNullCursor();
4703 }
4704
4705 return clang_getNullCursor();
4706}
4707
4708unsigned clang_isCursorDefinition(CXCursor C) {
4709 if (!clang_isDeclaration(C.kind))
4710 return 0;
4711
4712 return clang_getCursorDefinition(C) == C;
4713}
4714
4715CXCursor clang_getCanonicalCursor(CXCursor C) {
4716 if (!clang_isDeclaration(C.kind))
4717 return C;
4718
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004719 if (const Decl *D = getCursorDecl(C)) {
4720 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4722 return MakeCXCursor(CatD, getCursorTU(C));
4723
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4725 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 return MakeCXCursor(IFD, getCursorTU(C));
4727
4728 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4729 }
4730
4731 return C;
4732}
4733
4734int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4735 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4736}
4737
4738unsigned clang_getNumOverloadedDecls(CXCursor C) {
4739 if (C.kind != CXCursor_OverloadedDeclRef)
4740 return 0;
4741
4742 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 return E->getNumDecls();
4745
4746 if (OverloadedTemplateStorage *S
4747 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4748 return S->size();
4749
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 const Decl *D = Storage.get<const Decl *>();
4751 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 return Using->shadow_size();
4753
4754 return 0;
4755}
4756
4757CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4758 if (cursor.kind != CXCursor_OverloadedDeclRef)
4759 return clang_getNullCursor();
4760
4761 if (index >= clang_getNumOverloadedDecls(cursor))
4762 return clang_getNullCursor();
4763
4764 CXTranslationUnit TU = getCursorTU(cursor);
4765 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004766 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 return MakeCXCursor(E->decls_begin()[index], TU);
4768
4769 if (OverloadedTemplateStorage *S
4770 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4771 return MakeCXCursor(S->begin()[index], TU);
4772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 const Decl *D = Storage.get<const Decl *>();
4774 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 // FIXME: This is, unfortunately, linear time.
4776 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4777 std::advance(Pos, index);
4778 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4779 }
4780
4781 return clang_getNullCursor();
4782}
4783
4784void clang_getDefinitionSpellingAndExtent(CXCursor C,
4785 const char **startBuf,
4786 const char **endBuf,
4787 unsigned *startLine,
4788 unsigned *startColumn,
4789 unsigned *endLine,
4790 unsigned *endColumn) {
4791 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004792 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4794
4795 SourceManager &SM = FD->getASTContext().getSourceManager();
4796 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4797 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4798 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4799 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4800 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4801 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4802}
4803
4804
4805CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4806 unsigned PieceIndex) {
4807 RefNamePieces Pieces;
4808
4809 switch (C.kind) {
4810 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004811 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4813 E->getQualifierLoc().getSourceRange());
4814 break;
4815
4816 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004817 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4819 E->getQualifierLoc().getSourceRange(),
4820 E->getOptionalExplicitTemplateArgs());
4821 break;
4822
4823 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004824 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004826 const Expr *Callee = OCE->getCallee();
4827 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 Callee = ICE->getSubExpr();
4829
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004830 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4832 DRE->getQualifierLoc().getSourceRange());
4833 }
4834 break;
4835
4836 default:
4837 break;
4838 }
4839
4840 if (Pieces.empty()) {
4841 if (PieceIndex == 0)
4842 return clang_getCursorExtent(C);
4843 } else if (PieceIndex < Pieces.size()) {
4844 SourceRange R = Pieces[PieceIndex];
4845 if (R.isValid())
4846 return cxloc::translateSourceRange(getCursorContext(C), R);
4847 }
4848
4849 return clang_getNullRange();
4850}
4851
4852void clang_enableStackTraces(void) {
4853 llvm::sys::PrintStackTraceOnErrorSignal();
4854}
4855
4856void clang_executeOnThread(void (*fn)(void*), void *user_data,
4857 unsigned stack_size) {
4858 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4859}
4860
4861} // end: extern "C"
4862
4863//===----------------------------------------------------------------------===//
4864// Token-based Operations.
4865//===----------------------------------------------------------------------===//
4866
4867/* CXToken layout:
4868 * int_data[0]: a CXTokenKind
4869 * int_data[1]: starting token location
4870 * int_data[2]: token length
4871 * int_data[3]: reserved
4872 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4873 * otherwise unused.
4874 */
4875extern "C" {
4876
4877CXTokenKind clang_getTokenKind(CXToken CXTok) {
4878 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4879}
4880
4881CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4882 switch (clang_getTokenKind(CXTok)) {
4883 case CXToken_Identifier:
4884 case CXToken_Keyword:
4885 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004886 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 ->getNameStart());
4888
4889 case CXToken_Literal: {
4890 // We have stashed the starting pointer in the ptr_data field. Use it.
4891 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004892 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 }
4894
4895 case CXToken_Punctuation:
4896 case CXToken_Comment:
4897 break;
4898 }
4899
4900 // We have to find the starting buffer pointer the hard way, by
4901 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004902 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004904 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004905
4906 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4907 std::pair<FileID, unsigned> LocInfo
4908 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4909 bool Invalid = false;
4910 StringRef Buffer
4911 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4912 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004913 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004914
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004915 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004916}
4917
4918CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004919 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 if (!CXXUnit)
4921 return clang_getNullLocation();
4922
4923 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4924 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4925}
4926
4927CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004928 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 if (!CXXUnit)
4930 return clang_getNullRange();
4931
4932 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4933 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4934}
4935
4936static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4937 SmallVectorImpl<CXToken> &CXTokens) {
4938 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4939 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004940 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004942 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004943
4944 // Cannot tokenize across files.
4945 if (BeginLocInfo.first != EndLocInfo.first)
4946 return;
4947
4948 // Create a lexer
4949 bool Invalid = false;
4950 StringRef Buffer
4951 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4952 if (Invalid)
4953 return;
4954
4955 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4956 CXXUnit->getASTContext().getLangOpts(),
4957 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4958 Lex.SetCommentRetentionState(true);
4959
4960 // Lex tokens until we hit the end of the range.
4961 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4962 Token Tok;
4963 bool previousWasAt = false;
4964 do {
4965 // Lex the next token
4966 Lex.LexFromRawLexer(Tok);
4967 if (Tok.is(tok::eof))
4968 break;
4969
4970 // Initialize the CXToken.
4971 CXToken CXTok;
4972
4973 // - Common fields
4974 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4975 CXTok.int_data[2] = Tok.getLength();
4976 CXTok.int_data[3] = 0;
4977
4978 // - Kind-specific fields
4979 if (Tok.isLiteral()) {
4980 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004981 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 } else if (Tok.is(tok::raw_identifier)) {
4983 // Lookup the identifier to determine whether we have a keyword.
4984 IdentifierInfo *II
4985 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4986
4987 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4988 CXTok.int_data[0] = CXToken_Keyword;
4989 }
4990 else {
4991 CXTok.int_data[0] = Tok.is(tok::identifier)
4992 ? CXToken_Identifier
4993 : CXToken_Keyword;
4994 }
4995 CXTok.ptr_data = II;
4996 } else if (Tok.is(tok::comment)) {
4997 CXTok.int_data[0] = CXToken_Comment;
4998 CXTok.ptr_data = 0;
4999 } else {
5000 CXTok.int_data[0] = CXToken_Punctuation;
5001 CXTok.ptr_data = 0;
5002 }
5003 CXTokens.push_back(CXTok);
5004 previousWasAt = Tok.is(tok::at);
5005 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5006}
5007
5008void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5009 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005010 LOG_FUNC_SECTION {
5011 *Log << TU << ' ' << Range;
5012 }
5013
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 if (Tokens)
5015 *Tokens = 0;
5016 if (NumTokens)
5017 *NumTokens = 0;
5018
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005019 if (!TU)
5020 return;
5021
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005022 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 if (!CXXUnit || !Tokens || !NumTokens)
5024 return;
5025
5026 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5027
5028 SourceRange R = cxloc::translateCXSourceRange(Range);
5029 if (R.isInvalid())
5030 return;
5031
5032 SmallVector<CXToken, 32> CXTokens;
5033 getTokens(CXXUnit, R, CXTokens);
5034
5035 if (CXTokens.empty())
5036 return;
5037
5038 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5039 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5040 *NumTokens = CXTokens.size();
5041}
5042
5043void clang_disposeTokens(CXTranslationUnit TU,
5044 CXToken *Tokens, unsigned NumTokens) {
5045 free(Tokens);
5046}
5047
5048} // end: extern "C"
5049
5050//===----------------------------------------------------------------------===//
5051// Token annotation APIs.
5052//===----------------------------------------------------------------------===//
5053
Guy Benyei11169dd2012-12-18 14:30:41 +00005054static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5055 CXCursor parent,
5056 CXClientData client_data);
5057static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5058 CXClientData client_data);
5059
5060namespace {
5061class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 CXToken *Tokens;
5063 CXCursor *Cursors;
5064 unsigned NumTokens;
5065 unsigned TokIdx;
5066 unsigned PreprocessingTokIdx;
5067 CursorVisitor AnnotateVis;
5068 SourceManager &SrcMgr;
5069 bool HasContextSensitiveKeywords;
5070
5071 struct PostChildrenInfo {
5072 CXCursor Cursor;
5073 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005074 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 unsigned BeforeChildrenTokenIdx;
5076 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005077 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005078
5079 CXToken &getTok(unsigned Idx) {
5080 assert(Idx < NumTokens);
5081 return Tokens[Idx];
5082 }
5083 const CXToken &getTok(unsigned Idx) const {
5084 assert(Idx < NumTokens);
5085 return Tokens[Idx];
5086 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 bool MoreTokens() const { return TokIdx < NumTokens; }
5088 unsigned NextToken() const { return TokIdx; }
5089 void AdvanceToken() { ++TokIdx; }
5090 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005091 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 }
5093 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005094 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 }
5096 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005097 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 }
5099
5100 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005101 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 SourceRange);
5103
5104public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005105 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005106 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005107 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005109 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 AnnotateTokensVisitor, this,
5111 /*VisitPreprocessorLast=*/true,
5112 /*VisitIncludedEntities=*/false,
5113 RegionOfInterest,
5114 /*VisitDeclsOnly=*/false,
5115 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005116 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 HasContextSensitiveKeywords(false) { }
5118
5119 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5120 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5121 bool postVisitChildren(CXCursor cursor);
5122 void AnnotateTokens();
5123
5124 /// \brief Determine whether the annotator saw any cursors that have
5125 /// context-sensitive keywords.
5126 bool hasContextSensitiveKeywords() const {
5127 return HasContextSensitiveKeywords;
5128 }
5129
5130 ~AnnotateTokensWorker() {
5131 assert(PostChildrenInfos.empty());
5132 }
5133};
5134}
5135
5136void AnnotateTokensWorker::AnnotateTokens() {
5137 // Walk the AST within the region of interest, annotating tokens
5138 // along the way.
5139 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005140}
Guy Benyei11169dd2012-12-18 14:30:41 +00005141
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005142static inline void updateCursorAnnotation(CXCursor &Cursor,
5143 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005144 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005146 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005147}
5148
5149/// \brief It annotates and advances tokens with a cursor until the comparison
5150//// between the cursor location and the source range is the same as
5151/// \arg compResult.
5152///
5153/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5154/// Pass RangeOverlap to annotate tokens inside a range.
5155void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5156 RangeComparisonResult compResult,
5157 SourceRange range) {
5158 while (MoreTokens()) {
5159 const unsigned I = NextToken();
5160 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005161 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5162 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005163
5164 SourceLocation TokLoc = GetTokenLoc(I);
5165 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005166 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 AdvanceToken();
5168 continue;
5169 }
5170 break;
5171 }
5172}
5173
5174/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005175/// \returns true if it advanced beyond all macro tokens, false otherwise.
5176bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 CXCursor updateC,
5178 RangeComparisonResult compResult,
5179 SourceRange range) {
5180 assert(MoreTokens());
5181 assert(isFunctionMacroToken(NextToken()) &&
5182 "Should be called only for macro arg tokens");
5183
5184 // This works differently than annotateAndAdvanceTokens; because expanded
5185 // macro arguments can have arbitrary translation-unit source order, we do not
5186 // advance the token index one by one until a token fails the range test.
5187 // We only advance once past all of the macro arg tokens if all of them
5188 // pass the range test. If one of them fails we keep the token index pointing
5189 // at the start of the macro arg tokens so that the failing token will be
5190 // annotated by a subsequent annotation try.
5191
5192 bool atLeastOneCompFail = false;
5193
5194 unsigned I = NextToken();
5195 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5196 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5197 if (TokLoc.isFileID())
5198 continue; // not macro arg token, it's parens or comma.
5199 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5200 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5201 Cursors[I] = updateC;
5202 } else
5203 atLeastOneCompFail = true;
5204 }
5205
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005206 if (atLeastOneCompFail)
5207 return false;
5208
5209 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5210 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005211}
5212
5213enum CXChildVisitResult
5214AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 SourceRange cursorRange = getRawCursorExtent(cursor);
5216 if (cursorRange.isInvalid())
5217 return CXChildVisit_Recurse;
5218
5219 if (!HasContextSensitiveKeywords) {
5220 // Objective-C properties can have context-sensitive keywords.
5221 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005222 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5224 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5225 }
5226 // Objective-C methods can have context-sensitive keywords.
5227 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5228 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005229 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5231 if (Method->getObjCDeclQualifier())
5232 HasContextSensitiveKeywords = true;
5233 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005234 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5235 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 P != PEnd; ++P) {
5237 if ((*P)->getObjCDeclQualifier()) {
5238 HasContextSensitiveKeywords = true;
5239 break;
5240 }
5241 }
5242 }
5243 }
5244 }
5245 // C++ methods can have context-sensitive keywords.
5246 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005247 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5249 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5250 HasContextSensitiveKeywords = true;
5251 }
5252 }
5253 // C++ classes can have context-sensitive keywords.
5254 else if (cursor.kind == CXCursor_StructDecl ||
5255 cursor.kind == CXCursor_ClassDecl ||
5256 cursor.kind == CXCursor_ClassTemplate ||
5257 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005258 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 if (D->hasAttr<FinalAttr>())
5260 HasContextSensitiveKeywords = true;
5261 }
5262 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005263
5264 // Don't override a property annotation with its getter/setter method.
5265 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5266 parent.kind == CXCursor_ObjCPropertyDecl)
5267 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005268
5269 if (clang_isPreprocessing(cursor.kind)) {
5270 // Items in the preprocessing record are kept separate from items in
5271 // declarations, so we keep a separate token index.
5272 unsigned SavedTokIdx = TokIdx;
5273 TokIdx = PreprocessingTokIdx;
5274
5275 // Skip tokens up until we catch up to the beginning of the preprocessing
5276 // entry.
5277 while (MoreTokens()) {
5278 const unsigned I = NextToken();
5279 SourceLocation TokLoc = GetTokenLoc(I);
5280 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5281 case RangeBefore:
5282 AdvanceToken();
5283 continue;
5284 case RangeAfter:
5285 case RangeOverlap:
5286 break;
5287 }
5288 break;
5289 }
5290
5291 // Look at all of the tokens within this range.
5292 while (MoreTokens()) {
5293 const unsigned I = NextToken();
5294 SourceLocation TokLoc = GetTokenLoc(I);
5295 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5296 case RangeBefore:
5297 llvm_unreachable("Infeasible");
5298 case RangeAfter:
5299 break;
5300 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005301 // For macro expansions, just note where the beginning of the macro
5302 // expansion occurs.
5303 if (cursor.kind == CXCursor_MacroExpansion) {
5304 if (TokLoc == cursorRange.getBegin())
5305 Cursors[I] = cursor;
5306 AdvanceToken();
5307 break;
5308 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005309 // We may have already annotated macro names inside macro definitions.
5310 if (Cursors[I].kind != CXCursor_MacroExpansion)
5311 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 continue;
5314 }
5315 break;
5316 }
5317
5318 // Save the preprocessing token index; restore the non-preprocessing
5319 // token index.
5320 PreprocessingTokIdx = TokIdx;
5321 TokIdx = SavedTokIdx;
5322 return CXChildVisit_Recurse;
5323 }
5324
5325 if (cursorRange.isInvalid())
5326 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005327
5328 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 const enum CXCursorKind K = clang_getCursorKind(parent);
5331 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005332 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5333 // Attributes are annotated out-of-order, skip tokens until we reach it.
5334 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 ? clang_getNullCursor() : parent;
5336
5337 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5338
5339 // Avoid having the cursor of an expression "overwrite" the annotation of the
5340 // variable declaration that it belongs to.
5341 // This can happen for C++ constructor expressions whose range generally
5342 // include the variable declaration, e.g.:
5343 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005344 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005345 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005346 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 const unsigned I = NextToken();
5348 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5349 E->getLocStart() == D->getLocation() &&
5350 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005351 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 AdvanceToken();
5353 }
5354 }
5355 }
5356
5357 // Before recursing into the children keep some state that we are going
5358 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5359 // extra work after the child nodes are visited.
5360 // Note that we don't call VisitChildren here to avoid traversing statements
5361 // code-recursively which can blow the stack.
5362
5363 PostChildrenInfo Info;
5364 Info.Cursor = cursor;
5365 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005366 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 Info.BeforeChildrenTokenIdx = NextToken();
5368 PostChildrenInfos.push_back(Info);
5369
5370 return CXChildVisit_Recurse;
5371}
5372
5373bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5374 if (PostChildrenInfos.empty())
5375 return false;
5376 const PostChildrenInfo &Info = PostChildrenInfos.back();
5377 if (!clang_equalCursors(Info.Cursor, cursor))
5378 return false;
5379
5380 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5381 const unsigned AfterChildren = NextToken();
5382 SourceRange cursorRange = Info.CursorRange;
5383
5384 // Scan the tokens that are at the end of the cursor, but are not captured
5385 // but the child cursors.
5386 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5387
5388 // Scan the tokens that are at the beginning of the cursor, but are not
5389 // capture by the child cursors.
5390 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5391 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5392 break;
5393
5394 Cursors[I] = cursor;
5395 }
5396
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005397 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5398 // encountered the attribute cursor.
5399 if (clang_isAttribute(cursor.kind))
5400 TokIdx = Info.BeforeReachingCursorIdx;
5401
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 PostChildrenInfos.pop_back();
5403 return false;
5404}
5405
5406static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5407 CXCursor parent,
5408 CXClientData client_data) {
5409 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5410}
5411
5412static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5413 CXClientData client_data) {
5414 return static_cast<AnnotateTokensWorker*>(client_data)->
5415 postVisitChildren(cursor);
5416}
5417
5418namespace {
5419
5420/// \brief Uses the macro expansions in the preprocessing record to find
5421/// and mark tokens that are macro arguments. This info is used by the
5422/// AnnotateTokensWorker.
5423class MarkMacroArgTokensVisitor {
5424 SourceManager &SM;
5425 CXToken *Tokens;
5426 unsigned NumTokens;
5427 unsigned CurIdx;
5428
5429public:
5430 MarkMacroArgTokensVisitor(SourceManager &SM,
5431 CXToken *tokens, unsigned numTokens)
5432 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5433
5434 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5435 if (cursor.kind != CXCursor_MacroExpansion)
5436 return CXChildVisit_Continue;
5437
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005438 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 if (macroRange.getBegin() == macroRange.getEnd())
5440 return CXChildVisit_Continue; // it's not a function macro.
5441
5442 for (; CurIdx < NumTokens; ++CurIdx) {
5443 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5444 macroRange.getBegin()))
5445 break;
5446 }
5447
5448 if (CurIdx == NumTokens)
5449 return CXChildVisit_Break;
5450
5451 for (; CurIdx < NumTokens; ++CurIdx) {
5452 SourceLocation tokLoc = getTokenLoc(CurIdx);
5453 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5454 break;
5455
5456 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5457 }
5458
5459 if (CurIdx == NumTokens)
5460 return CXChildVisit_Break;
5461
5462 return CXChildVisit_Continue;
5463 }
5464
5465private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005466 CXToken &getTok(unsigned Idx) {
5467 assert(Idx < NumTokens);
5468 return Tokens[Idx];
5469 }
5470 const CXToken &getTok(unsigned Idx) const {
5471 assert(Idx < NumTokens);
5472 return Tokens[Idx];
5473 }
5474
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005476 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 }
5478
5479 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5480 // The third field is reserved and currently not used. Use it here
5481 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005482 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 }
5484};
5485
5486} // end anonymous namespace
5487
5488static CXChildVisitResult
5489MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5490 CXClientData client_data) {
5491 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5492 parent);
5493}
5494
5495namespace {
5496 struct clang_annotateTokens_Data {
5497 CXTranslationUnit TU;
5498 ASTUnit *CXXUnit;
5499 CXToken *Tokens;
5500 unsigned NumTokens;
5501 CXCursor *Cursors;
5502 };
5503}
5504
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005505/// \brief Used by \c annotatePreprocessorTokens.
5506/// \returns true if lexing was finished, false otherwise.
5507static bool lexNext(Lexer &Lex, Token &Tok,
5508 unsigned &NextIdx, unsigned NumTokens) {
5509 if (NextIdx >= NumTokens)
5510 return true;
5511
5512 ++NextIdx;
5513 Lex.LexFromRawLexer(Tok);
5514 if (Tok.is(tok::eof))
5515 return true;
5516
5517 return false;
5518}
5519
Guy Benyei11169dd2012-12-18 14:30:41 +00005520static void annotatePreprocessorTokens(CXTranslationUnit TU,
5521 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005522 CXCursor *Cursors,
5523 CXToken *Tokens,
5524 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005525 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005526
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005527 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5529 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005530 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005532 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005533
5534 if (BeginLocInfo.first != EndLocInfo.first)
5535 return;
5536
5537 StringRef Buffer;
5538 bool Invalid = false;
5539 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5540 if (Buffer.empty() || Invalid)
5541 return;
5542
5543 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5544 CXXUnit->getASTContext().getLangOpts(),
5545 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5546 Buffer.end());
5547 Lex.SetCommentRetentionState(true);
5548
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005549 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 // Lex tokens in raw mode until we hit the end of the range, to avoid
5551 // entering #includes or expanding macros.
5552 while (true) {
5553 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005554 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5555 break;
5556 unsigned TokIdx = NextIdx-1;
5557 assert(Tok.getLocation() ==
5558 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005559
5560 reprocess:
5561 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005562 // We have found a preprocessing directive. Annotate the tokens
5563 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 //
5565 // FIXME: Some simple tests here could identify macro definitions and
5566 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005567
5568 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005569 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5570 break;
5571
5572 MacroInfo *MI = 0;
5573 if (Tok.is(tok::raw_identifier) &&
5574 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5575 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5576 break;
5577
5578 if (Tok.is(tok::raw_identifier)) {
5579 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5580 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5581 SourceLocation MappedTokLoc =
5582 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5583 MI = getMacroInfo(II, MappedTokLoc, TU);
5584 }
5585 }
5586
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005587 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005589 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5590 finished = true;
5591 break;
5592 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005593 // If we are in a macro definition, check if the token was ever a
5594 // macro name and annotate it if that's the case.
5595 if (MI) {
5596 SourceLocation SaveLoc = Tok.getLocation();
5597 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5598 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5599 Tok.setLocation(SaveLoc);
5600 if (MacroDef)
5601 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5602 Tok.getLocation(), TU);
5603 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005604 } while (!Tok.isAtStartOfLine());
5605
5606 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5607 assert(TokIdx <= LastIdx);
5608 SourceLocation EndLoc =
5609 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5610 CXCursor Cursor =
5611 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5612
5613 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005614 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005615
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005616 if (finished)
5617 break;
5618 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 }
5621}
5622
5623// This gets run a separate thread to avoid stack blowout.
5624static void clang_annotateTokensImpl(void *UserData) {
5625 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5626 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5627 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5628 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5629 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5630
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005631 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5633 setThreadBackgroundPriority();
5634
5635 // Determine the region of interest, which contains all of the tokens.
5636 SourceRange RegionOfInterest;
5637 RegionOfInterest.setBegin(
5638 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5639 RegionOfInterest.setEnd(
5640 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5641 Tokens[NumTokens-1])));
5642
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 // Relex the tokens within the source range to look for preprocessing
5644 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005645 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005646
5647 // If begin location points inside a macro argument, set it to the expansion
5648 // location so we can have the full context when annotating semantically.
5649 {
5650 SourceManager &SM = CXXUnit->getSourceManager();
5651 SourceLocation Loc =
5652 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5653 if (Loc.isMacroID())
5654 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5655 }
5656
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5658 // Search and mark tokens that are macro argument expansions.
5659 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5660 Tokens, NumTokens);
5661 CursorVisitor MacroArgMarker(TU,
5662 MarkMacroArgTokensVisitorDelegate, &Visitor,
5663 /*VisitPreprocessorLast=*/true,
5664 /*VisitIncludedEntities=*/false,
5665 RegionOfInterest);
5666 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5667 }
5668
5669 // Annotate all of the source locations in the region of interest that map to
5670 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005671 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005672
5673 // FIXME: We use a ridiculous stack size here because the data-recursion
5674 // algorithm uses a large stack frame than the non-data recursive version,
5675 // and AnnotationTokensWorker currently transforms the data-recursion
5676 // algorithm back into a traditional recursion by explicitly calling
5677 // VisitChildren(). We will need to remove this explicit recursive call.
5678 W.AnnotateTokens();
5679
5680 // If we ran into any entities that involve context-sensitive keywords,
5681 // take another pass through the tokens to mark them as such.
5682 if (W.hasContextSensitiveKeywords()) {
5683 for (unsigned I = 0; I != NumTokens; ++I) {
5684 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5685 continue;
5686
5687 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5688 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005689 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5691 if (Property->getPropertyAttributesAsWritten() != 0 &&
5692 llvm::StringSwitch<bool>(II->getName())
5693 .Case("readonly", true)
5694 .Case("assign", true)
5695 .Case("unsafe_unretained", true)
5696 .Case("readwrite", true)
5697 .Case("retain", true)
5698 .Case("copy", true)
5699 .Case("nonatomic", true)
5700 .Case("atomic", true)
5701 .Case("getter", true)
5702 .Case("setter", true)
5703 .Case("strong", true)
5704 .Case("weak", true)
5705 .Default(false))
5706 Tokens[I].int_data[0] = CXToken_Keyword;
5707 }
5708 continue;
5709 }
5710
5711 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5712 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5713 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5714 if (llvm::StringSwitch<bool>(II->getName())
5715 .Case("in", true)
5716 .Case("out", true)
5717 .Case("inout", true)
5718 .Case("oneway", true)
5719 .Case("bycopy", true)
5720 .Case("byref", true)
5721 .Default(false))
5722 Tokens[I].int_data[0] = CXToken_Keyword;
5723 continue;
5724 }
5725
5726 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5727 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5728 Tokens[I].int_data[0] = CXToken_Keyword;
5729 continue;
5730 }
5731 }
5732 }
5733}
5734
5735extern "C" {
5736
5737void clang_annotateTokens(CXTranslationUnit TU,
5738 CXToken *Tokens, unsigned NumTokens,
5739 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005740 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005741 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005743 }
5744
5745 LOG_FUNC_SECTION {
5746 *Log << TU << ' ';
5747 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5748 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5749 *Log << clang_getRange(bloc, eloc);
5750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005751
5752 // Any token we don't specifically annotate will have a NULL cursor.
5753 CXCursor C = clang_getNullCursor();
5754 for (unsigned I = 0; I != NumTokens; ++I)
5755 Cursors[I] = C;
5756
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005757 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 if (!CXXUnit)
5759 return;
5760
5761 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5762
5763 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5764 llvm::CrashRecoveryContext CRC;
5765 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5766 GetSafetyThreadStackSize() * 2)) {
5767 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5768 }
5769}
5770
5771} // end: extern "C"
5772
5773//===----------------------------------------------------------------------===//
5774// Operations for querying linkage of a cursor.
5775//===----------------------------------------------------------------------===//
5776
5777extern "C" {
5778CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5779 if (!clang_isDeclaration(cursor.kind))
5780 return CXLinkage_Invalid;
5781
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005782 const Decl *D = cxcursor::getCursorDecl(cursor);
5783 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005784 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005785 case NoLinkage:
5786 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 case InternalLinkage: return CXLinkage_Internal;
5788 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5789 case ExternalLinkage: return CXLinkage_External;
5790 };
5791
5792 return CXLinkage_Invalid;
5793}
5794} // end: extern "C"
5795
5796//===----------------------------------------------------------------------===//
5797// Operations for querying language of a cursor.
5798//===----------------------------------------------------------------------===//
5799
5800static CXLanguageKind getDeclLanguage(const Decl *D) {
5801 if (!D)
5802 return CXLanguage_C;
5803
5804 switch (D->getKind()) {
5805 default:
5806 break;
5807 case Decl::ImplicitParam:
5808 case Decl::ObjCAtDefsField:
5809 case Decl::ObjCCategory:
5810 case Decl::ObjCCategoryImpl:
5811 case Decl::ObjCCompatibleAlias:
5812 case Decl::ObjCImplementation:
5813 case Decl::ObjCInterface:
5814 case Decl::ObjCIvar:
5815 case Decl::ObjCMethod:
5816 case Decl::ObjCProperty:
5817 case Decl::ObjCPropertyImpl:
5818 case Decl::ObjCProtocol:
5819 return CXLanguage_ObjC;
5820 case Decl::CXXConstructor:
5821 case Decl::CXXConversion:
5822 case Decl::CXXDestructor:
5823 case Decl::CXXMethod:
5824 case Decl::CXXRecord:
5825 case Decl::ClassTemplate:
5826 case Decl::ClassTemplatePartialSpecialization:
5827 case Decl::ClassTemplateSpecialization:
5828 case Decl::Friend:
5829 case Decl::FriendTemplate:
5830 case Decl::FunctionTemplate:
5831 case Decl::LinkageSpec:
5832 case Decl::Namespace:
5833 case Decl::NamespaceAlias:
5834 case Decl::NonTypeTemplateParm:
5835 case Decl::StaticAssert:
5836 case Decl::TemplateTemplateParm:
5837 case Decl::TemplateTypeParm:
5838 case Decl::UnresolvedUsingTypename:
5839 case Decl::UnresolvedUsingValue:
5840 case Decl::Using:
5841 case Decl::UsingDirective:
5842 case Decl::UsingShadow:
5843 return CXLanguage_CPlusPlus;
5844 }
5845
5846 return CXLanguage_C;
5847}
5848
5849extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005850
5851static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5852 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5853 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005854
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005855 switch (D->getAvailability()) {
5856 case AR_Available:
5857 case AR_NotYetIntroduced:
5858 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005859 return getCursorAvailabilityForDecl(
5860 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005861 return CXAvailability_Available;
5862
5863 case AR_Deprecated:
5864 return CXAvailability_Deprecated;
5865
5866 case AR_Unavailable:
5867 return CXAvailability_NotAvailable;
5868 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005869
5870 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005871}
5872
Guy Benyei11169dd2012-12-18 14:30:41 +00005873enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5874 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005875 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5876 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005877
5878 return CXAvailability_Available;
5879}
5880
5881static CXVersion convertVersion(VersionTuple In) {
5882 CXVersion Out = { -1, -1, -1 };
5883 if (In.empty())
5884 return Out;
5885
5886 Out.Major = In.getMajor();
5887
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005888 Optional<unsigned> Minor = In.getMinor();
5889 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 Out.Minor = *Minor;
5891 else
5892 return Out;
5893
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005894 Optional<unsigned> Subminor = In.getSubminor();
5895 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 Out.Subminor = *Subminor;
5897
5898 return Out;
5899}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005900
5901static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5902 int *always_deprecated,
5903 CXString *deprecated_message,
5904 int *always_unavailable,
5905 CXString *unavailable_message,
5906 CXPlatformAvailability *availability,
5907 int availability_size) {
5908 bool HadAvailAttr = false;
5909 int N = 0;
5910 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5911 ++A) {
5912 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5913 HadAvailAttr = true;
5914 if (always_deprecated)
5915 *always_deprecated = 1;
5916 if (deprecated_message)
5917 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5918 continue;
5919 }
5920
5921 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5922 HadAvailAttr = true;
5923 if (always_unavailable)
5924 *always_unavailable = 1;
5925 if (unavailable_message) {
5926 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5927 }
5928 continue;
5929 }
5930
5931 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5932 HadAvailAttr = true;
5933 if (N < availability_size) {
5934 availability[N].Platform
5935 = cxstring::createDup(Avail->getPlatform()->getName());
5936 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5937 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5938 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5939 availability[N].Unavailable = Avail->getUnavailable();
5940 availability[N].Message = cxstring::createDup(Avail->getMessage());
5941 }
5942 ++N;
5943 }
5944 }
5945
5946 if (!HadAvailAttr)
5947 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5948 return getCursorPlatformAvailabilityForDecl(
5949 cast<Decl>(EnumConst->getDeclContext()),
5950 always_deprecated,
5951 deprecated_message,
5952 always_unavailable,
5953 unavailable_message,
5954 availability,
5955 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005956
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005957 return N;
5958}
5959
Guy Benyei11169dd2012-12-18 14:30:41 +00005960int clang_getCursorPlatformAvailability(CXCursor cursor,
5961 int *always_deprecated,
5962 CXString *deprecated_message,
5963 int *always_unavailable,
5964 CXString *unavailable_message,
5965 CXPlatformAvailability *availability,
5966 int availability_size) {
5967 if (always_deprecated)
5968 *always_deprecated = 0;
5969 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005970 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005971 if (always_unavailable)
5972 *always_unavailable = 0;
5973 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005974 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005975
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 if (!clang_isDeclaration(cursor.kind))
5977 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005978
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005979 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005980 if (!D)
5981 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005982
5983 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5984 deprecated_message,
5985 always_unavailable,
5986 unavailable_message,
5987 availability,
5988 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005989}
5990
5991void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5992 clang_disposeString(availability->Platform);
5993 clang_disposeString(availability->Message);
5994}
5995
5996CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5997 if (clang_isDeclaration(cursor.kind))
5998 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5999
6000 return CXLanguage_Invalid;
6001}
6002
6003 /// \brief If the given cursor is the "templated" declaration
6004 /// descibing a class or function template, return the class or
6005 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006006static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 if (!D)
6008 return 0;
6009
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006010 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6012 return FunTmpl;
6013
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006014 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006015 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6016 return ClassTmpl;
6017
6018 return D;
6019}
6020
6021CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6022 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006023 if (const Decl *D = getCursorDecl(cursor)) {
6024 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 if (!DC)
6026 return clang_getNullCursor();
6027
6028 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6029 getCursorTU(cursor));
6030 }
6031 }
6032
6033 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006034 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 return MakeCXCursor(D, getCursorTU(cursor));
6036 }
6037
6038 return clang_getNullCursor();
6039}
6040
6041CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6042 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006043 if (const Decl *D = getCursorDecl(cursor)) {
6044 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 if (!DC)
6046 return clang_getNullCursor();
6047
6048 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6049 getCursorTU(cursor));
6050 }
6051 }
6052
6053 // FIXME: Note that we can't easily compute the lexical context of a
6054 // statement or expression, so we return nothing.
6055 return clang_getNullCursor();
6056}
6057
6058CXFile clang_getIncludedFile(CXCursor cursor) {
6059 if (cursor.kind != CXCursor_InclusionDirective)
6060 return 0;
6061
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006062 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006063 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006064}
6065
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006066unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6067 if (C.kind != CXCursor_ObjCPropertyDecl)
6068 return CXObjCPropertyAttr_noattr;
6069
6070 unsigned Result = CXObjCPropertyAttr_noattr;
6071 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6072 ObjCPropertyDecl::PropertyAttributeKind Attr =
6073 PD->getPropertyAttributesAsWritten();
6074
6075#define SET_CXOBJCPROP_ATTR(A) \
6076 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6077 Result |= CXObjCPropertyAttr_##A
6078 SET_CXOBJCPROP_ATTR(readonly);
6079 SET_CXOBJCPROP_ATTR(getter);
6080 SET_CXOBJCPROP_ATTR(assign);
6081 SET_CXOBJCPROP_ATTR(readwrite);
6082 SET_CXOBJCPROP_ATTR(retain);
6083 SET_CXOBJCPROP_ATTR(copy);
6084 SET_CXOBJCPROP_ATTR(nonatomic);
6085 SET_CXOBJCPROP_ATTR(setter);
6086 SET_CXOBJCPROP_ATTR(atomic);
6087 SET_CXOBJCPROP_ATTR(weak);
6088 SET_CXOBJCPROP_ATTR(strong);
6089 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6090#undef SET_CXOBJCPROP_ATTR
6091
6092 return Result;
6093}
6094
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006095unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6096 if (!clang_isDeclaration(C.kind))
6097 return CXObjCDeclQualifier_None;
6098
6099 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6100 const Decl *D = getCursorDecl(C);
6101 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6102 QT = MD->getObjCDeclQualifier();
6103 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6104 QT = PD->getObjCDeclQualifier();
6105 if (QT == Decl::OBJC_TQ_None)
6106 return CXObjCDeclQualifier_None;
6107
6108 unsigned Result = CXObjCDeclQualifier_None;
6109 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6110 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6111 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6112 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6113 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6114 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6115
6116 return Result;
6117}
6118
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006119unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6120 if (!clang_isDeclaration(C.kind))
6121 return 0;
6122
6123 const Decl *D = getCursorDecl(C);
6124 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6125 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6126 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6127 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6128
6129 return 0;
6130}
6131
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006132unsigned clang_Cursor_isVariadic(CXCursor C) {
6133 if (!clang_isDeclaration(C.kind))
6134 return 0;
6135
6136 const Decl *D = getCursorDecl(C);
6137 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6138 return FD->isVariadic();
6139 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6140 return MD->isVariadic();
6141
6142 return 0;
6143}
6144
Guy Benyei11169dd2012-12-18 14:30:41 +00006145CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6146 if (!clang_isDeclaration(C.kind))
6147 return clang_getNullRange();
6148
6149 const Decl *D = getCursorDecl(C);
6150 ASTContext &Context = getCursorContext(C);
6151 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6152 if (!RC)
6153 return clang_getNullRange();
6154
6155 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6156}
6157
6158CXString clang_Cursor_getRawCommentText(CXCursor C) {
6159 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006160 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006161
6162 const Decl *D = getCursorDecl(C);
6163 ASTContext &Context = getCursorContext(C);
6164 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6165 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6166 StringRef();
6167
6168 // Don't duplicate the string because RawText points directly into source
6169 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006170 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006171}
6172
6173CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6174 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006175 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006176
6177 const Decl *D = getCursorDecl(C);
6178 const ASTContext &Context = getCursorContext(C);
6179 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6180
6181 if (RC) {
6182 StringRef BriefText = RC->getBriefText(Context);
6183
6184 // Don't duplicate the string because RawComment ensures that this memory
6185 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006186 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 }
6188
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006189 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006190}
6191
6192CXComment clang_Cursor_getParsedComment(CXCursor C) {
6193 if (!clang_isDeclaration(C.kind))
6194 return cxcomment::createCXComment(NULL, NULL);
6195
6196 const Decl *D = getCursorDecl(C);
6197 const ASTContext &Context = getCursorContext(C);
6198 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6199
6200 return cxcomment::createCXComment(FC, getCursorTU(C));
6201}
6202
6203CXModule clang_Cursor_getModule(CXCursor C) {
6204 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006205 if (const ImportDecl *ImportD =
6206 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006207 return ImportD->getImportedModule();
6208 }
6209
6210 return 0;
6211}
6212
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006213CXFile clang_Module_getASTFile(CXModule CXMod) {
6214 if (!CXMod)
6215 return 0;
6216 Module *Mod = static_cast<Module*>(CXMod);
6217 return const_cast<FileEntry *>(Mod->getASTFile());
6218}
6219
Guy Benyei11169dd2012-12-18 14:30:41 +00006220CXModule clang_Module_getParent(CXModule CXMod) {
6221 if (!CXMod)
6222 return 0;
6223 Module *Mod = static_cast<Module*>(CXMod);
6224 return Mod->Parent;
6225}
6226
6227CXString clang_Module_getName(CXModule CXMod) {
6228 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006229 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006230 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006231 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006232}
6233
6234CXString clang_Module_getFullName(CXModule CXMod) {
6235 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006236 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006237 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006238 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006239}
6240
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006241unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6242 CXModule CXMod) {
6243 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006244 return 0;
6245 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006246 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6247 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6248 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006249}
6250
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006251CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6252 CXModule CXMod, unsigned Index) {
6253 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006254 return 0;
6255 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006256 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006257
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006258 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6259 if (Index < TopHeaders.size())
6260 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006261
6262 return 0;
6263}
6264
6265} // end: extern "C"
6266
6267//===----------------------------------------------------------------------===//
6268// C++ AST instrospection.
6269//===----------------------------------------------------------------------===//
6270
6271extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006272unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6273 if (!clang_isDeclaration(C.kind))
6274 return 0;
6275
6276 const CXXMethodDecl *Method = 0;
6277 const Decl *D = cxcursor::getCursorDecl(C);
6278 if (const FunctionTemplateDecl *FunTmpl =
6279 dyn_cast_or_null<FunctionTemplateDecl>(D))
6280 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6281 else
6282 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6283 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6284}
6285
Guy Benyei11169dd2012-12-18 14:30:41 +00006286unsigned clang_CXXMethod_isStatic(CXCursor C) {
6287 if (!clang_isDeclaration(C.kind))
6288 return 0;
6289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006290 const CXXMethodDecl *Method = 0;
6291 const Decl *D = cxcursor::getCursorDecl(C);
6292 if (const FunctionTemplateDecl *FunTmpl =
6293 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6295 else
6296 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6297 return (Method && Method->isStatic()) ? 1 : 0;
6298}
6299
6300unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6301 if (!clang_isDeclaration(C.kind))
6302 return 0;
6303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006304 const CXXMethodDecl *Method = 0;
6305 const Decl *D = cxcursor::getCursorDecl(C);
6306 if (const FunctionTemplateDecl *FunTmpl =
6307 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6309 else
6310 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6311 return (Method && Method->isVirtual()) ? 1 : 0;
6312}
6313} // end: extern "C"
6314
6315//===----------------------------------------------------------------------===//
6316// Attribute introspection.
6317//===----------------------------------------------------------------------===//
6318
6319extern "C" {
6320CXType clang_getIBOutletCollectionType(CXCursor C) {
6321 if (C.kind != CXCursor_IBOutletCollectionAttr)
6322 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6323
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006324 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006325 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6326
6327 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6328}
6329} // end: extern "C"
6330
6331//===----------------------------------------------------------------------===//
6332// Inspecting memory usage.
6333//===----------------------------------------------------------------------===//
6334
6335typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6336
6337static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6338 enum CXTUResourceUsageKind k,
6339 unsigned long amount) {
6340 CXTUResourceUsageEntry entry = { k, amount };
6341 entries.push_back(entry);
6342}
6343
6344extern "C" {
6345
6346const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6347 const char *str = "";
6348 switch (kind) {
6349 case CXTUResourceUsage_AST:
6350 str = "ASTContext: expressions, declarations, and types";
6351 break;
6352 case CXTUResourceUsage_Identifiers:
6353 str = "ASTContext: identifiers";
6354 break;
6355 case CXTUResourceUsage_Selectors:
6356 str = "ASTContext: selectors";
6357 break;
6358 case CXTUResourceUsage_GlobalCompletionResults:
6359 str = "Code completion: cached global results";
6360 break;
6361 case CXTUResourceUsage_SourceManagerContentCache:
6362 str = "SourceManager: content cache allocator";
6363 break;
6364 case CXTUResourceUsage_AST_SideTables:
6365 str = "ASTContext: side tables";
6366 break;
6367 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6368 str = "SourceManager: malloc'ed memory buffers";
6369 break;
6370 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6371 str = "SourceManager: mmap'ed memory buffers";
6372 break;
6373 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6374 str = "ExternalASTSource: malloc'ed memory buffers";
6375 break;
6376 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6377 str = "ExternalASTSource: mmap'ed memory buffers";
6378 break;
6379 case CXTUResourceUsage_Preprocessor:
6380 str = "Preprocessor: malloc'ed memory";
6381 break;
6382 case CXTUResourceUsage_PreprocessingRecord:
6383 str = "Preprocessor: PreprocessingRecord";
6384 break;
6385 case CXTUResourceUsage_SourceManager_DataStructures:
6386 str = "SourceManager: data structures and tables";
6387 break;
6388 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6389 str = "Preprocessor: header search tables";
6390 break;
6391 }
6392 return str;
6393}
6394
6395CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6396 if (!TU) {
6397 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6398 return usage;
6399 }
6400
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006401 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006402 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6403 ASTContext &astContext = astUnit->getASTContext();
6404
6405 // How much memory is used by AST nodes and types?
6406 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6407 (unsigned long) astContext.getASTAllocatedMemory());
6408
6409 // How much memory is used by identifiers?
6410 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6411 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6412
6413 // How much memory is used for selectors?
6414 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6415 (unsigned long) astContext.Selectors.getTotalMemory());
6416
6417 // How much memory is used by ASTContext's side tables?
6418 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6419 (unsigned long) astContext.getSideTableAllocatedMemory());
6420
6421 // How much memory is used for caching global code completion results?
6422 unsigned long completionBytes = 0;
6423 if (GlobalCodeCompletionAllocator *completionAllocator =
6424 astUnit->getCachedCompletionAllocator().getPtr()) {
6425 completionBytes = completionAllocator->getTotalMemory();
6426 }
6427 createCXTUResourceUsageEntry(*entries,
6428 CXTUResourceUsage_GlobalCompletionResults,
6429 completionBytes);
6430
6431 // How much memory is being used by SourceManager's content cache?
6432 createCXTUResourceUsageEntry(*entries,
6433 CXTUResourceUsage_SourceManagerContentCache,
6434 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6435
6436 // How much memory is being used by the MemoryBuffer's in SourceManager?
6437 const SourceManager::MemoryBufferSizes &srcBufs =
6438 astUnit->getSourceManager().getMemoryBufferSizes();
6439
6440 createCXTUResourceUsageEntry(*entries,
6441 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6442 (unsigned long) srcBufs.malloc_bytes);
6443 createCXTUResourceUsageEntry(*entries,
6444 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6445 (unsigned long) srcBufs.mmap_bytes);
6446 createCXTUResourceUsageEntry(*entries,
6447 CXTUResourceUsage_SourceManager_DataStructures,
6448 (unsigned long) astContext.getSourceManager()
6449 .getDataStructureSizes());
6450
6451 // How much memory is being used by the ExternalASTSource?
6452 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6453 const ExternalASTSource::MemoryBufferSizes &sizes =
6454 esrc->getMemoryBufferSizes();
6455
6456 createCXTUResourceUsageEntry(*entries,
6457 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6458 (unsigned long) sizes.malloc_bytes);
6459 createCXTUResourceUsageEntry(*entries,
6460 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6461 (unsigned long) sizes.mmap_bytes);
6462 }
6463
6464 // How much memory is being used by the Preprocessor?
6465 Preprocessor &pp = astUnit->getPreprocessor();
6466 createCXTUResourceUsageEntry(*entries,
6467 CXTUResourceUsage_Preprocessor,
6468 pp.getTotalMemory());
6469
6470 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6471 createCXTUResourceUsageEntry(*entries,
6472 CXTUResourceUsage_PreprocessingRecord,
6473 pRec->getTotalMemory());
6474 }
6475
6476 createCXTUResourceUsageEntry(*entries,
6477 CXTUResourceUsage_Preprocessor_HeaderSearch,
6478 pp.getHeaderSearchInfo().getTotalMemory());
6479
6480 CXTUResourceUsage usage = { (void*) entries.get(),
6481 (unsigned) entries->size(),
6482 entries->size() ? &(*entries)[0] : 0 };
6483 entries.take();
6484 return usage;
6485}
6486
6487void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6488 if (usage.data)
6489 delete (MemUsageEntries*) usage.data;
6490}
6491
6492} // end extern "C"
6493
6494void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6495 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6496 for (unsigned I = 0; I != Usage.numEntries; ++I)
6497 fprintf(stderr, " %s: %lu\n",
6498 clang_getTUResourceUsageName(Usage.entries[I].kind),
6499 Usage.entries[I].amount);
6500
6501 clang_disposeCXTUResourceUsage(Usage);
6502}
6503
6504//===----------------------------------------------------------------------===//
6505// Misc. utility functions.
6506//===----------------------------------------------------------------------===//
6507
6508/// Default to using an 8 MB stack size on "safety" threads.
6509static unsigned SafetyStackThreadSize = 8 << 20;
6510
6511namespace clang {
6512
6513bool RunSafely(llvm::CrashRecoveryContext &CRC,
6514 void (*Fn)(void*), void *UserData,
6515 unsigned Size) {
6516 if (!Size)
6517 Size = GetSafetyThreadStackSize();
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006518 if (getenv("LIBCLANG_DISABLE_CRASH_RECOVERY")) {
6519 // Don't use crash recovery.
6520 llvm::llvm_execute_on_thread(Fn, UserData, Size);
6521 return true;
6522 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006523 if (Size)
6524 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6525 return CRC.RunSafely(Fn, UserData);
6526}
6527
6528unsigned GetSafetyThreadStackSize() {
6529 return SafetyStackThreadSize;
6530}
6531
6532void SetSafetyThreadStackSize(unsigned Value) {
6533 SafetyStackThreadSize = Value;
6534}
6535
6536}
6537
6538void clang::setThreadBackgroundPriority() {
6539 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6540 return;
6541
6542 // FIXME: Move to llvm/Support and make it cross-platform.
6543#ifdef __APPLE__
6544 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6545#endif
6546}
6547
6548void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6549 if (!Unit)
6550 return;
6551
6552 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6553 DEnd = Unit->stored_diag_end();
6554 D != DEnd; ++D) {
6555 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6556 CXString Msg = clang_formatDiagnostic(&Diag,
6557 clang_defaultDiagnosticDisplayOptions());
6558 fprintf(stderr, "%s\n", clang_getCString(Msg));
6559 clang_disposeString(Msg);
6560 }
6561#ifdef LLVM_ON_WIN32
6562 // On Windows, force a flush, since there may be multiple copies of
6563 // stderr and stdout in the file system, all with different buffers
6564 // but writing to the same device.
6565 fflush(stderr);
6566#endif
6567}
6568
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006569MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6570 SourceLocation MacroDefLoc,
6571 CXTranslationUnit TU){
6572 if (MacroDefLoc.isInvalid() || !TU)
6573 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006574 if (!II.hadMacroDefinition())
6575 return 0;
6576
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006577 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006578 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006579 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006580 if (MD) {
6581 for (MacroDirective::DefInfo
6582 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6583 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6584 return Def.getMacroInfo();
6585 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006586 }
6587
6588 return 0;
6589}
6590
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006591const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6592 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006593 if (!MacroDef || !TU)
6594 return 0;
6595 const IdentifierInfo *II = MacroDef->getName();
6596 if (!II)
6597 return 0;
6598
6599 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6600}
6601
6602MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6603 const Token &Tok,
6604 CXTranslationUnit TU) {
6605 if (!MI || !TU)
6606 return 0;
6607 if (Tok.isNot(tok::raw_identifier))
6608 return 0;
6609
6610 if (MI->getNumTokens() == 0)
6611 return 0;
6612 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6613 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006614 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006615
6616 // Check that the token is inside the definition and not its argument list.
6617 SourceManager &SM = Unit->getSourceManager();
6618 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6619 return 0;
6620 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6621 return 0;
6622
6623 Preprocessor &PP = Unit->getPreprocessor();
6624 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6625 if (!PPRec)
6626 return 0;
6627
6628 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6629 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6630 if (!II.hadMacroDefinition())
6631 return 0;
6632
6633 // Check that the identifier is not one of the macro arguments.
6634 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6635 return 0;
6636
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006637 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6638 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006639 return 0;
6640
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006641 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006642}
6643
6644MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6645 SourceLocation Loc,
6646 CXTranslationUnit TU) {
6647 if (Loc.isInvalid() || !MI || !TU)
6648 return 0;
6649
6650 if (MI->getNumTokens() == 0)
6651 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006652 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006653 Preprocessor &PP = Unit->getPreprocessor();
6654 if (!PP.getPreprocessingRecord())
6655 return 0;
6656 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6657 Token Tok;
6658 if (PP.getRawToken(Loc, Tok))
6659 return 0;
6660
6661 return checkForMacroInMacroDefinition(MI, Tok, TU);
6662}
6663
Guy Benyei11169dd2012-12-18 14:30:41 +00006664extern "C" {
6665
6666CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006667 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006668}
6669
6670} // end: extern "C"
6671
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006672Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6673 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006674 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006675 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006676 if (Unit->isMainFileAST())
6677 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006678 return *this;
6679 }
6680 }
6681
6682 LogOS << "<NULL TU>";
6683 return *this;
6684}
6685
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006686Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6687 *this << FE->getName();
6688 return *this;
6689}
6690
6691Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6692 CXString cursorName = clang_getCursorDisplayName(cursor);
6693 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6694 clang_disposeString(cursorName);
6695 return *this;
6696}
6697
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006698Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6699 CXFile File;
6700 unsigned Line, Column;
6701 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6702 CXString FileName = clang_getFileName(File);
6703 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6704 clang_disposeString(FileName);
6705 return *this;
6706}
6707
6708Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6709 CXSourceLocation BLoc = clang_getRangeStart(range);
6710 CXSourceLocation ELoc = clang_getRangeEnd(range);
6711
6712 CXFile BFile;
6713 unsigned BLine, BColumn;
6714 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6715
6716 CXFile EFile;
6717 unsigned ELine, EColumn;
6718 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6719
6720 CXString BFileName = clang_getFileName(BFile);
6721 if (BFile == EFile) {
6722 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6723 BLine, BColumn, ELine, EColumn);
6724 } else {
6725 CXString EFileName = clang_getFileName(EFile);
6726 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6727 BLine, BColumn)
6728 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6729 ELine, EColumn);
6730 clang_disposeString(EFileName);
6731 }
6732 clang_disposeString(BFileName);
6733 return *this;
6734}
6735
6736Logger &cxindex::Logger::operator<<(CXString Str) {
6737 *this << clang_getCString(Str);
6738 return *this;
6739}
6740
6741Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6742 LogOS << Fmt;
6743 return *this;
6744}
6745
6746cxindex::Logger::~Logger() {
6747 LogOS.flush();
6748
6749 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6750
6751 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6752
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006753 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006754 OS << "[libclang:" << Name << ':';
6755
6756 // FIXME: Portability.
6757#if HAVE_PTHREAD_H && __APPLE__
6758 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6759 OS << tid << ':';
6760#endif
6761
6762 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6763 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6764 OS << Msg.str() << '\n';
6765
6766 if (Trace) {
6767 llvm::sys::PrintStackTrace(stderr);
6768 OS << "--------------------------------------------------\n";
6769 }
6770}