blob: 1af3c70282824abf49d8327d8fbac42d55524c37 [file] [log] [blame]
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
Fariborz Jahanian88b95212012-12-18 23:02:59 +000025#include "SimpleFormatContext.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
28#include "clang/Basic/Version.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
31#include "clang/Frontend/FrontendDiagnostic.h"
32#include "clang/Lex/HeaderSearch.h"
33#include "clang/Lex/Lexer.h"
34#include "clang/Lex/PreprocessingRecord.h"
35#include "clang/Lex/Preprocessor.h"
36#include "llvm/ADT/Optional.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringSwitch.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000039#include "llvm/Config/config.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000040#include "llvm/Support/Compiler.h"
41#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000042#include "llvm/Support/Format.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000043#include "llvm/Support/MemoryBuffer.h"
44#include "llvm/Support/Mutex.h"
45#include "llvm/Support/PrettyStackTrace.h"
46#include "llvm/Support/Program.h"
47#include "llvm/Support/SaveAndRestore.h"
48#include "llvm/Support/Signals.h"
49#include "llvm/Support/Threading.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +000052
53#if HAVE_PTHREAD_H
54#include <pthread.h>
55#endif
Guy Benyei7f92f2d2012-12-18 14:30:41 +000056
57using namespace clang;
58using namespace clang::cxcursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000059using namespace clang::cxtu;
60using namespace clang::cxindex;
61
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000062CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
63 if (!AU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +000064 return 0;
65 CXTranslationUnit D = new CXTranslationUnitImpl();
66 D->CIdx = CIdx;
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000067 D->TheASTUnit = AU;
Dmitri Gribenkoaca3e562013-02-03 13:52:47 +000068 D->StringPool = new cxstring::CXStringPool();
Guy Benyei7f92f2d2012-12-18 14:30:41 +000069 D->Diagnostics = 0;
70 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Fariborz Jahanian88b95212012-12-18 23:02:59 +000071 D->FormatContext = 0;
72 D->FormatInMemoryUniqueId = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000073 return D;
74}
75
76cxtu::CXTUOwner::~CXTUOwner() {
77 if (TU)
78 clang_disposeTranslationUnit(TU);
79}
80
81/// \brief Compare two source ranges to determine their relative position in
82/// the translation unit.
83static RangeComparisonResult RangeCompare(SourceManager &SM,
84 SourceRange R1,
85 SourceRange R2) {
86 assert(R1.isValid() && "First range is invalid?");
87 assert(R2.isValid() && "Second range is invalid?");
88 if (R1.getEnd() != R2.getBegin() &&
89 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
90 return RangeBefore;
91 if (R2.getEnd() != R1.getBegin() &&
92 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
93 return RangeAfter;
94 return RangeOverlap;
95}
96
97/// \brief Determine if a source location falls within, before, or after a
98/// a given source range.
99static RangeComparisonResult LocationCompare(SourceManager &SM,
100 SourceLocation L, SourceRange R) {
101 assert(R.isValid() && "First range is invalid?");
102 assert(L.isValid() && "Second range is invalid?");
103 if (L == R.getBegin() || L == R.getEnd())
104 return RangeOverlap;
105 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
106 return RangeBefore;
107 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Translate a Clang source range into a CIndex source range.
113///
114/// Clang internally represents ranges where the end location points to the
115/// start of the token at the end. However, for external clients it is more
116/// useful to have a CXSourceRange be a proper half-open interval. This routine
117/// does the appropriate translation.
118CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
119 const LangOptions &LangOpts,
120 const CharSourceRange &R) {
121 // We want the last character in this location, so we will adjust the
122 // location accordingly.
123 SourceLocation EndLoc = R.getEnd();
124 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
125 EndLoc = SM.getExpansionRange(EndLoc).second;
126 if (R.isTokenRange() && !EndLoc.isInvalid()) {
127 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
128 SM, LangOpts);
129 EndLoc = EndLoc.getLocWithOffset(Length);
130 }
131
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000132 CXSourceRange Result = {
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +0000133 { &SM, &LangOpts },
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000134 R.getBegin().getRawEncoding(),
135 EndLoc.getRawEncoding()
136 };
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000137 return Result;
138}
139
140//===----------------------------------------------------------------------===//
141// Cursor visitor.
142//===----------------------------------------------------------------------===//
143
144static SourceRange getRawCursorExtent(CXCursor C);
145static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
146
147
148RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
149 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
150}
151
152/// \brief Visit the given cursor and, if requested by the visitor,
153/// its children.
154///
155/// \param Cursor the cursor to visit.
156///
157/// \param CheckedRegionOfInterest if true, then the caller already checked
158/// that this cursor is within the region of interest.
159///
160/// \returns true if the visitation should be aborted, false if it
161/// should continue.
162bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
163 if (clang_isInvalid(Cursor.kind))
164 return false;
165
166 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000167 const Decl *D = getCursorDecl(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000168 if (!D) {
169 assert(0 && "Invalid declaration cursor");
170 return true; // abort.
171 }
172
173 // Ignore implicit declarations, unless it's an objc method because
174 // currently we should report implicit methods for properties when indexing.
175 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
176 return false;
177 }
178
179 // If we have a range of interest, and this cursor doesn't intersect with it,
180 // we're done.
181 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
182 SourceRange Range = getRawCursorExtent(Cursor);
183 if (Range.isInvalid() || CompareRegionOfInterest(Range))
184 return false;
185 }
186
187 switch (Visitor(Cursor, Parent, ClientData)) {
188 case CXChildVisit_Break:
189 return true;
190
191 case CXChildVisit_Continue:
192 return false;
193
194 case CXChildVisit_Recurse: {
195 bool ret = VisitChildren(Cursor);
196 if (PostChildrenVisitor)
197 if (PostChildrenVisitor(Cursor, ClientData))
198 return true;
199 return ret;
200 }
201 }
202
203 llvm_unreachable("Invalid CXChildVisitResult!");
204}
205
206static bool visitPreprocessedEntitiesInRange(SourceRange R,
207 PreprocessingRecord &PPRec,
208 CursorVisitor &Visitor) {
209 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
210 FileID FID;
211
212 if (!Visitor.shouldVisitIncludedEntities()) {
213 // If the begin/end of the range lie in the same FileID, do the optimization
214 // where we skip preprocessed entities that do not come from the same FileID.
215 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
216 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
217 FID = FileID();
218 }
219
220 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
221 Entities = PPRec.getPreprocessedEntitiesInRange(R);
222 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
223 PPRec, FID);
224}
225
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000226bool CursorVisitor::visitFileRegion() {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000227 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000228 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000229
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000230 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000231 SourceManager &SM = Unit->getSourceManager();
232
233 std::pair<FileID, unsigned>
234 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
235 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
236
237 if (End.first != Begin.first) {
238 // If the end does not reside in the same file, try to recover by
239 // picking the end of the file of begin location.
240 End.first = Begin.first;
241 End.second = SM.getFileIDSize(Begin.first);
242 }
243
244 assert(Begin.first == End.first);
245 if (Begin.second > End.second)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000246 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000247
248 FileID File = Begin.first;
249 unsigned Offset = Begin.second;
250 unsigned Length = End.second - Begin.second;
251
252 if (!VisitDeclsOnly && !VisitPreprocessorLast)
253 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000254 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000255
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000256 if (visitDeclsFromFileRegion(File, Offset, Length))
257 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000258
259 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000260 return visitPreprocessedEntitiesInRegion();
261
262 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000263}
264
265static bool isInLexicalContext(Decl *D, DeclContext *DC) {
266 if (!DC)
267 return false;
268
269 for (DeclContext *DeclDC = D->getLexicalDeclContext();
270 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
271 if (DeclDC == DC)
272 return true;
273 }
274 return false;
275}
276
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000277bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000278 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000279 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000280 SourceManager &SM = Unit->getSourceManager();
281 SourceRange Range = RegionOfInterest;
282
283 SmallVector<Decl *, 16> Decls;
284 Unit->findFileRegionDecls(File, Offset, Length, Decls);
285
286 // If we didn't find any file level decls for the file, try looking at the
287 // file that it was included from.
288 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
289 bool Invalid = false;
290 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
291 if (Invalid)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000292 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000293
294 SourceLocation Outer;
295 if (SLEntry.isFile())
296 Outer = SLEntry.getFile().getIncludeLoc();
297 else
298 Outer = SLEntry.getExpansion().getExpansionLocStart();
299 if (Outer.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000300 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000301
302 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
303 Length = 0;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305 }
306
307 assert(!Decls.empty());
308
309 bool VisitedAtLeastOnce = false;
310 DeclContext *CurDC = 0;
Craig Topper09d19ef2013-07-04 03:08:24 +0000311 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
312 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000313 Decl *D = *DIt;
314 if (D->getSourceRange().isInvalid())
315 continue;
316
317 if (isInLexicalContext(D, CurDC))
318 continue;
319
320 CurDC = dyn_cast<DeclContext>(D);
321
322 if (TagDecl *TD = dyn_cast<TagDecl>(D))
323 if (!TD->isFreeStanding())
324 continue;
325
326 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
327 if (CompRes == RangeBefore)
328 continue;
329 if (CompRes == RangeAfter)
330 break;
331
332 assert(CompRes == RangeOverlap);
333 VisitedAtLeastOnce = true;
334
335 if (isa<ObjCContainerDecl>(D)) {
336 FileDI_current = &DIt;
337 FileDE_current = DE;
338 } else {
339 FileDI_current = 0;
340 }
341
342 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000343 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000344 }
345
346 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000347 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000348
349 // No Decls overlapped with the range. Move up the lexical context until there
350 // is a context that contains the range or we reach the translation unit
351 // level.
352 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
353 : (*(DIt-1))->getLexicalDeclContext();
354
355 while (DC && !DC->isTranslationUnit()) {
356 Decl *D = cast<Decl>(DC);
357 SourceRange CurDeclRange = D->getSourceRange();
358 if (CurDeclRange.isInvalid())
359 break;
360
361 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
363 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000364 }
365
366 DC = D->getLexicalDeclContext();
367 }
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000368
369 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000370}
371
372bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
373 if (!AU->getPreprocessor().getPreprocessingRecord())
374 return false;
375
376 PreprocessingRecord &PPRec
377 = *AU->getPreprocessor().getPreprocessingRecord();
378 SourceManager &SM = AU->getSourceManager();
379
380 if (RegionOfInterest.isValid()) {
381 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
382 SourceLocation B = MappedRange.getBegin();
383 SourceLocation E = MappedRange.getEnd();
384
385 if (AU->isInPreambleFileID(B)) {
386 if (SM.isLoadedSourceLocation(E))
387 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
388 PPRec, *this);
389
390 // Beginning of range lies in the preamble but it also extends beyond
391 // it into the main file. Split the range into 2 parts, one covering
392 // the preamble and another covering the main file. This allows subsequent
393 // calls to visitPreprocessedEntitiesInRange to accept a source range that
394 // lies in the same FileID, allowing it to skip preprocessed entities that
395 // do not come from the same FileID.
396 bool breaked =
397 visitPreprocessedEntitiesInRange(
398 SourceRange(B, AU->getEndOfPreambleFileID()),
399 PPRec, *this);
400 if (breaked) return true;
401 return visitPreprocessedEntitiesInRange(
402 SourceRange(AU->getStartOfMainFileID(), E),
403 PPRec, *this);
404 }
405
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
407 }
408
409 bool OnlyLocalDecls
410 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
411
412 if (OnlyLocalDecls)
413 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
414 PPRec);
415
416 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
417}
418
419template<typename InputIterator>
420bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
421 InputIterator Last,
422 PreprocessingRecord &PPRec,
423 FileID FID) {
424 for (; First != Last; ++First) {
425 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
426 continue;
427
428 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis333e44c2013-05-07 20:37:17 +0000429 if (!PPE)
430 continue;
431
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000432 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
433 if (Visit(MakeMacroExpansionCursor(ME, TU)))
434 return true;
435
436 continue;
437 }
438
439 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
440 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
441 return true;
442
443 continue;
444 }
445
446 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
447 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
448 return true;
449
450 continue;
451 }
452 }
453
454 return false;
455}
456
457/// \brief Visit the children of the given cursor.
458///
459/// \returns true if the visitation should be aborted, false if it
460/// should continue.
461bool CursorVisitor::VisitChildren(CXCursor Cursor) {
462 if (clang_isReference(Cursor.kind) &&
463 Cursor.kind != CXCursor_CXXBaseSpecifier) {
464 // By definition, references have no children.
465 return false;
466 }
467
468 // Set the Parent field to Cursor, then back to its old value once we're
469 // done.
470 SetParentRAII SetParent(Parent, StmtParent, Cursor);
471
472 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000473 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000474 if (!D)
475 return false;
476
477 return VisitAttributes(D) || Visit(D);
478 }
479
480 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000481 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000482 return Visit(S);
483
484 return false;
485 }
486
487 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000488 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000489 return Visit(E);
490
491 return false;
492 }
493
494 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000495 CXTranslationUnit TU = getCursorTU(Cursor);
496 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000497
498 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
499 for (unsigned I = 0; I != 2; ++I) {
500 if (VisitOrder[I]) {
501 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
502 RegionOfInterest.isInvalid()) {
503 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
504 TLEnd = CXXUnit->top_level_end();
505 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000506 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000507 return true;
508 }
509 } else if (VisitDeclContext(
510 CXXUnit->getASTContext().getTranslationUnitDecl()))
511 return true;
512 continue;
513 }
514
515 // Walk the preprocessing record.
516 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
517 visitPreprocessedEntitiesInRegion();
518 }
519
520 return false;
521 }
522
523 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000524 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000525 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
526 return Visit(BaseTSInfo->getTypeLoc());
527 }
528 }
529 }
530
531 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000532 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000533 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
534 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
535 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
536 A->getInterfaceLoc(), TU));
537 }
538
Argyrios Kyrtzidis664b06f2013-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 Gribenko67812b22013-01-11 21:01:49 +0000546 const MacroInfo *MI =
547 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-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 Benyei7f92f2d2012-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 Kremenek943f9092013-02-21 01:29:01 +0000568Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000569 if (RegionOfInterest.isValid()) {
570 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
571 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000572 return None;
Guy Benyei7f92f2d2012-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 Blaikie66874fb2013-02-21 01:47:18 +0000577 return None;
Guy Benyei7f92f2d2012-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 Kremenek943f9092013-02-21 01:29:01 +0000628 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-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 Blaikie39e6ab42013-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 Benyei7f92f2d2012-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 Zaffanellac1cef082013-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 Benyei7f92f2d2012-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 Kyrtzidis516143b2013-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 Benyei7f92f2d2012-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.
750static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
751 CXXCtorInitializer const * const *X
752 = static_cast<CXXCtorInitializer const * const *>(Xp);
753 CXXCtorInitializer const * const *Y
754 = static_cast<CXXCtorInitializer const * const *>(Yp);
755
756 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
757 return -1;
758 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
759 return 1;
760 else
761 return 0;
762}
763
764bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000765 unsigned NumParamList = ND->getNumTemplateParameterLists();
766 for (unsigned i = 0; i < NumParamList; i++) {
767 TemplateParameterList* Params = ND->getTemplateParameterList(i);
768 if (VisitTemplateParameters(Params))
769 return true;
770 }
771
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000772 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
773 // Visit the function declaration's syntactic components in the order
774 // written. This requires a bit of work.
775 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000776 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000777
778 // If we have a function declared directly (without the use of a typedef),
779 // visit just the return type. Otherwise, just visit the function's type
780 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000781 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000782 (!FTL && Visit(TL)))
783 return true;
784
785 // Visit the nested-name-specifier, if present.
786 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
787 if (VisitNestedNameSpecifierLoc(QualifierLoc))
788 return true;
789
790 // Visit the declaration name.
791 if (VisitDeclarationNameInfo(ND->getNameInfo()))
792 return true;
793
794 // FIXME: Visit explicitly-specified template arguments!
795
796 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000797 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000798 return true;
799
Bill Wendlingad017fa2012-12-20 19:22:21 +0000800 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000801 }
802
803 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
804 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
805 // Find the initializers that were written in the source.
806 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
807 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
808 IEnd = Constructor->init_end();
809 I != IEnd; ++I) {
810 if (!(*I)->isWritten())
811 continue;
812
813 WrittenInits.push_back(*I);
814 }
815
816 // Sort the initializers in source order
817 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
818 &CompareCXXCtorInitializers);
819
820 // Visit the initializers in source order
821 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
822 CXXCtorInitializer *Init = WrittenInits[I];
823 if (Init->isAnyMemberInitializer()) {
824 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
825 Init->getMemberLocation(), TU)))
826 return true;
827 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
828 if (Visit(TInfo->getTypeLoc()))
829 return true;
830 }
831
832 // Visit the initializer value.
833 if (Expr *Initializer = Init->getInit())
834 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
835 return true;
836 }
837 }
838
839 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
840 return true;
841 }
842
843 return false;
844}
845
846bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
847 if (VisitDeclaratorDecl(D))
848 return true;
849
850 if (Expr *BitWidth = D->getBitWidth())
851 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
852
853 return false;
854}
855
856bool CursorVisitor::VisitVarDecl(VarDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *Init = D->getInit())
861 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
871 if (Expr *DefArg = D->getDefaultArgument())
872 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
878 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
879 // before visiting these template parameters.
880 if (VisitTemplateParameters(D->getTemplateParameters()))
881 return true;
882
883 return VisitFunctionDecl(D->getTemplatedDecl());
884}
885
886bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
887 // FIXME: Visit the "outer" template parameter lists on the TagDecl
888 // before visiting these template parameters.
889 if (VisitTemplateParameters(D->getTemplateParameters()))
890 return true;
891
892 return VisitCXXRecordDecl(D->getTemplatedDecl());
893}
894
895bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
896 if (VisitTemplateParameters(D->getTemplateParameters()))
897 return true;
898
899 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
900 VisitTemplateArgumentLoc(D->getDefaultArgument()))
901 return true;
902
903 return false;
904}
905
906bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
907 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
908 if (Visit(TSInfo->getTypeLoc()))
909 return true;
910
911 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
912 PEnd = ND->param_end();
913 P != PEnd; ++P) {
914 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
915 return true;
916 }
917
918 if (ND->isThisDeclarationADefinition() &&
919 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
920 return true;
921
922 return false;
923}
924
925template <typename DeclIt>
926static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
927 SourceManager &SM, SourceLocation EndLoc,
928 SmallVectorImpl<Decl *> &Decls) {
929 DeclIt next = *DI_current;
930 while (++next != DE_current) {
931 Decl *D_next = *next;
932 if (!D_next)
933 break;
934 SourceLocation L = D_next->getLocStart();
935 if (!L.isValid())
936 break;
937 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
938 *DI_current = next;
939 Decls.push_back(D_next);
940 continue;
941 }
942 break;
943 }
944}
945
946namespace {
947 struct ContainerDeclsSort {
948 SourceManager &SM;
949 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
950 bool operator()(Decl *A, Decl *B) {
951 SourceLocation L_A = A->getLocStart();
952 SourceLocation L_B = B->getLocStart();
953 assert(L_A.isValid() && L_B.isValid());
954 return SM.isBeforeInTranslationUnit(L_A, L_B);
955 }
956 };
957}
958
959bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
960 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
961 // an @implementation can lexically contain Decls that are not properly
962 // nested in the AST. When we identify such cases, we need to retrofit
963 // this nesting here.
964 if (!DI_current && !FileDI_current)
965 return VisitDeclContext(D);
966
967 // Scan the Decls that immediately come after the container
968 // in the current DeclContext. If any fall within the
969 // container's lexical region, stash them into a vector
970 // for later processing.
971 SmallVector<Decl *, 24> DeclsInContainer;
972 SourceLocation EndLoc = D->getSourceRange().getEnd();
973 SourceManager &SM = AU->getSourceManager();
974 if (EndLoc.isValid()) {
975 if (DI_current) {
976 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
977 DeclsInContainer);
978 } else {
979 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
980 DeclsInContainer);
981 }
982 }
983
984 // The common case.
985 if (DeclsInContainer.empty())
986 return VisitDeclContext(D);
987
988 // Get all the Decls in the DeclContext, and sort them with the
989 // additional ones we've collected. Then visit them.
990 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
991 I!=E; ++I) {
992 Decl *subDecl = *I;
993 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
994 subDecl->getLocStart().isInvalid())
995 continue;
996 DeclsInContainer.push_back(subDecl);
997 }
998
999 // Now sort the Decls so that they appear in lexical order.
1000 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1001 ContainerDeclsSort(SM));
1002
1003 // Now visit the decls.
1004 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1005 E = DeclsInContainer.end(); I != E; ++I) {
1006 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +00001007 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001008 if (!V.hasValue())
1009 continue;
1010 if (!V.getValue())
1011 return false;
1012 if (Visit(Cursor, true))
1013 return true;
1014 }
1015 return false;
1016}
1017
1018bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1019 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1020 TU)))
1021 return true;
1022
1023 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1024 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1025 E = ND->protocol_end(); I != E; ++I, ++PL)
1026 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1027 return true;
1028
1029 return VisitObjCContainerDecl(ND);
1030}
1031
1032bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1033 if (!PID->isThisDeclarationADefinition())
1034 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1035
1036 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1037 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1038 E = PID->protocol_end(); I != E; ++I, ++PL)
1039 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1040 return true;
1041
1042 return VisitObjCContainerDecl(PID);
1043}
1044
1045bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1046 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1047 return true;
1048
1049 // FIXME: This implements a workaround with @property declarations also being
1050 // installed in the DeclContext for the @interface. Eventually this code
1051 // should be removed.
1052 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1053 if (!CDecl || !CDecl->IsClassExtension())
1054 return false;
1055
1056 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1057 if (!ID)
1058 return false;
1059
1060 IdentifierInfo *PropertyId = PD->getIdentifier();
1061 ObjCPropertyDecl *prevDecl =
1062 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1063
1064 if (!prevDecl)
1065 return false;
1066
1067 // Visit synthesized methods since they will be skipped when visiting
1068 // the @interface.
1069 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1070 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1071 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1072 return true;
1073
1074 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1075 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1076 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1077 return true;
1078
1079 return false;
1080}
1081
1082bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1083 if (!D->isThisDeclarationADefinition()) {
1084 // Forward declaration is treated like a reference.
1085 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1086 }
1087
1088 // Issue callbacks for super class.
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1091 D->getSuperClassLoc(),
1092 TU)))
1093 return true;
1094
1095 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1096 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1097 E = D->protocol_end(); I != E; ++I, ++PL)
1098 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1099 return true;
1100
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1105 return VisitObjCContainerDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1109 // 'ID' could be null when dealing with invalid code.
1110 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1111 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1112 return true;
1113
1114 return VisitObjCImplDecl(D);
1115}
1116
1117bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1118#if 0
1119 // Issue callbacks for super class.
1120 // FIXME: No source location information!
1121 if (D->getSuperClass() &&
1122 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1123 D->getSuperClassLoc(),
1124 TU)))
1125 return true;
1126#endif
1127
1128 return VisitObjCImplDecl(D);
1129}
1130
1131bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1132 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1133 if (PD->isIvarNameSpecified())
1134 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1135
1136 return false;
1137}
1138
1139bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1140 return VisitDeclContext(D);
1141}
1142
1143bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1144 // Visit nested-name-specifier.
1145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1147 return true;
1148
1149 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1150 D->getTargetNameLoc(), TU));
1151}
1152
1153bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1154 // Visit nested-name-specifier.
1155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1157 return true;
1158 }
1159
1160 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1161 return true;
1162
1163 return VisitDeclarationNameInfo(D->getNameInfo());
1164}
1165
1166bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1167 // Visit nested-name-specifier.
1168 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1169 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1170 return true;
1171
1172 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1173 D->getIdentLocation(), TU));
1174}
1175
1176bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1177 // Visit nested-name-specifier.
1178 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1179 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1180 return true;
1181 }
1182
1183 return VisitDeclarationNameInfo(D->getNameInfo());
1184}
1185
1186bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1187 UnresolvedUsingTypenameDecl *D) {
1188 // Visit nested-name-specifier.
1189 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1190 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1191 return true;
1192
1193 return false;
1194}
1195
1196bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1197 switch (Name.getName().getNameKind()) {
1198 case clang::DeclarationName::Identifier:
1199 case clang::DeclarationName::CXXLiteralOperatorName:
1200 case clang::DeclarationName::CXXOperatorName:
1201 case clang::DeclarationName::CXXUsingDirective:
1202 return false;
1203
1204 case clang::DeclarationName::CXXConstructorName:
1205 case clang::DeclarationName::CXXDestructorName:
1206 case clang::DeclarationName::CXXConversionFunctionName:
1207 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1208 return Visit(TSInfo->getTypeLoc());
1209 return false;
1210
1211 case clang::DeclarationName::ObjCZeroArgSelector:
1212 case clang::DeclarationName::ObjCOneArgSelector:
1213 case clang::DeclarationName::ObjCMultiArgSelector:
1214 // FIXME: Per-identifier location info?
1215 return false;
1216 }
1217
1218 llvm_unreachable("Invalid DeclarationName::Kind!");
1219}
1220
1221bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1222 SourceRange Range) {
1223 // FIXME: This whole routine is a hack to work around the lack of proper
1224 // source information in nested-name-specifiers (PR5791). Since we do have
1225 // a beginning source location, we can visit the first component of the
1226 // nested-name-specifier, if it's a single-token component.
1227 if (!NNS)
1228 return false;
1229
1230 // Get the first component in the nested-name-specifier.
1231 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1232 NNS = Prefix;
1233
1234 switch (NNS->getKind()) {
1235 case NestedNameSpecifier::Namespace:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1237 TU));
1238
1239 case NestedNameSpecifier::NamespaceAlias:
1240 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1241 Range.getBegin(), TU));
1242
1243 case NestedNameSpecifier::TypeSpec: {
1244 // If the type has a form where we know that the beginning of the source
1245 // range matches up with a reference cursor. Visit the appropriate reference
1246 // cursor.
1247 const Type *T = NNS->getAsType();
1248 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1249 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1250 if (const TagType *Tag = dyn_cast<TagType>(T))
1251 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1252 if (const TemplateSpecializationType *TST
1253 = dyn_cast<TemplateSpecializationType>(T))
1254 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1255 break;
1256 }
1257
1258 case NestedNameSpecifier::TypeSpecWithTemplate:
1259 case NestedNameSpecifier::Global:
1260 case NestedNameSpecifier::Identifier:
1261 break;
1262 }
1263
1264 return false;
1265}
1266
1267bool
1268CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1269 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1270 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1271 Qualifiers.push_back(Qualifier);
1272
1273 while (!Qualifiers.empty()) {
1274 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1275 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1276 switch (NNS->getKind()) {
1277 case NestedNameSpecifier::Namespace:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::NamespaceAlias:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::TypeSpec:
1294 case NestedNameSpecifier::TypeSpecWithTemplate:
1295 if (Visit(Q.getTypeLoc()))
1296 return true;
1297
1298 break;
1299
1300 case NestedNameSpecifier::Global:
1301 case NestedNameSpecifier::Identifier:
1302 break;
1303 }
1304 }
1305
1306 return false;
1307}
1308
1309bool CursorVisitor::VisitTemplateParameters(
1310 const TemplateParameterList *Params) {
1311 if (!Params)
1312 return false;
1313
1314 for (TemplateParameterList::const_iterator P = Params->begin(),
1315 PEnd = Params->end();
1316 P != PEnd; ++P) {
1317 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1318 return true;
1319 }
1320
1321 return false;
1322}
1323
1324bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1325 switch (Name.getKind()) {
1326 case TemplateName::Template:
1327 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1328
1329 case TemplateName::OverloadedTemplate:
1330 // Visit the overloaded template set.
1331 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1332 return true;
1333
1334 return false;
1335
1336 case TemplateName::DependentTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return false;
1339
1340 case TemplateName::QualifiedTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return Visit(MakeCursorTemplateRef(
1343 Name.getAsQualifiedTemplateName()->getDecl(),
1344 Loc, TU));
1345
1346 case TemplateName::SubstTemplateTemplateParm:
1347 return Visit(MakeCursorTemplateRef(
1348 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1349 Loc, TU));
1350
1351 case TemplateName::SubstTemplateTemplateParmPack:
1352 return Visit(MakeCursorTemplateRef(
1353 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1354 Loc, TU));
1355 }
1356
1357 llvm_unreachable("Invalid TemplateName::Kind!");
1358}
1359
1360bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1361 switch (TAL.getArgument().getKind()) {
1362 case TemplateArgument::Null:
1363 case TemplateArgument::Integral:
1364 case TemplateArgument::Pack:
1365 return false;
1366
1367 case TemplateArgument::Type:
1368 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1369 return Visit(TSInfo->getTypeLoc());
1370 return false;
1371
1372 case TemplateArgument::Declaration:
1373 if (Expr *E = TAL.getSourceDeclExpression())
1374 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1375 return false;
1376
1377 case TemplateArgument::NullPtr:
1378 if (Expr *E = TAL.getSourceNullPtrExpression())
1379 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1380 return false;
1381
1382 case TemplateArgument::Expression:
1383 if (Expr *E = TAL.getSourceExpression())
1384 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1385 return false;
1386
1387 case TemplateArgument::Template:
1388 case TemplateArgument::TemplateExpansion:
1389 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1390 return true;
1391
1392 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1393 TAL.getTemplateNameLoc());
1394 }
1395
1396 llvm_unreachable("Invalid TemplateArgument::Kind!");
1397}
1398
1399bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1400 return VisitDeclContext(D);
1401}
1402
1403bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1404 return Visit(TL.getUnqualifiedLoc());
1405}
1406
1407bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1408 ASTContext &Context = AU->getASTContext();
1409
1410 // Some builtin types (such as Objective-C's "id", "sel", and
1411 // "Class") have associated declarations. Create cursors for those.
1412 QualType VisitType;
1413 switch (TL.getTypePtr()->getKind()) {
1414
1415 case BuiltinType::Void:
1416 case BuiltinType::NullPtr:
1417 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001418 case BuiltinType::OCLImage1d:
1419 case BuiltinType::OCLImage1dArray:
1420 case BuiltinType::OCLImage1dBuffer:
1421 case BuiltinType::OCLImage2d:
1422 case BuiltinType::OCLImage2dArray:
1423 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001424 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001425 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001426#define BUILTIN_TYPE(Id, SingletonId)
1427#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#include "clang/AST/BuiltinTypes.def"
1432 break;
1433
1434 case BuiltinType::ObjCId:
1435 VisitType = Context.getObjCIdType();
1436 break;
1437
1438 case BuiltinType::ObjCClass:
1439 VisitType = Context.getObjCClassType();
1440 break;
1441
1442 case BuiltinType::ObjCSel:
1443 VisitType = Context.getObjCSelType();
1444 break;
1445 }
1446
1447 if (!VisitType.isNull()) {
1448 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1449 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1450 TU));
1451 }
1452
1453 return false;
1454}
1455
1456bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1465 if (TL.isDefinition())
1466 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1467
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1476 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1477 return true;
1478
1479 return false;
1480}
1481
1482bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1483 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1484 return true;
1485
1486 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1487 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1488 TU)))
1489 return true;
1490 }
1491
1492 return false;
1493}
1494
1495bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1500 return Visit(TL.getInnerLoc());
1501}
1502
1503bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1524 return Visit(TL.getModifiedLoc());
1525}
1526
1527bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1528 bool SkipResultType) {
1529 if (!SkipResultType && Visit(TL.getResultLoc()))
1530 return true;
1531
1532 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1533 if (Decl *D = TL.getArg(I))
1534 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1535 return true;
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1541 if (Visit(TL.getElementLoc()))
1542 return true;
1543
1544 if (Expr *Size = TL.getSizeExpr())
1545 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1546
1547 return false;
1548}
1549
Reid Kleckner12df2462013-06-24 17:51:48 +00001550bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001554bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1555 TemplateSpecializationTypeLoc TL) {
1556 // Visit the template name.
1557 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1558 TL.getTemplateNameLoc()))
1559 return true;
1560
1561 // Visit the template arguments.
1562 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1563 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1564 return true;
1565
1566 return false;
1567}
1568
1569bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1570 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1571}
1572
1573bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1574 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1575 return Visit(TSInfo->getTypeLoc());
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1595 DependentTemplateSpecializationTypeLoc TL) {
1596 // Visit the nested-name-specifier, if there is one.
1597 if (TL.getQualifierLoc() &&
1598 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1599 return true;
1600
1601 // Visit the template arguments.
1602 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1603 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1604 return true;
1605
1606 return false;
1607}
1608
1609bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1610 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 return Visit(TL.getNamedTypeLoc());
1614}
1615
1616bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1617 return Visit(TL.getPatternLoc());
1618}
1619
1620bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1621 if (Expr *E = TL.getUnderlyingExpr())
1622 return Visit(MakeCXCursor(E, StmtParent, TU));
1623
1624 return false;
1625}
1626
1627bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1628 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1629}
1630
1631bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1632 return Visit(TL.getValueLoc());
1633}
1634
1635#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1636bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1637 return Visit##PARENT##Loc(TL); \
1638}
1639
1640DEFAULT_TYPELOC_IMPL(Complex, Type)
1641DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1646DEFAULT_TYPELOC_IMPL(Vector, Type)
1647DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1648DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1649DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1650DEFAULT_TYPELOC_IMPL(Record, TagType)
1651DEFAULT_TYPELOC_IMPL(Enum, TagType)
1652DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1653DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1654DEFAULT_TYPELOC_IMPL(Auto, Type)
1655
1656bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1657 // Visit the nested-name-specifier, if present.
1658 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1659 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1660 return true;
1661
1662 if (D->isCompleteDefinition()) {
1663 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1664 E = D->bases_end(); I != E; ++I) {
1665 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1666 return true;
1667 }
1668 }
1669
1670 return VisitTagDecl(D);
1671}
1672
1673bool CursorVisitor::VisitAttributes(Decl *D) {
1674 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1675 i != e; ++i)
1676 if (Visit(MakeCXCursor(*i, D, TU)))
1677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001711 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
1847 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1848 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001860
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001861private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001862 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001863 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1864 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001865 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1866 void AddStmt(const Stmt *S);
1867 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001868 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001869 void EnqueueChildren(const Stmt *S);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001870 void EnqueueChildren(const OMPClause *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001871};
1872} // end anonyous namespace
1873
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001874void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001875 // 'S' should always be non-null, since it comes from the
1876 // statement we are visiting.
1877 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1878}
1879
1880void
1881EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1882 if (Qualifier)
1883 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1884}
1885
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001886void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001887 if (S)
1888 WL.push_back(StmtVisit(S, Parent));
1889}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001890void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001891 if (D)
1892 WL.push_back(DeclVisit(D, Parent, isFirst));
1893}
1894void EnqueueVisitor::
1895 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1896 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001897 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001898}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001899void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 if (D)
1901 WL.push_back(MemberRefVisit(D, L, Parent));
1902}
1903void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1904 if (TI)
1905 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1906 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001907void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001908 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001909 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001910 AddStmt(*Child);
1911 }
1912 if (size == WL.size())
1913 return;
1914 // Now reverse the entries we just added. This will match the DFS
1915 // ordering performed by the worklist.
1916 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1917 std::reverse(I, E);
1918}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001919namespace {
1920class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1921 EnqueueVisitor *Visitor;
1922public:
1923 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1924#define OPENMP_CLAUSE(Name, Class) \
1925 void Visit##Class(const Class *C);
1926#include "clang/Basic/OpenMPKinds.def"
1927};
1928
1929void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
1930#define PROCESS_OMP_CLAUSE_LIST(Class, Node) \
1931 for (OMPVarList<Class>::varlist_const_iterator I = Node->varlist_begin(), \
1932 E = Node->varlist_end(); \
1933 I != E; ++I) \
1934 Visitor->AddStmt(*I);
1935
1936void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
1937 PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
1938}
1939#undef PROCESS_OMP_CLAUSE_LIST
1940}
1941void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1942 unsigned size = WL.size();
1943 OMPClauseEnqueue Visitor(this);
1944 Visitor.Visit(S);
1945 if (size == WL.size())
1946 return;
1947 // Now reverse the entries we just added. This will match the DFS
1948 // ordering performed by the worklist.
1949 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1950 std::reverse(I, E);
1951}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001952void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001953 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1954}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001955void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001956 AddDecl(B->getBlockDecl());
1957}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001958void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001959 EnqueueChildren(E);
1960 AddTypeLoc(E->getTypeSourceInfo());
1961}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001962void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1963 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001964 E = S->body_rend(); I != E; ++I) {
1965 AddStmt(*I);
1966 }
1967}
1968void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001969VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001970 AddStmt(S->getSubStmt());
1971 AddDeclarationNameInfo(S);
1972 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1973 AddNestedNameSpecifierLoc(QualifierLoc);
1974}
1975
1976void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001977VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001978 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1979 AddDeclarationNameInfo(E);
1980 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1981 AddNestedNameSpecifierLoc(QualifierLoc);
1982 if (!E->isImplicitAccess())
1983 AddStmt(E->getBase());
1984}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001985void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001986 // Enqueue the initializer , if any.
1987 AddStmt(E->getInitializer());
1988 // Enqueue the array size, if any.
1989 AddStmt(E->getArraySize());
1990 // Enqueue the allocated type.
1991 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1992 // Enqueue the placement arguments.
1993 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1994 AddStmt(E->getPlacementArg(I-1));
1995}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001996void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001997 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1998 AddStmt(CE->getArg(I-1));
1999 AddStmt(CE->getCallee());
2000 AddStmt(CE->getArg(0));
2001}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002002void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2003 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002004 // Visit the name of the type being destroyed.
2005 AddTypeLoc(E->getDestroyedTypeInfo());
2006 // Visit the scope type that looks disturbingly like the nested-name-specifier
2007 // but isn't.
2008 AddTypeLoc(E->getScopeTypeInfo());
2009 // Visit the nested-name-specifier.
2010 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2011 AddNestedNameSpecifierLoc(QualifierLoc);
2012 // Visit base expression.
2013 AddStmt(E->getBase());
2014}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2016 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002017 AddTypeLoc(E->getTypeSourceInfo());
2018}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2020 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002021 EnqueueChildren(E);
2022 AddTypeLoc(E->getTypeSourceInfo());
2023}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002024void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002025 EnqueueChildren(E);
2026 if (E->isTypeOperand())
2027 AddTypeLoc(E->getTypeOperandSourceInfo());
2028}
2029
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2031 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002032 EnqueueChildren(E);
2033 AddTypeLoc(E->getTypeSourceInfo());
2034}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002036 EnqueueChildren(E);
2037 if (E->isTypeOperand())
2038 AddTypeLoc(E->getTypeOperandSourceInfo());
2039}
2040
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002042 EnqueueChildren(S);
2043 AddDecl(S->getExceptionDecl());
2044}
2045
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002047 if (DR->hasExplicitTemplateArgs()) {
2048 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2049 }
2050 WL.push_back(DeclRefExprParts(DR, Parent));
2051}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2053 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002054 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2055 AddDeclarationNameInfo(E);
2056 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2057}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002059 unsigned size = WL.size();
2060 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002061 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002062 D != DEnd; ++D) {
2063 AddDecl(*D, isFirst);
2064 isFirst = false;
2065 }
2066 if (size == WL.size())
2067 return;
2068 // Now reverse the entries we just added. This will match the DFS
2069 // ordering performed by the worklist.
2070 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2071 std::reverse(I, E);
2072}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002074 AddStmt(E->getInit());
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002075 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002076 D = E->designators_rbegin(), DEnd = E->designators_rend();
2077 D != DEnd; ++D) {
2078 if (D->isFieldDesignator()) {
2079 if (FieldDecl *Field = D->getField())
2080 AddMemberRef(Field, D->getFieldLoc());
2081 continue;
2082 }
2083 if (D->isArrayDesignator()) {
2084 AddStmt(E->getArrayIndex(*D));
2085 continue;
2086 }
2087 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2088 AddStmt(E->getArrayRangeEnd(*D));
2089 AddStmt(E->getArrayRangeStart(*D));
2090 }
2091}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002093 EnqueueChildren(E);
2094 AddTypeLoc(E->getTypeInfoAsWritten());
2095}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002097 AddStmt(FS->getBody());
2098 AddStmt(FS->getInc());
2099 AddStmt(FS->getCond());
2100 AddDecl(FS->getConditionVariable());
2101 AddStmt(FS->getInit());
2102}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002104 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2105}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002107 AddStmt(If->getElse());
2108 AddStmt(If->getThen());
2109 AddStmt(If->getCond());
2110 AddDecl(If->getConditionVariable());
2111}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002113 // We care about the syntactic form of the initializer list, only.
2114 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2115 IE = Syntactic;
2116 EnqueueChildren(IE);
2117}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002119 WL.push_back(MemberExprParts(M, Parent));
2120
2121 // If the base of the member access expression is an implicit 'this', don't
2122 // visit it.
2123 // FIXME: If we ever want to show these implicit accesses, this will be
2124 // unfortunate. However, clang_getCursor() relies on this behavior.
2125 if (!M->isImplicitAccess())
2126 AddStmt(M->getBase());
2127}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002129 AddTypeLoc(E->getEncodedTypeSourceInfo());
2130}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002132 EnqueueChildren(M);
2133 AddTypeLoc(M->getClassReceiverTypeInfo());
2134}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002136 // Visit the components of the offsetof expression.
2137 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2138 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2139 const OffsetOfNode &Node = E->getComponent(I-1);
2140 switch (Node.getKind()) {
2141 case OffsetOfNode::Array:
2142 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2143 break;
2144 case OffsetOfNode::Field:
2145 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2146 break;
2147 case OffsetOfNode::Identifier:
2148 case OffsetOfNode::Base:
2149 continue;
2150 }
2151 }
2152 // Visit the type into which we're computing the offset.
2153 AddTypeLoc(E->getTypeSourceInfo());
2154}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002156 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2157 WL.push_back(OverloadExprParts(E, Parent));
2158}
2159void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002160 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002161 EnqueueChildren(E);
2162 if (E->isArgumentType())
2163 AddTypeLoc(E->getArgumentTypeInfo());
2164}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002166 EnqueueChildren(S);
2167}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002169 AddStmt(S->getBody());
2170 AddStmt(S->getCond());
2171 AddDecl(S->getConditionVariable());
2172}
2173
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002175 AddStmt(W->getBody());
2176 AddStmt(W->getCond());
2177 AddDecl(W->getConditionVariable());
2178}
2179
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002181 AddTypeLoc(E->getQueriedTypeSourceInfo());
2182}
2183
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002185 AddTypeLoc(E->getRhsTypeSourceInfo());
2186 AddTypeLoc(E->getLhsTypeSourceInfo());
2187}
2188
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002190 for (unsigned I = E->getNumArgs(); I > 0; --I)
2191 AddTypeLoc(E->getArg(I-1));
2192}
2193
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002195 AddTypeLoc(E->getQueriedTypeSourceInfo());
2196}
2197
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002199 EnqueueChildren(E);
2200}
2201
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002203 VisitOverloadExpr(U);
2204 if (!U->isImplicitAccess())
2205 AddStmt(U->getBase());
2206}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002208 AddStmt(E->getSubExpr());
2209 AddTypeLoc(E->getWrittenTypeInfo());
2210}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002212 WL.push_back(SizeOfPackExprParts(E, Parent));
2213}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002215 // If the opaque value has a source expression, just transparently
2216 // visit that. This is useful for (e.g.) pseudo-object expressions.
2217 if (Expr *SourceExpr = E->getSourceExpr())
2218 return Visit(SourceExpr);
2219}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002221 AddStmt(E->getBody());
2222 WL.push_back(LambdaExprParts(E, Parent));
2223}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002225 // Treat the expression like its syntactic form.
2226 Visit(E->getSyntacticForm());
2227}
2228
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002229void EnqueueVisitor::VisitOMPExecutableDirective(
2230 const OMPExecutableDirective *D) {
2231 EnqueueChildren(D);
2232 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2233 E = D->clauses().end();
2234 I != E; ++I)
2235 EnqueueChildren(*I);
2236}
2237
2238void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2239 VisitOMPExecutableDirective(D);
2240}
2241
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002242void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002243 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2244}
2245
2246bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2247 if (RegionOfInterest.isValid()) {
2248 SourceRange Range = getRawCursorExtent(C);
2249 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2250 return false;
2251 }
2252 return true;
2253}
2254
2255bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2256 while (!WL.empty()) {
2257 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002258 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002259
2260 // Set the Parent field, then back to its old value once we're done.
2261 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2262
2263 switch (LI.getKind()) {
2264 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002265 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002266 if (!D)
2267 continue;
2268
2269 // For now, perform default visitation for Decls.
2270 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2271 cast<DeclVisit>(&LI)->isFirst())))
2272 return true;
2273
2274 continue;
2275 }
2276 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2277 const ASTTemplateArgumentListInfo *ArgList =
2278 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2279 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2280 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2281 Arg != ArgEnd; ++Arg) {
2282 if (VisitTemplateArgumentLoc(*Arg))
2283 return true;
2284 }
2285 continue;
2286 }
2287 case VisitorJob::TypeLocVisitKind: {
2288 // Perform default visitation for TypeLocs.
2289 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2290 return true;
2291 continue;
2292 }
2293 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002294 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002295 if (LabelStmt *stmt = LS->getStmt()) {
2296 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2297 TU))) {
2298 return true;
2299 }
2300 }
2301 continue;
2302 }
2303
2304 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2305 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2306 if (VisitNestedNameSpecifierLoc(V->get()))
2307 return true;
2308 continue;
2309 }
2310
2311 case VisitorJob::DeclarationNameInfoVisitKind: {
2312 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2313 ->get()))
2314 return true;
2315 continue;
2316 }
2317 case VisitorJob::MemberRefVisitKind: {
2318 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2319 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2320 return true;
2321 continue;
2322 }
2323 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002324 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002325 if (!S)
2326 continue;
2327
2328 // Update the current cursor.
2329 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2330 if (!IsInRegionOfInterest(Cursor))
2331 continue;
2332 switch (Visitor(Cursor, Parent, ClientData)) {
2333 case CXChildVisit_Break: return true;
2334 case CXChildVisit_Continue: break;
2335 case CXChildVisit_Recurse:
2336 if (PostChildrenVisitor)
2337 WL.push_back(PostChildrenVisit(0, Cursor));
2338 EnqueueWorkList(WL, S);
2339 break;
2340 }
2341 continue;
2342 }
2343 case VisitorJob::MemberExprPartsKind: {
2344 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002345 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002346
2347 // Visit the nested-name-specifier
2348 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2349 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2350 return true;
2351
2352 // Visit the declaration name.
2353 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2354 return true;
2355
2356 // Visit the explicitly-specified template arguments, if any.
2357 if (M->hasExplicitTemplateArgs()) {
2358 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2359 *ArgEnd = Arg + M->getNumTemplateArgs();
2360 Arg != ArgEnd; ++Arg) {
2361 if (VisitTemplateArgumentLoc(*Arg))
2362 return true;
2363 }
2364 }
2365 continue;
2366 }
2367 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002368 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002369 // Visit nested-name-specifier, if present.
2370 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2371 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2372 return true;
2373 // Visit declaration name.
2374 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2375 return true;
2376 continue;
2377 }
2378 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002379 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002380 // Visit the nested-name-specifier.
2381 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2382 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2383 return true;
2384 // Visit the declaration name.
2385 if (VisitDeclarationNameInfo(O->getNameInfo()))
2386 return true;
2387 // Visit the overloaded declaration reference.
2388 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2389 return true;
2390 continue;
2391 }
2392 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002393 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002394 NamedDecl *Pack = E->getPack();
2395 if (isa<TemplateTypeParmDecl>(Pack)) {
2396 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2397 E->getPackLoc(), TU)))
2398 return true;
2399
2400 continue;
2401 }
2402
2403 if (isa<TemplateTemplateParmDecl>(Pack)) {
2404 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2405 E->getPackLoc(), TU)))
2406 return true;
2407
2408 continue;
2409 }
2410
2411 // Non-type template parameter packs and function parameter packs are
2412 // treated like DeclRefExpr cursors.
2413 continue;
2414 }
2415
2416 case VisitorJob::LambdaExprPartsKind: {
2417 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002418 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002419 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2420 CEnd = E->explicit_capture_end();
2421 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002422 // FIXME: Lambda init-captures.
2423 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002424 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002425
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002426 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2427 C->getLocation(),
2428 TU)))
2429 return true;
2430 }
2431
2432 // Visit parameters and return type, if present.
2433 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2434 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2435 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2436 // Visit the whole type.
2437 if (Visit(TL))
2438 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002439 } else if (FunctionProtoTypeLoc Proto =
2440 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002441 if (E->hasExplicitParameters()) {
2442 // Visit parameters.
2443 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2444 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2445 return true;
2446 } else {
2447 // Visit result type.
2448 if (Visit(Proto.getResultLoc()))
2449 return true;
2450 }
2451 }
2452 }
2453 break;
2454 }
2455
2456 case VisitorJob::PostChildrenVisitKind:
2457 if (PostChildrenVisitor(Parent, ClientData))
2458 return true;
2459 break;
2460 }
2461 }
2462 return false;
2463}
2464
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002465bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002466 VisitorWorkList *WL = 0;
2467 if (!WorkListFreeList.empty()) {
2468 WL = WorkListFreeList.back();
2469 WL->clear();
2470 WorkListFreeList.pop_back();
2471 }
2472 else {
2473 WL = new VisitorWorkList();
2474 WorkListCache.push_back(WL);
2475 }
2476 EnqueueWorkList(*WL, S);
2477 bool result = RunVisitorWorkList(*WL);
2478 WorkListFreeList.push_back(WL);
2479 return result;
2480}
2481
2482namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002483typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002484RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2485 const DeclarationNameInfo &NI,
2486 const SourceRange &QLoc,
2487 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2488 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2489 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2490 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2491
2492 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2493
2494 RefNamePieces Pieces;
2495
2496 if (WantQualifier && QLoc.isValid())
2497 Pieces.push_back(QLoc);
2498
2499 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2500 Pieces.push_back(NI.getLoc());
2501
2502 if (WantTemplateArgs && TemplateArgs)
2503 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2504 TemplateArgs->RAngleLoc));
2505
2506 if (Kind == DeclarationName::CXXOperatorName) {
2507 Pieces.push_back(SourceLocation::getFromRawEncoding(
2508 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2509 Pieces.push_back(SourceLocation::getFromRawEncoding(
2510 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2511 }
2512
2513 if (WantSinglePiece) {
2514 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2515 Pieces.clear();
2516 Pieces.push_back(R);
2517 }
2518
2519 return Pieces;
2520}
2521}
2522
2523//===----------------------------------------------------------------------===//
2524// Misc. API hooks.
2525//===----------------------------------------------------------------------===//
2526
2527static llvm::sys::Mutex EnableMultithreadingMutex;
2528static bool EnabledMultithreading;
2529
Chad Rosier90836282013-03-27 18:28:23 +00002530static void fatal_error_handler(void *user_data, const std::string& reason,
2531 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002532 // Write the result out to stderr avoiding errs() because raw_ostreams can
2533 // call report_fatal_error.
2534 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2535 ::abort();
2536}
2537
2538extern "C" {
2539CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2540 int displayDiagnostics) {
2541 // Disable pretty stack trace functionality, which will otherwise be a very
2542 // poor citizen of the world and set up all sorts of signal handlers.
2543 llvm::DisablePrettyStackTrace = true;
2544
2545 // 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 Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002600 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002601 return 0;
2602
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002603 LOG_FUNC_SECTION {
2604 *Log << ast_filename;
2605 }
2606
Guy Benyei7f92f2d2012-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 Silvad47afb92013-01-20 01:58:28 +00002682 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-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 Kyrtzidisc6f5c6a2013-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 Benyei7f92f2d2012-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 Gribenko8c718e72013-01-26 21:49:50 +00002841 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002842 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2843 setThreadBackgroundPriority();
2844
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002845 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-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 Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002851 LOG_FUNC_SECTION {
2852 *Log << TU << ' ' << FileName;
2853 }
2854
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002855 if (!TU)
2856 return CXSaveError_InvalidTU;
2857
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002858 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-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 Gribenko5694feb2013-01-26 18:53:38 +00002899 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002900 return;
2901
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002902 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002903 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002904 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2905 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002906 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-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 Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002927 if (!TU)
2928 return;
Guy Benyei7f92f2d2012-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 Gribenko8c718e72013-01-26 21:49:50 +00002940 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002941 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2942 setThreadBackgroundPriority();
2943
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002944 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-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 Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << TU;
2973 }
2974
Guy Benyei7f92f2d2012-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 Gribenko5694feb2013-01-26 18:53:38 +00002987 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-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 Gribenkodc66adb2013-02-01 14:21:22 +00002998 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002999
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003000 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003001 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003002}
3003
3004CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003005 if (!TU)
3006 return clang_getNullCursor();
3007
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-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 Gribenkodad4c1a2013-02-01 14:13:32 +00003021 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003022
3023 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003024 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-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 Gribenko5694feb2013-01-26 18:53:38 +00003035CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3036 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003037 return 0;
3038
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003039 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003040
3041 FileManager &FMgr = CXXUnit->getFileManager();
3042 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3043}
3044
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003045unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3046 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003047 return 0;
3048
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003049 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003050 FileEntry *FEnt = static_cast<FileEntry *>(file);
3051 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3052 .isFileMultipleIncludeGuarded(FEnt);
3053}
3054
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003055int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3056 if (!file || !outID)
3057 return 1;
3058
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003059 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-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 Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003063 outID->data[2] = FEnt->getModificationTime();
3064 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003065}
3066
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003067} // end: extern "C"
3068
3069//===----------------------------------------------------------------------===//
3070// CXCursor Operations.
3071//===----------------------------------------------------------------------===//
3072
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003073static const Decl *getDeclFromExpr(const Stmt *E) {
3074 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003075 return getDeclFromExpr(CE->getSubExpr());
3076
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003077 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003078 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003079 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003080 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003081 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003082 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003083 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-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 Gribenkoe22339c2013-01-23 17:25:27 +00003094 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003095 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003096 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003097 if (Expr *Src = OVE->getSourceExpr())
3098 return getDeclFromExpr(Src);
3099
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003100 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003101 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003102 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003103 if (!CE->isElidable())
3104 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003105 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003106 return OME->getMethodDecl();
3107
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003108 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003109 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003110 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003111 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3112 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003113 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-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 Gribenkoff74f962013-01-26 15:29:08 +00003121static SourceLocation getLocationFromExpr(const Expr *E) {
3122 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003123 return getLocationFromExpr(CE->getSubExpr());
3124
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003125 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003126 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003127 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003128 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003129 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003130 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003131 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003132 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003133 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003134 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003135 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-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 Gribenkoe22339c2013-01-23 17:25:27 +00003188static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003189 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003190 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003191
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003192 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003193 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003194 if (const ObjCPropertyImplDecl *PropImpl =
3195 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003196 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003197 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003198
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003199 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003200 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003201 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003202
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003203 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003204 }
3205
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003206 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003207 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003208
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003209 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-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 Gribenko0c4394c2013-02-02 00:02:12 +00003213 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003214
3215 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003216 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003217
3218 SmallString<1024> S;
3219 llvm::raw_svector_ostream os(S);
3220 ND->printName(os);
3221
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003222 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003223}
3224
3225CXString clang_getCursorSpelling(CXCursor C) {
3226 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003227 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003228
3229 if (clang_isReference(C.kind)) {
3230 switch (C.kind) {
3231 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003232 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003233 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003234 }
3235 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003236 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003237 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003238 }
3239 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003240 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003241 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003242 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003243 }
3244 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003245 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003246 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003247 }
3248 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003249 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003250 assert(Type && "Missing type decl");
3251
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003252 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003253 getAsString());
3254 }
3255 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003256 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003257 assert(Template && "Missing template decl");
3258
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003259 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003260 }
3261
3262 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003263 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003264 assert(NS && "Missing namespace decl");
3265
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003266 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003267 }
3268
3269 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003270 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003271 assert(Field && "Missing member decl");
3272
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003273 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003274 }
3275
3276 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003277 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003278 assert(Label && "Missing label");
3279
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003280 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003281 }
3282
3283 case CXCursor_OverloadedDeclRef: {
3284 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-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 Gribenko5595ded2013-02-02 02:19:29 +00003287 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003288 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003289 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003290 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003291 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003292 OverloadedTemplateStorage *Ovl
3293 = Storage.get<OverloadedTemplateStorage*>();
3294 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003295 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003296 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003297 }
3298
3299 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003300 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003301 assert(Var && "Missing variable decl");
3302
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003303 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003304 }
3305
3306 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003307 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003308 }
3309 }
3310
3311 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003312 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003313 if (D)
3314 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003315 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003316 }
3317
3318 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003319 const Stmt *S = getCursorStmt(C);
3320 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003321 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003322
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003323 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003324 }
3325
3326 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003327 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003328 ->getNameStart());
3329
3330 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003331 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003332 ->getNameStart());
3333
3334 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003335 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-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 Gribenko7d914382013-01-26 18:08:08 +00003341 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003342 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003343 }
3344
3345 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003346 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003347 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003348 }
3349
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003350 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003351}
3352
3353CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3354 unsigned pieceIndex,
3355 unsigned options) {
3356 if (clang_Cursor_isNull(C))
3357 return clang_getNullRange();
3358
3359 ASTContext &Ctx = getCursorContext(C);
3360
3361 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003362 const Stmt *S = getCursorStmt(C);
3363 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003364 if (pieceIndex > 0)
3365 return clang_getNullRange();
3366 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3367 }
3368
3369 return clang_getNullRange();
3370 }
3371
3372 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003373 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003374 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3375 if (pieceIndex >= ME->getNumSelectorLocs())
3376 return clang_getNullRange();
3377 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3378 }
3379 }
3380
3381 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3382 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003383 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003384 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3385 if (pieceIndex >= MD->getNumSelectorLocs())
3386 return clang_getNullRange();
3387 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3388 }
3389 }
3390
3391 if (C.kind == CXCursor_ObjCCategoryDecl ||
3392 C.kind == CXCursor_ObjCCategoryImplDecl) {
3393 if (pieceIndex > 0)
3394 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003395 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003396 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3397 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003398 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003399 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3400 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3401 }
3402
3403 if (C.kind == CXCursor_ModuleImportDecl) {
3404 if (pieceIndex > 0)
3405 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003406 if (const ImportDecl *ImportD =
3407 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003408 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3409 if (!Locs.empty())
3410 return cxloc::translateSourceRange(Ctx,
3411 SourceRange(Locs.front(), Locs.back()));
3412 }
3413 return clang_getNullRange();
3414 }
3415
3416 // FIXME: A CXCursor_InclusionDirective should give the location of the
3417 // filename, but we don't keep track of this.
3418
3419 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3420 // but we don't keep track of this.
3421
3422 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3423 // but we don't keep track of this.
3424
3425 // Default handling, give the location of the cursor.
3426
3427 if (pieceIndex > 0)
3428 return clang_getNullRange();
3429
3430 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3431 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3432 return cxloc::translateSourceRange(Ctx, Loc);
3433}
3434
3435CXString clang_getCursorDisplayName(CXCursor C) {
3436 if (!clang_isDeclaration(C.kind))
3437 return clang_getCursorSpelling(C);
3438
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003439 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003440 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003441 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003442
3443 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003444 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003445 D = FunTmpl->getTemplatedDecl();
3446
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003447 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003448 SmallString<64> Str;
3449 llvm::raw_svector_ostream OS(Str);
3450 OS << *Function;
3451 if (Function->getPrimaryTemplate())
3452 OS << "<>";
3453 OS << "(";
3454 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3455 if (I)
3456 OS << ", ";
3457 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3458 }
3459
3460 if (Function->isVariadic()) {
3461 if (Function->getNumParams())
3462 OS << ", ";
3463 OS << "...";
3464 }
3465 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003466 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003467 }
3468
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003469 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003470 SmallString<64> Str;
3471 llvm::raw_svector_ostream OS(Str);
3472 OS << *ClassTemplate;
3473 OS << "<";
3474 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3475 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3476 if (I)
3477 OS << ", ";
3478
3479 NamedDecl *Param = Params->getParam(I);
3480 if (Param->getIdentifier()) {
3481 OS << Param->getIdentifier()->getName();
3482 continue;
3483 }
3484
3485 // There is no parameter name, which makes this tricky. Try to come up
3486 // with something useful that isn't too long.
3487 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3488 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3489 else if (NonTypeTemplateParmDecl *NTTP
3490 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3491 OS << NTTP->getType().getAsString(Policy);
3492 else
3493 OS << "template<...> class";
3494 }
3495
3496 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003497 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003498 }
3499
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003500 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3502 // If the type was explicitly written, use that.
3503 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003504 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505
Benjamin Kramer5eada842013-02-22 15:46:01 +00003506 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 llvm::raw_svector_ostream OS(Str);
3508 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003509 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510 ClassSpec->getTemplateArgs().data(),
3511 ClassSpec->getTemplateArgs().size(),
3512 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003513 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003514 }
3515
3516 return clang_getCursorSpelling(C);
3517}
3518
3519CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3520 switch (Kind) {
3521 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003649 case CXCursor_ObjCSelfExpr:
3650 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003742 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003743 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003744 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003745 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003746 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003747 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003748 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003749 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003750 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003751 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003752 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003753 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003754 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003755 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003756 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003757 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003758 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003759 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003760 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003761 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003762 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003763 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003764 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003765 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003766 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003767 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003768 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003769 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003770 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003771 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003772 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003773 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003774 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003775 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003776 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003777 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003778 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003779 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003780 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003781 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003783 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003785 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003787 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003788 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003789 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003790 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003791 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003792 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003793 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003794 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003795 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003796 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003797 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003798 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003799 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003800 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003801 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003802 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003803 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003804 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003805 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003806 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003807 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003809 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003811 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003812 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003813 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003814 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003815 case CXCursor_OMPParallelDirective:
3816 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003817 }
3818
3819 llvm_unreachable("Unhandled CXCursorKind");
3820}
3821
3822struct GetCursorData {
3823 SourceLocation TokenBeginLoc;
3824 bool PointsAtMacroArgExpansion;
3825 bool VisitedObjCPropertyImplDecl;
3826 SourceLocation VisitedDeclaratorDeclStartLoc;
3827 CXCursor &BestCursor;
3828
3829 GetCursorData(SourceManager &SM,
3830 SourceLocation tokenBegin, CXCursor &outputCursor)
3831 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3832 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3833 VisitedObjCPropertyImplDecl = false;
3834 }
3835};
3836
3837static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3838 CXCursor parent,
3839 CXClientData client_data) {
3840 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3841 CXCursor *BestCursor = &Data->BestCursor;
3842
3843 // If we point inside a macro argument we should provide info of what the
3844 // token is so use the actual cursor, don't replace it with a macro expansion
3845 // cursor.
3846 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3847 return CXChildVisit_Recurse;
3848
3849 if (clang_isDeclaration(cursor.kind)) {
3850 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003851 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003852 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3853 if (MD->isImplicit())
3854 return CXChildVisit_Break;
3855
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003856 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003857 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3858 // Check that when we have multiple @class references in the same line,
3859 // that later ones do not override the previous ones.
3860 // If we have:
3861 // @class Foo, Bar;
3862 // source ranges for both start at '@', so 'Bar' will end up overriding
3863 // 'Foo' even though the cursor location was at 'Foo'.
3864 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3865 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003866 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003867 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3868 if (PrevID != ID &&
3869 !PrevID->isThisDeclarationADefinition() &&
3870 !ID->isThisDeclarationADefinition())
3871 return CXChildVisit_Break;
3872 }
3873
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003874 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003875 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3876 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3877 // Check that when we have multiple declarators in the same line,
3878 // that later ones do not override the previous ones.
3879 // If we have:
3880 // int Foo, Bar;
3881 // source ranges for both start at 'int', so 'Bar' will end up overriding
3882 // 'Foo' even though the cursor location was at 'Foo'.
3883 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3884 return CXChildVisit_Break;
3885 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3886
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003887 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003888 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3889 (void)PropImp;
3890 // Check that when we have multiple @synthesize in the same line,
3891 // that later ones do not override the previous ones.
3892 // If we have:
3893 // @synthesize Foo, Bar;
3894 // source ranges for both start at '@', so 'Bar' will end up overriding
3895 // 'Foo' even though the cursor location was at 'Foo'.
3896 if (Data->VisitedObjCPropertyImplDecl)
3897 return CXChildVisit_Break;
3898 Data->VisitedObjCPropertyImplDecl = true;
3899 }
3900 }
3901
3902 if (clang_isExpression(cursor.kind) &&
3903 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003904 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003905 // Avoid having the cursor of an expression replace the declaration cursor
3906 // when the expression source range overlaps the declaration range.
3907 // This can happen for C++ constructor expressions whose range generally
3908 // include the variable declaration, e.g.:
3909 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3910 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3911 D->getLocation() == Data->TokenBeginLoc)
3912 return CXChildVisit_Break;
3913 }
3914 }
3915
3916 // If our current best cursor is the construction of a temporary object,
3917 // don't replace that cursor with a type reference, because we want
3918 // clang_getCursor() to point at the constructor.
3919 if (clang_isExpression(BestCursor->kind) &&
3920 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3921 cursor.kind == CXCursor_TypeRef) {
3922 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3923 // as having the actual point on the type reference.
3924 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3925 return CXChildVisit_Recurse;
3926 }
3927
3928 *BestCursor = cursor;
3929 return CXChildVisit_Recurse;
3930}
3931
3932CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3933 if (!TU)
3934 return clang_getNullCursor();
3935
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003936 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003937 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3938
3939 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3940 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3941
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003942 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003943 CXFile SearchFile;
3944 unsigned SearchLine, SearchColumn;
3945 CXFile ResultFile;
3946 unsigned ResultLine, ResultColumn;
3947 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3948 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3949 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3950
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003951 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3952 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003953 &ResultColumn, 0);
3954 SearchFileName = clang_getFileName(SearchFile);
3955 ResultFileName = clang_getFileName(ResultFile);
3956 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3957 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003958 *Log << llvm::format("(%s:%d:%d) = %s",
3959 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3960 clang_getCString(KindSpelling))
3961 << llvm::format("(%s:%d:%d):%s%s",
3962 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3963 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003964 clang_disposeString(SearchFileName);
3965 clang_disposeString(ResultFileName);
3966 clang_disposeString(KindSpelling);
3967 clang_disposeString(USR);
3968
3969 CXCursor Definition = clang_getCursorDefinition(Result);
3970 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3971 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3972 CXString DefinitionKindSpelling
3973 = clang_getCursorKindSpelling(Definition.kind);
3974 CXFile DefinitionFile;
3975 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003976 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003977 &DefinitionLine, &DefinitionColumn, 0);
3978 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003979 *Log << llvm::format(" -> %s(%s:%d:%d)",
3980 clang_getCString(DefinitionKindSpelling),
3981 clang_getCString(DefinitionFileName),
3982 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003983 clang_disposeString(DefinitionFileName);
3984 clang_disposeString(DefinitionKindSpelling);
3985 }
3986 }
3987
3988 return Result;
3989}
3990
3991CXCursor clang_getNullCursor(void) {
3992 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3993}
3994
3995unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003996 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3997 // can't set consistently. For example, when visiting a DeclStmt we will set
3998 // it but we don't set it on the result of clang_getCursorDefinition for
3999 // a reference of the same declaration.
4000 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4001 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4002 // to provide that kind of info.
4003 if (clang_isDeclaration(X.kind))
4004 X.data[1] = 0;
4005 if (clang_isDeclaration(Y.kind))
4006 Y.data[1] = 0;
4007
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004008 return X == Y;
4009}
4010
4011unsigned clang_hashCursor(CXCursor C) {
4012 unsigned Index = 0;
4013 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4014 Index = 1;
4015
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004016 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004017 std::make_pair(C.kind, C.data[Index]));
4018}
4019
4020unsigned clang_isInvalid(enum CXCursorKind K) {
4021 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4022}
4023
4024unsigned clang_isDeclaration(enum CXCursorKind K) {
4025 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4026 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4027}
4028
4029unsigned clang_isReference(enum CXCursorKind K) {
4030 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4031}
4032
4033unsigned clang_isExpression(enum CXCursorKind K) {
4034 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4035}
4036
4037unsigned clang_isStatement(enum CXCursorKind K) {
4038 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4039}
4040
4041unsigned clang_isAttribute(enum CXCursorKind K) {
4042 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4043}
4044
4045unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4046 return K == CXCursor_TranslationUnit;
4047}
4048
4049unsigned clang_isPreprocessing(enum CXCursorKind K) {
4050 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4051}
4052
4053unsigned clang_isUnexposed(enum CXCursorKind K) {
4054 switch (K) {
4055 case CXCursor_UnexposedDecl:
4056 case CXCursor_UnexposedExpr:
4057 case CXCursor_UnexposedStmt:
4058 case CXCursor_UnexposedAttr:
4059 return true;
4060 default:
4061 return false;
4062 }
4063}
4064
4065CXCursorKind clang_getCursorKind(CXCursor C) {
4066 return C.kind;
4067}
4068
4069CXSourceLocation clang_getCursorLocation(CXCursor C) {
4070 if (clang_isReference(C.kind)) {
4071 switch (C.kind) {
4072 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004073 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004074 = getCursorObjCSuperClassRef(C);
4075 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4076 }
4077
4078 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004079 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004080 = getCursorObjCProtocolRef(C);
4081 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4082 }
4083
4084 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004085 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004086 = getCursorObjCClassRef(C);
4087 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4088 }
4089
4090 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004091 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004092 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4093 }
4094
4095 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004096 std::pair<const TemplateDecl *, SourceLocation> P =
4097 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004102 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004103 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4104 }
4105
4106 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004107 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004108 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4109 }
4110
4111 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004112 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004113 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4114 }
4115
4116 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004117 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004118 if (!BaseSpec)
4119 return clang_getNullLocation();
4120
4121 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4122 return cxloc::translateSourceLocation(getCursorContext(C),
4123 TSInfo->getTypeLoc().getBeginLoc());
4124
4125 return cxloc::translateSourceLocation(getCursorContext(C),
4126 BaseSpec->getLocStart());
4127 }
4128
4129 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004130 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004131 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4132 }
4133
4134 case CXCursor_OverloadedDeclRef:
4135 return cxloc::translateSourceLocation(getCursorContext(C),
4136 getCursorOverloadedDeclRef(C).second);
4137
4138 default:
4139 // FIXME: Need a way to enumerate all non-reference cases.
4140 llvm_unreachable("Missed a reference kind");
4141 }
4142 }
4143
4144 if (clang_isExpression(C.kind))
4145 return cxloc::translateSourceLocation(getCursorContext(C),
4146 getLocationFromExpr(getCursorExpr(C)));
4147
4148 if (clang_isStatement(C.kind))
4149 return cxloc::translateSourceLocation(getCursorContext(C),
4150 getCursorStmt(C)->getLocStart());
4151
4152 if (C.kind == CXCursor_PreprocessingDirective) {
4153 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4154 return cxloc::translateSourceLocation(getCursorContext(C), L);
4155 }
4156
4157 if (C.kind == CXCursor_MacroExpansion) {
4158 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004159 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004160 return cxloc::translateSourceLocation(getCursorContext(C), L);
4161 }
4162
4163 if (C.kind == CXCursor_MacroDefinition) {
4164 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4165 return cxloc::translateSourceLocation(getCursorContext(C), L);
4166 }
4167
4168 if (C.kind == CXCursor_InclusionDirective) {
4169 SourceLocation L
4170 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
4174 if (!clang_isDeclaration(C.kind))
4175 return clang_getNullLocation();
4176
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004177 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004178 if (!D)
4179 return clang_getNullLocation();
4180
4181 SourceLocation Loc = D->getLocation();
4182 // FIXME: Multiple variables declared in a single declaration
4183 // currently lack the information needed to correctly determine their
4184 // ranges when accounting for the type-specifier. We use context
4185 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4186 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004187 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004188 if (!cxcursor::isFirstInDeclGroup(C))
4189 Loc = VD->getLocation();
4190 }
4191
4192 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004193 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004194 Loc = MD->getSelectorStartLoc();
4195
4196 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4197}
4198
4199} // end extern "C"
4200
4201CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4202 assert(TU);
4203
4204 // Guard against an invalid SourceLocation, or we may assert in one
4205 // of the following calls.
4206 if (SLoc.isInvalid())
4207 return clang_getNullCursor();
4208
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004209 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004210
4211 // Translate the given source location to make it point at the beginning of
4212 // the token under the cursor.
4213 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4214 CXXUnit->getASTContext().getLangOpts());
4215
4216 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4217 if (SLoc.isValid()) {
4218 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4219 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4220 /*VisitPreprocessorLast=*/true,
4221 /*VisitIncludedEntities=*/false,
4222 SourceLocation(SLoc));
4223 CursorVis.visitFileRegion();
4224 }
4225
4226 return Result;
4227}
4228
4229static SourceRange getRawCursorExtent(CXCursor C) {
4230 if (clang_isReference(C.kind)) {
4231 switch (C.kind) {
4232 case CXCursor_ObjCSuperClassRef:
4233 return getCursorObjCSuperClassRef(C).second;
4234
4235 case CXCursor_ObjCProtocolRef:
4236 return getCursorObjCProtocolRef(C).second;
4237
4238 case CXCursor_ObjCClassRef:
4239 return getCursorObjCClassRef(C).second;
4240
4241 case CXCursor_TypeRef:
4242 return getCursorTypeRef(C).second;
4243
4244 case CXCursor_TemplateRef:
4245 return getCursorTemplateRef(C).second;
4246
4247 case CXCursor_NamespaceRef:
4248 return getCursorNamespaceRef(C).second;
4249
4250 case CXCursor_MemberRef:
4251 return getCursorMemberRef(C).second;
4252
4253 case CXCursor_CXXBaseSpecifier:
4254 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4255
4256 case CXCursor_LabelRef:
4257 return getCursorLabelRef(C).second;
4258
4259 case CXCursor_OverloadedDeclRef:
4260 return getCursorOverloadedDeclRef(C).second;
4261
4262 case CXCursor_VariableRef:
4263 return getCursorVariableRef(C).second;
4264
4265 default:
4266 // FIXME: Need a way to enumerate all non-reference cases.
4267 llvm_unreachable("Missed a reference kind");
4268 }
4269 }
4270
4271 if (clang_isExpression(C.kind))
4272 return getCursorExpr(C)->getSourceRange();
4273
4274 if (clang_isStatement(C.kind))
4275 return getCursorStmt(C)->getSourceRange();
4276
4277 if (clang_isAttribute(C.kind))
4278 return getCursorAttr(C)->getRange();
4279
4280 if (C.kind == CXCursor_PreprocessingDirective)
4281 return cxcursor::getCursorPreprocessingDirective(C);
4282
4283 if (C.kind == CXCursor_MacroExpansion) {
4284 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004285 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004286 return TU->mapRangeFromPreamble(Range);
4287 }
4288
4289 if (C.kind == CXCursor_MacroDefinition) {
4290 ASTUnit *TU = getCursorASTUnit(C);
4291 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4292 return TU->mapRangeFromPreamble(Range);
4293 }
4294
4295 if (C.kind == CXCursor_InclusionDirective) {
4296 ASTUnit *TU = getCursorASTUnit(C);
4297 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4298 return TU->mapRangeFromPreamble(Range);
4299 }
4300
4301 if (C.kind == CXCursor_TranslationUnit) {
4302 ASTUnit *TU = getCursorASTUnit(C);
4303 FileID MainID = TU->getSourceManager().getMainFileID();
4304 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4305 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4306 return SourceRange(Start, End);
4307 }
4308
4309 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004310 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004311 if (!D)
4312 return SourceRange();
4313
4314 SourceRange R = D->getSourceRange();
4315 // FIXME: Multiple variables declared in a single declaration
4316 // currently lack the information needed to correctly determine their
4317 // ranges when accounting for the type-specifier. We use context
4318 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4319 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004320 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004321 if (!cxcursor::isFirstInDeclGroup(C))
4322 R.setBegin(VD->getLocation());
4323 }
4324 return R;
4325 }
4326 return SourceRange();
4327}
4328
4329/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4330/// the decl-specifier-seq for declarations.
4331static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4332 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004333 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004334 if (!D)
4335 return SourceRange();
4336
4337 SourceRange R = D->getSourceRange();
4338
4339 // Adjust the start of the location for declarations preceded by
4340 // declaration specifiers.
4341 SourceLocation StartLoc;
4342 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4343 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4344 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004345 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004346 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4347 StartLoc = TI->getTypeLoc().getLocStart();
4348 }
4349
4350 if (StartLoc.isValid() && R.getBegin().isValid() &&
4351 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4352 R.setBegin(StartLoc);
4353
4354 // FIXME: Multiple variables declared in a single declaration
4355 // currently lack the information needed to correctly determine their
4356 // ranges when accounting for the type-specifier. We use context
4357 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4358 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004359 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004360 if (!cxcursor::isFirstInDeclGroup(C))
4361 R.setBegin(VD->getLocation());
4362 }
4363
4364 return R;
4365 }
4366
4367 return getRawCursorExtent(C);
4368}
4369
4370extern "C" {
4371
4372CXSourceRange clang_getCursorExtent(CXCursor C) {
4373 SourceRange R = getRawCursorExtent(C);
4374 if (R.isInvalid())
4375 return clang_getNullRange();
4376
4377 return cxloc::translateSourceRange(getCursorContext(C), R);
4378}
4379
4380CXCursor clang_getCursorReferenced(CXCursor C) {
4381 if (clang_isInvalid(C.kind))
4382 return clang_getNullCursor();
4383
4384 CXTranslationUnit tu = getCursorTU(C);
4385 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004386 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004387 if (!D)
4388 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004389 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004390 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004391 if (const ObjCPropertyImplDecl *PropImpl =
4392 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004393 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4394 return MakeCXCursor(Property, tu);
4395
4396 return C;
4397 }
4398
4399 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004400 const Expr *E = getCursorExpr(C);
4401 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004402 if (D) {
4403 CXCursor declCursor = MakeCXCursor(D, tu);
4404 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4405 declCursor);
4406 return declCursor;
4407 }
4408
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004409 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004410 return MakeCursorOverloadedDeclRef(Ovl, tu);
4411
4412 return clang_getNullCursor();
4413 }
4414
4415 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004416 const Stmt *S = getCursorStmt(C);
4417 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004418 if (LabelDecl *label = Goto->getLabel())
4419 if (LabelStmt *labelS = label->getStmt())
4420 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4421
4422 return clang_getNullCursor();
4423 }
4424
4425 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004426 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004427 return MakeMacroDefinitionCursor(Def, tu);
4428 }
4429
4430 if (!clang_isReference(C.kind))
4431 return clang_getNullCursor();
4432
4433 switch (C.kind) {
4434 case CXCursor_ObjCSuperClassRef:
4435 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4436
4437 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004438 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4439 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004440 return MakeCXCursor(Def, tu);
4441
4442 return MakeCXCursor(Prot, tu);
4443 }
4444
4445 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004446 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4447 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004448 return MakeCXCursor(Def, tu);
4449
4450 return MakeCXCursor(Class, tu);
4451 }
4452
4453 case CXCursor_TypeRef:
4454 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4455
4456 case CXCursor_TemplateRef:
4457 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4458
4459 case CXCursor_NamespaceRef:
4460 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4461
4462 case CXCursor_MemberRef:
4463 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4464
4465 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004466 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004467 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4468 tu ));
4469 }
4470
4471 case CXCursor_LabelRef:
4472 // FIXME: We end up faking the "parent" declaration here because we
4473 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004474 return MakeCXCursor(getCursorLabelRef(C).first,
4475 cxtu::getASTUnit(tu)->getASTContext()
4476 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004477 tu);
4478
4479 case CXCursor_OverloadedDeclRef:
4480 return C;
4481
4482 case CXCursor_VariableRef:
4483 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4484
4485 default:
4486 // We would prefer to enumerate all non-reference cursor kinds here.
4487 llvm_unreachable("Unhandled reference cursor kind");
4488 }
4489}
4490
4491CXCursor clang_getCursorDefinition(CXCursor C) {
4492 if (clang_isInvalid(C.kind))
4493 return clang_getNullCursor();
4494
4495 CXTranslationUnit TU = getCursorTU(C);
4496
4497 bool WasReference = false;
4498 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4499 C = clang_getCursorReferenced(C);
4500 WasReference = true;
4501 }
4502
4503 if (C.kind == CXCursor_MacroExpansion)
4504 return clang_getCursorReferenced(C);
4505
4506 if (!clang_isDeclaration(C.kind))
4507 return clang_getNullCursor();
4508
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004509 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004510 if (!D)
4511 return clang_getNullCursor();
4512
4513 switch (D->getKind()) {
4514 // Declaration kinds that don't really separate the notions of
4515 // declaration and definition.
4516 case Decl::Namespace:
4517 case Decl::Typedef:
4518 case Decl::TypeAlias:
4519 case Decl::TypeAliasTemplate:
4520 case Decl::TemplateTypeParm:
4521 case Decl::EnumConstant:
4522 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004523 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004524 case Decl::IndirectField:
4525 case Decl::ObjCIvar:
4526 case Decl::ObjCAtDefsField:
4527 case Decl::ImplicitParam:
4528 case Decl::ParmVar:
4529 case Decl::NonTypeTemplateParm:
4530 case Decl::TemplateTemplateParm:
4531 case Decl::ObjCCategoryImpl:
4532 case Decl::ObjCImplementation:
4533 case Decl::AccessSpec:
4534 case Decl::LinkageSpec:
4535 case Decl::ObjCPropertyImpl:
4536 case Decl::FileScopeAsm:
4537 case Decl::StaticAssert:
4538 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004539 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004540 case Decl::Label: // FIXME: Is this right??
4541 case Decl::ClassScopeFunctionSpecialization:
4542 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004543 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004544 return C;
4545
4546 // Declaration kinds that don't make any sense here, but are
4547 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004548 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004549 case Decl::TranslationUnit:
4550 break;
4551
4552 // Declaration kinds for which the definition is not resolvable.
4553 case Decl::UnresolvedUsingTypename:
4554 case Decl::UnresolvedUsingValue:
4555 break;
4556
4557 case Decl::UsingDirective:
4558 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4559 TU);
4560
4561 case Decl::NamespaceAlias:
4562 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4563
4564 case Decl::Enum:
4565 case Decl::Record:
4566 case Decl::CXXRecord:
4567 case Decl::ClassTemplateSpecialization:
4568 case Decl::ClassTemplatePartialSpecialization:
4569 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4570 return MakeCXCursor(Def, TU);
4571 return clang_getNullCursor();
4572
4573 case Decl::Function:
4574 case Decl::CXXMethod:
4575 case Decl::CXXConstructor:
4576 case Decl::CXXDestructor:
4577 case Decl::CXXConversion: {
4578 const FunctionDecl *Def = 0;
4579 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004580 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004581 return clang_getNullCursor();
4582 }
4583
Larisse Voufoef4579c2013-08-06 01:03:05 +00004584 case Decl::Var:
4585 case Decl::VarTemplateSpecialization:
4586 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004587 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004588 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004589 return MakeCXCursor(Def, TU);
4590 return clang_getNullCursor();
4591 }
4592
4593 case Decl::FunctionTemplate: {
4594 const FunctionDecl *Def = 0;
4595 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4596 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4597 return clang_getNullCursor();
4598 }
4599
4600 case Decl::ClassTemplate: {
4601 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4602 ->getDefinition())
4603 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4604 TU);
4605 return clang_getNullCursor();
4606 }
4607
Larisse Voufoef4579c2013-08-06 01:03:05 +00004608 case Decl::VarTemplate: {
4609 if (VarDecl *Def =
4610 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4611 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4612 return clang_getNullCursor();
4613 }
4614
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004615 case Decl::Using:
4616 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4617 D->getLocation(), TU);
4618
4619 case Decl::UsingShadow:
4620 return clang_getCursorDefinition(
4621 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4622 TU));
4623
4624 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004625 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004626 if (Method->isThisDeclarationADefinition())
4627 return C;
4628
4629 // Dig out the method definition in the associated
4630 // @implementation, if we have it.
4631 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004632 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004633 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4634 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4635 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4636 Method->isInstanceMethod()))
4637 if (Def->isThisDeclarationADefinition())
4638 return MakeCXCursor(Def, TU);
4639
4640 return clang_getNullCursor();
4641 }
4642
4643 case Decl::ObjCCategory:
4644 if (ObjCCategoryImplDecl *Impl
4645 = cast<ObjCCategoryDecl>(D)->getImplementation())
4646 return MakeCXCursor(Impl, TU);
4647 return clang_getNullCursor();
4648
4649 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004650 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004651 return MakeCXCursor(Def, TU);
4652 return clang_getNullCursor();
4653
4654 case Decl::ObjCInterface: {
4655 // There are two notions of a "definition" for an Objective-C
4656 // class: the interface and its implementation. When we resolved a
4657 // reference to an Objective-C class, produce the @interface as
4658 // the definition; when we were provided with the interface,
4659 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004660 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004661 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004662 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004663 return MakeCXCursor(Def, TU);
4664 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4665 return MakeCXCursor(Impl, TU);
4666 return clang_getNullCursor();
4667 }
4668
4669 case Decl::ObjCProperty:
4670 // FIXME: We don't really know where to find the
4671 // ObjCPropertyImplDecls that implement this property.
4672 return clang_getNullCursor();
4673
4674 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004675 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004676 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004677 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004678 return MakeCXCursor(Def, TU);
4679
4680 return clang_getNullCursor();
4681
4682 case Decl::Friend:
4683 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4684 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4685 return clang_getNullCursor();
4686
4687 case Decl::FriendTemplate:
4688 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4689 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4690 return clang_getNullCursor();
4691 }
4692
4693 return clang_getNullCursor();
4694}
4695
4696unsigned clang_isCursorDefinition(CXCursor C) {
4697 if (!clang_isDeclaration(C.kind))
4698 return 0;
4699
4700 return clang_getCursorDefinition(C) == C;
4701}
4702
4703CXCursor clang_getCanonicalCursor(CXCursor C) {
4704 if (!clang_isDeclaration(C.kind))
4705 return C;
4706
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004707 if (const Decl *D = getCursorDecl(C)) {
4708 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004709 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4710 return MakeCXCursor(CatD, getCursorTU(C));
4711
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004712 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4713 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004714 return MakeCXCursor(IFD, getCursorTU(C));
4715
4716 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4717 }
4718
4719 return C;
4720}
4721
4722int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4723 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4724}
4725
4726unsigned clang_getNumOverloadedDecls(CXCursor C) {
4727 if (C.kind != CXCursor_OverloadedDeclRef)
4728 return 0;
4729
4730 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004731 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004732 return E->getNumDecls();
4733
4734 if (OverloadedTemplateStorage *S
4735 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4736 return S->size();
4737
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004738 const Decl *D = Storage.get<const Decl *>();
4739 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004740 return Using->shadow_size();
4741
4742 return 0;
4743}
4744
4745CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4746 if (cursor.kind != CXCursor_OverloadedDeclRef)
4747 return clang_getNullCursor();
4748
4749 if (index >= clang_getNumOverloadedDecls(cursor))
4750 return clang_getNullCursor();
4751
4752 CXTranslationUnit TU = getCursorTU(cursor);
4753 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004754 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004755 return MakeCXCursor(E->decls_begin()[index], TU);
4756
4757 if (OverloadedTemplateStorage *S
4758 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4759 return MakeCXCursor(S->begin()[index], TU);
4760
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004761 const Decl *D = Storage.get<const Decl *>();
4762 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004763 // FIXME: This is, unfortunately, linear time.
4764 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4765 std::advance(Pos, index);
4766 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4767 }
4768
4769 return clang_getNullCursor();
4770}
4771
4772void clang_getDefinitionSpellingAndExtent(CXCursor C,
4773 const char **startBuf,
4774 const char **endBuf,
4775 unsigned *startLine,
4776 unsigned *startColumn,
4777 unsigned *endLine,
4778 unsigned *endColumn) {
4779 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004780 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004781 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4782
4783 SourceManager &SM = FD->getASTContext().getSourceManager();
4784 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4785 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4786 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4787 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4788 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4789 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4790}
4791
4792
4793CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4794 unsigned PieceIndex) {
4795 RefNamePieces Pieces;
4796
4797 switch (C.kind) {
4798 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004799 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004800 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4801 E->getQualifierLoc().getSourceRange());
4802 break;
4803
4804 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004805 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004806 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4807 E->getQualifierLoc().getSourceRange(),
4808 E->getOptionalExplicitTemplateArgs());
4809 break;
4810
4811 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004812 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004813 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004814 const Expr *Callee = OCE->getCallee();
4815 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004816 Callee = ICE->getSubExpr();
4817
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004818 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004819 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4820 DRE->getQualifierLoc().getSourceRange());
4821 }
4822 break;
4823
4824 default:
4825 break;
4826 }
4827
4828 if (Pieces.empty()) {
4829 if (PieceIndex == 0)
4830 return clang_getCursorExtent(C);
4831 } else if (PieceIndex < Pieces.size()) {
4832 SourceRange R = Pieces[PieceIndex];
4833 if (R.isValid())
4834 return cxloc::translateSourceRange(getCursorContext(C), R);
4835 }
4836
4837 return clang_getNullRange();
4838}
4839
4840void clang_enableStackTraces(void) {
4841 llvm::sys::PrintStackTraceOnErrorSignal();
4842}
4843
4844void clang_executeOnThread(void (*fn)(void*), void *user_data,
4845 unsigned stack_size) {
4846 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4847}
4848
4849} // end: extern "C"
4850
4851//===----------------------------------------------------------------------===//
4852// Token-based Operations.
4853//===----------------------------------------------------------------------===//
4854
4855/* CXToken layout:
4856 * int_data[0]: a CXTokenKind
4857 * int_data[1]: starting token location
4858 * int_data[2]: token length
4859 * int_data[3]: reserved
4860 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4861 * otherwise unused.
4862 */
4863extern "C" {
4864
4865CXTokenKind clang_getTokenKind(CXToken CXTok) {
4866 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4867}
4868
4869CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4870 switch (clang_getTokenKind(CXTok)) {
4871 case CXToken_Identifier:
4872 case CXToken_Keyword:
4873 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004874 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004875 ->getNameStart());
4876
4877 case CXToken_Literal: {
4878 // We have stashed the starting pointer in the ptr_data field. Use it.
4879 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004880 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004881 }
4882
4883 case CXToken_Punctuation:
4884 case CXToken_Comment:
4885 break;
4886 }
4887
4888 // We have to find the starting buffer pointer the hard way, by
4889 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004890 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004891 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004892 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004893
4894 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4895 std::pair<FileID, unsigned> LocInfo
4896 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4897 bool Invalid = false;
4898 StringRef Buffer
4899 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4900 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004901 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004902
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004903 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004904}
4905
4906CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004907 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004908 if (!CXXUnit)
4909 return clang_getNullLocation();
4910
4911 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4912 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4913}
4914
4915CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004916 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004917 if (!CXXUnit)
4918 return clang_getNullRange();
4919
4920 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4921 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4922}
4923
4924static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4925 SmallVectorImpl<CXToken> &CXTokens) {
4926 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4927 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004928 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004929 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004930 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004931
4932 // Cannot tokenize across files.
4933 if (BeginLocInfo.first != EndLocInfo.first)
4934 return;
4935
4936 // Create a lexer
4937 bool Invalid = false;
4938 StringRef Buffer
4939 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4940 if (Invalid)
4941 return;
4942
4943 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4944 CXXUnit->getASTContext().getLangOpts(),
4945 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4946 Lex.SetCommentRetentionState(true);
4947
4948 // Lex tokens until we hit the end of the range.
4949 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4950 Token Tok;
4951 bool previousWasAt = false;
4952 do {
4953 // Lex the next token
4954 Lex.LexFromRawLexer(Tok);
4955 if (Tok.is(tok::eof))
4956 break;
4957
4958 // Initialize the CXToken.
4959 CXToken CXTok;
4960
4961 // - Common fields
4962 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4963 CXTok.int_data[2] = Tok.getLength();
4964 CXTok.int_data[3] = 0;
4965
4966 // - Kind-specific fields
4967 if (Tok.isLiteral()) {
4968 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004969 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004970 } else if (Tok.is(tok::raw_identifier)) {
4971 // Lookup the identifier to determine whether we have a keyword.
4972 IdentifierInfo *II
4973 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4974
4975 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4976 CXTok.int_data[0] = CXToken_Keyword;
4977 }
4978 else {
4979 CXTok.int_data[0] = Tok.is(tok::identifier)
4980 ? CXToken_Identifier
4981 : CXToken_Keyword;
4982 }
4983 CXTok.ptr_data = II;
4984 } else if (Tok.is(tok::comment)) {
4985 CXTok.int_data[0] = CXToken_Comment;
4986 CXTok.ptr_data = 0;
4987 } else {
4988 CXTok.int_data[0] = CXToken_Punctuation;
4989 CXTok.ptr_data = 0;
4990 }
4991 CXTokens.push_back(CXTok);
4992 previousWasAt = Tok.is(tok::at);
4993 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4994}
4995
4996void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4997 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004998 LOG_FUNC_SECTION {
4999 *Log << TU << ' ' << Range;
5000 }
5001
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005002 if (Tokens)
5003 *Tokens = 0;
5004 if (NumTokens)
5005 *NumTokens = 0;
5006
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005007 if (!TU)
5008 return;
5009
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005010 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005011 if (!CXXUnit || !Tokens || !NumTokens)
5012 return;
5013
5014 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5015
5016 SourceRange R = cxloc::translateCXSourceRange(Range);
5017 if (R.isInvalid())
5018 return;
5019
5020 SmallVector<CXToken, 32> CXTokens;
5021 getTokens(CXXUnit, R, CXTokens);
5022
5023 if (CXTokens.empty())
5024 return;
5025
5026 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5027 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5028 *NumTokens = CXTokens.size();
5029}
5030
5031void clang_disposeTokens(CXTranslationUnit TU,
5032 CXToken *Tokens, unsigned NumTokens) {
5033 free(Tokens);
5034}
5035
5036} // end: extern "C"
5037
5038//===----------------------------------------------------------------------===//
5039// Token annotation APIs.
5040//===----------------------------------------------------------------------===//
5041
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005042static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5043 CXCursor parent,
5044 CXClientData client_data);
5045static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5046 CXClientData client_data);
5047
5048namespace {
5049class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005050 CXToken *Tokens;
5051 CXCursor *Cursors;
5052 unsigned NumTokens;
5053 unsigned TokIdx;
5054 unsigned PreprocessingTokIdx;
5055 CursorVisitor AnnotateVis;
5056 SourceManager &SrcMgr;
5057 bool HasContextSensitiveKeywords;
5058
5059 struct PostChildrenInfo {
5060 CXCursor Cursor;
5061 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005062 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005063 unsigned BeforeChildrenTokenIdx;
5064 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005065 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005066
5067 bool MoreTokens() const { return TokIdx < NumTokens; }
5068 unsigned NextToken() const { return TokIdx; }
5069 void AdvanceToken() { ++TokIdx; }
5070 SourceLocation GetTokenLoc(unsigned tokI) {
5071 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5072 }
5073 bool isFunctionMacroToken(unsigned tokI) const {
5074 return Tokens[tokI].int_data[3] != 0;
5075 }
5076 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5077 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5078 }
5079
5080 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005081 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005082 SourceRange);
5083
5084public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005085 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005086 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005087 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005088 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005089 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005090 AnnotateTokensVisitor, this,
5091 /*VisitPreprocessorLast=*/true,
5092 /*VisitIncludedEntities=*/false,
5093 RegionOfInterest,
5094 /*VisitDeclsOnly=*/false,
5095 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005096 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005097 HasContextSensitiveKeywords(false) { }
5098
5099 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5100 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5101 bool postVisitChildren(CXCursor cursor);
5102 void AnnotateTokens();
5103
5104 /// \brief Determine whether the annotator saw any cursors that have
5105 /// context-sensitive keywords.
5106 bool hasContextSensitiveKeywords() const {
5107 return HasContextSensitiveKeywords;
5108 }
5109
5110 ~AnnotateTokensWorker() {
5111 assert(PostChildrenInfos.empty());
5112 }
5113};
5114}
5115
5116void AnnotateTokensWorker::AnnotateTokens() {
5117 // Walk the AST within the region of interest, annotating tokens
5118 // along the way.
5119 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005120}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005121
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005122static inline void updateCursorAnnotation(CXCursor &Cursor,
5123 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005124 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005125 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005126 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005127}
5128
5129/// \brief It annotates and advances tokens with a cursor until the comparison
5130//// between the cursor location and the source range is the same as
5131/// \arg compResult.
5132///
5133/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5134/// Pass RangeOverlap to annotate tokens inside a range.
5135void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5136 RangeComparisonResult compResult,
5137 SourceRange range) {
5138 while (MoreTokens()) {
5139 const unsigned I = NextToken();
5140 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005141 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5142 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005143
5144 SourceLocation TokLoc = GetTokenLoc(I);
5145 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005146 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005147 AdvanceToken();
5148 continue;
5149 }
5150 break;
5151 }
5152}
5153
5154/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005155/// \returns true if it advanced beyond all macro tokens, false otherwise.
5156bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005157 CXCursor updateC,
5158 RangeComparisonResult compResult,
5159 SourceRange range) {
5160 assert(MoreTokens());
5161 assert(isFunctionMacroToken(NextToken()) &&
5162 "Should be called only for macro arg tokens");
5163
5164 // This works differently than annotateAndAdvanceTokens; because expanded
5165 // macro arguments can have arbitrary translation-unit source order, we do not
5166 // advance the token index one by one until a token fails the range test.
5167 // We only advance once past all of the macro arg tokens if all of them
5168 // pass the range test. If one of them fails we keep the token index pointing
5169 // at the start of the macro arg tokens so that the failing token will be
5170 // annotated by a subsequent annotation try.
5171
5172 bool atLeastOneCompFail = false;
5173
5174 unsigned I = NextToken();
5175 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5176 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5177 if (TokLoc.isFileID())
5178 continue; // not macro arg token, it's parens or comma.
5179 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5180 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5181 Cursors[I] = updateC;
5182 } else
5183 atLeastOneCompFail = true;
5184 }
5185
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005186 if (atLeastOneCompFail)
5187 return false;
5188
5189 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5190 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005191}
5192
5193enum CXChildVisitResult
5194AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005195 SourceRange cursorRange = getRawCursorExtent(cursor);
5196 if (cursorRange.isInvalid())
5197 return CXChildVisit_Recurse;
5198
5199 if (!HasContextSensitiveKeywords) {
5200 // Objective-C properties can have context-sensitive keywords.
5201 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005202 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005203 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5204 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5205 }
5206 // Objective-C methods can have context-sensitive keywords.
5207 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5208 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005209 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005210 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5211 if (Method->getObjCDeclQualifier())
5212 HasContextSensitiveKeywords = true;
5213 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005214 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5215 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005216 P != PEnd; ++P) {
5217 if ((*P)->getObjCDeclQualifier()) {
5218 HasContextSensitiveKeywords = true;
5219 break;
5220 }
5221 }
5222 }
5223 }
5224 }
5225 // C++ methods can have context-sensitive keywords.
5226 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005227 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005228 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5229 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5230 HasContextSensitiveKeywords = true;
5231 }
5232 }
5233 // C++ classes can have context-sensitive keywords.
5234 else if (cursor.kind == CXCursor_StructDecl ||
5235 cursor.kind == CXCursor_ClassDecl ||
5236 cursor.kind == CXCursor_ClassTemplate ||
5237 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005238 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005239 if (D->hasAttr<FinalAttr>())
5240 HasContextSensitiveKeywords = true;
5241 }
5242 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005243
5244 // Don't override a property annotation with its getter/setter method.
5245 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5246 parent.kind == CXCursor_ObjCPropertyDecl)
5247 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005248
5249 if (clang_isPreprocessing(cursor.kind)) {
5250 // Items in the preprocessing record are kept separate from items in
5251 // declarations, so we keep a separate token index.
5252 unsigned SavedTokIdx = TokIdx;
5253 TokIdx = PreprocessingTokIdx;
5254
5255 // Skip tokens up until we catch up to the beginning of the preprocessing
5256 // entry.
5257 while (MoreTokens()) {
5258 const unsigned I = NextToken();
5259 SourceLocation TokLoc = GetTokenLoc(I);
5260 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5261 case RangeBefore:
5262 AdvanceToken();
5263 continue;
5264 case RangeAfter:
5265 case RangeOverlap:
5266 break;
5267 }
5268 break;
5269 }
5270
5271 // Look at all of the tokens within this range.
5272 while (MoreTokens()) {
5273 const unsigned I = NextToken();
5274 SourceLocation TokLoc = GetTokenLoc(I);
5275 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5276 case RangeBefore:
5277 llvm_unreachable("Infeasible");
5278 case RangeAfter:
5279 break;
5280 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005281 // For macro expansions, just note where the beginning of the macro
5282 // expansion occurs.
5283 if (cursor.kind == CXCursor_MacroExpansion) {
5284 if (TokLoc == cursorRange.getBegin())
5285 Cursors[I] = cursor;
5286 AdvanceToken();
5287 break;
5288 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005289 // We may have already annotated macro names inside macro definitions.
5290 if (Cursors[I].kind != CXCursor_MacroExpansion)
5291 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005292 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005293 continue;
5294 }
5295 break;
5296 }
5297
5298 // Save the preprocessing token index; restore the non-preprocessing
5299 // token index.
5300 PreprocessingTokIdx = TokIdx;
5301 TokIdx = SavedTokIdx;
5302 return CXChildVisit_Recurse;
5303 }
5304
5305 if (cursorRange.isInvalid())
5306 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005307
5308 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005309 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005310 const enum CXCursorKind K = clang_getCursorKind(parent);
5311 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005312 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5313 // Attributes are annotated out-of-order, skip tokens until we reach it.
5314 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005315 ? clang_getNullCursor() : parent;
5316
5317 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5318
5319 // Avoid having the cursor of an expression "overwrite" the annotation of the
5320 // variable declaration that it belongs to.
5321 // This can happen for C++ constructor expressions whose range generally
5322 // include the variable declaration, e.g.:
5323 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5324 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005325 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005326 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005327 const unsigned I = NextToken();
5328 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5329 E->getLocStart() == D->getLocation() &&
5330 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005331 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005332 AdvanceToken();
5333 }
5334 }
5335 }
5336
5337 // Before recursing into the children keep some state that we are going
5338 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5339 // extra work after the child nodes are visited.
5340 // Note that we don't call VisitChildren here to avoid traversing statements
5341 // code-recursively which can blow the stack.
5342
5343 PostChildrenInfo Info;
5344 Info.Cursor = cursor;
5345 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005346 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005347 Info.BeforeChildrenTokenIdx = NextToken();
5348 PostChildrenInfos.push_back(Info);
5349
5350 return CXChildVisit_Recurse;
5351}
5352
5353bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5354 if (PostChildrenInfos.empty())
5355 return false;
5356 const PostChildrenInfo &Info = PostChildrenInfos.back();
5357 if (!clang_equalCursors(Info.Cursor, cursor))
5358 return false;
5359
5360 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5361 const unsigned AfterChildren = NextToken();
5362 SourceRange cursorRange = Info.CursorRange;
5363
5364 // Scan the tokens that are at the end of the cursor, but are not captured
5365 // but the child cursors.
5366 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5367
5368 // Scan the tokens that are at the beginning of the cursor, but are not
5369 // capture by the child cursors.
5370 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5371 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5372 break;
5373
5374 Cursors[I] = cursor;
5375 }
5376
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005377 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5378 // encountered the attribute cursor.
5379 if (clang_isAttribute(cursor.kind))
5380 TokIdx = Info.BeforeReachingCursorIdx;
5381
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005382 PostChildrenInfos.pop_back();
5383 return false;
5384}
5385
5386static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5387 CXCursor parent,
5388 CXClientData client_data) {
5389 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5390}
5391
5392static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5393 CXClientData client_data) {
5394 return static_cast<AnnotateTokensWorker*>(client_data)->
5395 postVisitChildren(cursor);
5396}
5397
5398namespace {
5399
5400/// \brief Uses the macro expansions in the preprocessing record to find
5401/// and mark tokens that are macro arguments. This info is used by the
5402/// AnnotateTokensWorker.
5403class MarkMacroArgTokensVisitor {
5404 SourceManager &SM;
5405 CXToken *Tokens;
5406 unsigned NumTokens;
5407 unsigned CurIdx;
5408
5409public:
5410 MarkMacroArgTokensVisitor(SourceManager &SM,
5411 CXToken *tokens, unsigned numTokens)
5412 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5413
5414 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5415 if (cursor.kind != CXCursor_MacroExpansion)
5416 return CXChildVisit_Continue;
5417
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005418 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005419 if (macroRange.getBegin() == macroRange.getEnd())
5420 return CXChildVisit_Continue; // it's not a function macro.
5421
5422 for (; CurIdx < NumTokens; ++CurIdx) {
5423 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5424 macroRange.getBegin()))
5425 break;
5426 }
5427
5428 if (CurIdx == NumTokens)
5429 return CXChildVisit_Break;
5430
5431 for (; CurIdx < NumTokens; ++CurIdx) {
5432 SourceLocation tokLoc = getTokenLoc(CurIdx);
5433 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5434 break;
5435
5436 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5437 }
5438
5439 if (CurIdx == NumTokens)
5440 return CXChildVisit_Break;
5441
5442 return CXChildVisit_Continue;
5443 }
5444
5445private:
5446 SourceLocation getTokenLoc(unsigned tokI) {
5447 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5448 }
5449
5450 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5451 // The third field is reserved and currently not used. Use it here
5452 // to mark macro arg expanded tokens with their expanded locations.
5453 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5454 }
5455};
5456
5457} // end anonymous namespace
5458
5459static CXChildVisitResult
5460MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5461 CXClientData client_data) {
5462 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5463 parent);
5464}
5465
5466namespace {
5467 struct clang_annotateTokens_Data {
5468 CXTranslationUnit TU;
5469 ASTUnit *CXXUnit;
5470 CXToken *Tokens;
5471 unsigned NumTokens;
5472 CXCursor *Cursors;
5473 };
5474}
5475
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005476/// \brief Used by \c annotatePreprocessorTokens.
5477/// \returns true if lexing was finished, false otherwise.
5478static bool lexNext(Lexer &Lex, Token &Tok,
5479 unsigned &NextIdx, unsigned NumTokens) {
5480 if (NextIdx >= NumTokens)
5481 return true;
5482
5483 ++NextIdx;
5484 Lex.LexFromRawLexer(Tok);
5485 if (Tok.is(tok::eof))
5486 return true;
5487
5488 return false;
5489}
5490
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005491static void annotatePreprocessorTokens(CXTranslationUnit TU,
5492 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005493 CXCursor *Cursors,
5494 CXToken *Tokens,
5495 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005496 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005497
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005498 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005499 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5500 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005501 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005502 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005503 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005504
5505 if (BeginLocInfo.first != EndLocInfo.first)
5506 return;
5507
5508 StringRef Buffer;
5509 bool Invalid = false;
5510 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5511 if (Buffer.empty() || Invalid)
5512 return;
5513
5514 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5515 CXXUnit->getASTContext().getLangOpts(),
5516 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5517 Buffer.end());
5518 Lex.SetCommentRetentionState(true);
5519
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005520 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005521 // Lex tokens in raw mode until we hit the end of the range, to avoid
5522 // entering #includes or expanding macros.
5523 while (true) {
5524 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005525 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5526 break;
5527 unsigned TokIdx = NextIdx-1;
5528 assert(Tok.getLocation() ==
5529 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005530
5531 reprocess:
5532 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005533 // We have found a preprocessing directive. Annotate the tokens
5534 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005535 //
5536 // FIXME: Some simple tests here could identify macro definitions and
5537 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005538
5539 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005540 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5541 break;
5542
5543 MacroInfo *MI = 0;
5544 if (Tok.is(tok::raw_identifier) &&
5545 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5546 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5547 break;
5548
5549 if (Tok.is(tok::raw_identifier)) {
5550 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5551 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5552 SourceLocation MappedTokLoc =
5553 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5554 MI = getMacroInfo(II, MappedTokLoc, TU);
5555 }
5556 }
5557
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005558 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005559 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005560 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5561 finished = true;
5562 break;
5563 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005564 // If we are in a macro definition, check if the token was ever a
5565 // macro name and annotate it if that's the case.
5566 if (MI) {
5567 SourceLocation SaveLoc = Tok.getLocation();
5568 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5569 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5570 Tok.setLocation(SaveLoc);
5571 if (MacroDef)
5572 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5573 Tok.getLocation(), TU);
5574 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005575 } while (!Tok.isAtStartOfLine());
5576
5577 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5578 assert(TokIdx <= LastIdx);
5579 SourceLocation EndLoc =
5580 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5581 CXCursor Cursor =
5582 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5583
5584 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005585 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005586
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005587 if (finished)
5588 break;
5589 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005590 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005591 }
5592}
5593
5594// This gets run a separate thread to avoid stack blowout.
5595static void clang_annotateTokensImpl(void *UserData) {
5596 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5597 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5598 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5599 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5600 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5601
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005602 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005603 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5604 setThreadBackgroundPriority();
5605
5606 // Determine the region of interest, which contains all of the tokens.
5607 SourceRange RegionOfInterest;
5608 RegionOfInterest.setBegin(
5609 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5610 RegionOfInterest.setEnd(
5611 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5612 Tokens[NumTokens-1])));
5613
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005614 // Relex the tokens within the source range to look for preprocessing
5615 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005616 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005617
5618 // If begin location points inside a macro argument, set it to the expansion
5619 // location so we can have the full context when annotating semantically.
5620 {
5621 SourceManager &SM = CXXUnit->getSourceManager();
5622 SourceLocation Loc =
5623 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5624 if (Loc.isMacroID())
5625 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5626 }
5627
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005628 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5629 // Search and mark tokens that are macro argument expansions.
5630 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5631 Tokens, NumTokens);
5632 CursorVisitor MacroArgMarker(TU,
5633 MarkMacroArgTokensVisitorDelegate, &Visitor,
5634 /*VisitPreprocessorLast=*/true,
5635 /*VisitIncludedEntities=*/false,
5636 RegionOfInterest);
5637 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5638 }
5639
5640 // Annotate all of the source locations in the region of interest that map to
5641 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005642 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005643
5644 // FIXME: We use a ridiculous stack size here because the data-recursion
5645 // algorithm uses a large stack frame than the non-data recursive version,
5646 // and AnnotationTokensWorker currently transforms the data-recursion
5647 // algorithm back into a traditional recursion by explicitly calling
5648 // VisitChildren(). We will need to remove this explicit recursive call.
5649 W.AnnotateTokens();
5650
5651 // If we ran into any entities that involve context-sensitive keywords,
5652 // take another pass through the tokens to mark them as such.
5653 if (W.hasContextSensitiveKeywords()) {
5654 for (unsigned I = 0; I != NumTokens; ++I) {
5655 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5656 continue;
5657
5658 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5659 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005660 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005661 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5662 if (Property->getPropertyAttributesAsWritten() != 0 &&
5663 llvm::StringSwitch<bool>(II->getName())
5664 .Case("readonly", true)
5665 .Case("assign", true)
5666 .Case("unsafe_unretained", true)
5667 .Case("readwrite", true)
5668 .Case("retain", true)
5669 .Case("copy", true)
5670 .Case("nonatomic", true)
5671 .Case("atomic", true)
5672 .Case("getter", true)
5673 .Case("setter", true)
5674 .Case("strong", true)
5675 .Case("weak", true)
5676 .Default(false))
5677 Tokens[I].int_data[0] = CXToken_Keyword;
5678 }
5679 continue;
5680 }
5681
5682 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5683 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5684 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5685 if (llvm::StringSwitch<bool>(II->getName())
5686 .Case("in", true)
5687 .Case("out", true)
5688 .Case("inout", true)
5689 .Case("oneway", true)
5690 .Case("bycopy", true)
5691 .Case("byref", true)
5692 .Default(false))
5693 Tokens[I].int_data[0] = CXToken_Keyword;
5694 continue;
5695 }
5696
5697 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5698 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5699 Tokens[I].int_data[0] = CXToken_Keyword;
5700 continue;
5701 }
5702 }
5703 }
5704}
5705
5706extern "C" {
5707
5708void clang_annotateTokens(CXTranslationUnit TU,
5709 CXToken *Tokens, unsigned NumTokens,
5710 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005711 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005712 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005713 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005714 }
5715
5716 LOG_FUNC_SECTION {
5717 *Log << TU << ' ';
5718 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5719 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5720 *Log << clang_getRange(bloc, eloc);
5721 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005722
5723 // Any token we don't specifically annotate will have a NULL cursor.
5724 CXCursor C = clang_getNullCursor();
5725 for (unsigned I = 0; I != NumTokens; ++I)
5726 Cursors[I] = C;
5727
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005728 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005729 if (!CXXUnit)
5730 return;
5731
5732 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5733
5734 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5735 llvm::CrashRecoveryContext CRC;
5736 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5737 GetSafetyThreadStackSize() * 2)) {
5738 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5739 }
5740}
5741
5742} // end: extern "C"
5743
5744//===----------------------------------------------------------------------===//
5745// Operations for querying linkage of a cursor.
5746//===----------------------------------------------------------------------===//
5747
5748extern "C" {
5749CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5750 if (!clang_isDeclaration(cursor.kind))
5751 return CXLinkage_Invalid;
5752
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005753 const Decl *D = cxcursor::getCursorDecl(cursor);
5754 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005755 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005756 case NoLinkage:
5757 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005758 case InternalLinkage: return CXLinkage_Internal;
5759 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5760 case ExternalLinkage: return CXLinkage_External;
5761 };
5762
5763 return CXLinkage_Invalid;
5764}
5765} // end: extern "C"
5766
5767//===----------------------------------------------------------------------===//
5768// Operations for querying language of a cursor.
5769//===----------------------------------------------------------------------===//
5770
5771static CXLanguageKind getDeclLanguage(const Decl *D) {
5772 if (!D)
5773 return CXLanguage_C;
5774
5775 switch (D->getKind()) {
5776 default:
5777 break;
5778 case Decl::ImplicitParam:
5779 case Decl::ObjCAtDefsField:
5780 case Decl::ObjCCategory:
5781 case Decl::ObjCCategoryImpl:
5782 case Decl::ObjCCompatibleAlias:
5783 case Decl::ObjCImplementation:
5784 case Decl::ObjCInterface:
5785 case Decl::ObjCIvar:
5786 case Decl::ObjCMethod:
5787 case Decl::ObjCProperty:
5788 case Decl::ObjCPropertyImpl:
5789 case Decl::ObjCProtocol:
5790 return CXLanguage_ObjC;
5791 case Decl::CXXConstructor:
5792 case Decl::CXXConversion:
5793 case Decl::CXXDestructor:
5794 case Decl::CXXMethod:
5795 case Decl::CXXRecord:
5796 case Decl::ClassTemplate:
5797 case Decl::ClassTemplatePartialSpecialization:
5798 case Decl::ClassTemplateSpecialization:
5799 case Decl::Friend:
5800 case Decl::FriendTemplate:
5801 case Decl::FunctionTemplate:
5802 case Decl::LinkageSpec:
5803 case Decl::Namespace:
5804 case Decl::NamespaceAlias:
5805 case Decl::NonTypeTemplateParm:
5806 case Decl::StaticAssert:
5807 case Decl::TemplateTemplateParm:
5808 case Decl::TemplateTypeParm:
5809 case Decl::UnresolvedUsingTypename:
5810 case Decl::UnresolvedUsingValue:
5811 case Decl::Using:
5812 case Decl::UsingDirective:
5813 case Decl::UsingShadow:
5814 return CXLanguage_CPlusPlus;
5815 }
5816
5817 return CXLanguage_C;
5818}
5819
5820extern "C" {
5821
5822enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5823 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005824 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005825 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5826 return CXAvailability_Available;
5827
5828 switch (D->getAvailability()) {
5829 case AR_Available:
5830 case AR_NotYetIntroduced:
5831 return CXAvailability_Available;
5832
5833 case AR_Deprecated:
5834 return CXAvailability_Deprecated;
5835
5836 case AR_Unavailable:
5837 return CXAvailability_NotAvailable;
5838 }
5839 }
5840
5841 return CXAvailability_Available;
5842}
5843
5844static CXVersion convertVersion(VersionTuple In) {
5845 CXVersion Out = { -1, -1, -1 };
5846 if (In.empty())
5847 return Out;
5848
5849 Out.Major = In.getMajor();
5850
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005851 Optional<unsigned> Minor = In.getMinor();
5852 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005853 Out.Minor = *Minor;
5854 else
5855 return Out;
5856
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005857 Optional<unsigned> Subminor = In.getSubminor();
5858 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005859 Out.Subminor = *Subminor;
5860
5861 return Out;
5862}
5863
5864int clang_getCursorPlatformAvailability(CXCursor cursor,
5865 int *always_deprecated,
5866 CXString *deprecated_message,
5867 int *always_unavailable,
5868 CXString *unavailable_message,
5869 CXPlatformAvailability *availability,
5870 int availability_size) {
5871 if (always_deprecated)
5872 *always_deprecated = 0;
5873 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005874 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005875 if (always_unavailable)
5876 *always_unavailable = 0;
5877 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005878 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005879
5880 if (!clang_isDeclaration(cursor.kind))
5881 return 0;
5882
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005883 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005884 if (!D)
5885 return 0;
5886
5887 int N = 0;
5888 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5889 ++A) {
5890 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5891 if (always_deprecated)
5892 *always_deprecated = 1;
5893 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005894 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005895 continue;
5896 }
5897
5898 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5899 if (always_unavailable)
5900 *always_unavailable = 1;
5901 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005902 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005903 }
5904 continue;
5905 }
5906
5907 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5908 if (N < availability_size) {
5909 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005910 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005911 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5912 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5913 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5914 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005915 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005916 }
5917 ++N;
5918 }
5919 }
5920
5921 return N;
5922}
5923
5924void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5925 clang_disposeString(availability->Platform);
5926 clang_disposeString(availability->Message);
5927}
5928
5929CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5930 if (clang_isDeclaration(cursor.kind))
5931 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5932
5933 return CXLanguage_Invalid;
5934}
5935
5936 /// \brief If the given cursor is the "templated" declaration
5937 /// descibing a class or function template, return the class or
5938 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005939static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005940 if (!D)
5941 return 0;
5942
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005943 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005944 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5945 return FunTmpl;
5946
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005947 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005948 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5949 return ClassTmpl;
5950
5951 return D;
5952}
5953
5954CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5955 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005956 if (const Decl *D = getCursorDecl(cursor)) {
5957 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005958 if (!DC)
5959 return clang_getNullCursor();
5960
5961 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5962 getCursorTU(cursor));
5963 }
5964 }
5965
5966 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005967 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005968 return MakeCXCursor(D, getCursorTU(cursor));
5969 }
5970
5971 return clang_getNullCursor();
5972}
5973
5974CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5975 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005976 if (const Decl *D = getCursorDecl(cursor)) {
5977 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005978 if (!DC)
5979 return clang_getNullCursor();
5980
5981 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5982 getCursorTU(cursor));
5983 }
5984 }
5985
5986 // FIXME: Note that we can't easily compute the lexical context of a
5987 // statement or expression, so we return nothing.
5988 return clang_getNullCursor();
5989}
5990
5991CXFile clang_getIncludedFile(CXCursor cursor) {
5992 if (cursor.kind != CXCursor_InclusionDirective)
5993 return 0;
5994
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005995 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005996 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005997}
5998
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005999unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6000 if (C.kind != CXCursor_ObjCPropertyDecl)
6001 return CXObjCPropertyAttr_noattr;
6002
6003 unsigned Result = CXObjCPropertyAttr_noattr;
6004 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6005 ObjCPropertyDecl::PropertyAttributeKind Attr =
6006 PD->getPropertyAttributesAsWritten();
6007
6008#define SET_CXOBJCPROP_ATTR(A) \
6009 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6010 Result |= CXObjCPropertyAttr_##A
6011 SET_CXOBJCPROP_ATTR(readonly);
6012 SET_CXOBJCPROP_ATTR(getter);
6013 SET_CXOBJCPROP_ATTR(assign);
6014 SET_CXOBJCPROP_ATTR(readwrite);
6015 SET_CXOBJCPROP_ATTR(retain);
6016 SET_CXOBJCPROP_ATTR(copy);
6017 SET_CXOBJCPROP_ATTR(nonatomic);
6018 SET_CXOBJCPROP_ATTR(setter);
6019 SET_CXOBJCPROP_ATTR(atomic);
6020 SET_CXOBJCPROP_ATTR(weak);
6021 SET_CXOBJCPROP_ATTR(strong);
6022 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6023#undef SET_CXOBJCPROP_ATTR
6024
6025 return Result;
6026}
6027
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006028unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6029 if (!clang_isDeclaration(C.kind))
6030 return CXObjCDeclQualifier_None;
6031
6032 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6033 const Decl *D = getCursorDecl(C);
6034 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6035 QT = MD->getObjCDeclQualifier();
6036 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6037 QT = PD->getObjCDeclQualifier();
6038 if (QT == Decl::OBJC_TQ_None)
6039 return CXObjCDeclQualifier_None;
6040
6041 unsigned Result = CXObjCDeclQualifier_None;
6042 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6043 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6044 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6045 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6046 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6047 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6048
6049 return Result;
6050}
6051
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006052unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6053 if (!clang_isDeclaration(C.kind))
6054 return 0;
6055
6056 const Decl *D = getCursorDecl(C);
6057 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6058 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6059 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6060 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6061
6062 return 0;
6063}
6064
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006065unsigned clang_Cursor_isVariadic(CXCursor C) {
6066 if (!clang_isDeclaration(C.kind))
6067 return 0;
6068
6069 const Decl *D = getCursorDecl(C);
6070 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6071 return FD->isVariadic();
6072 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6073 return MD->isVariadic();
6074
6075 return 0;
6076}
6077
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006078CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6079 if (!clang_isDeclaration(C.kind))
6080 return clang_getNullRange();
6081
6082 const Decl *D = getCursorDecl(C);
6083 ASTContext &Context = getCursorContext(C);
6084 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6085 if (!RC)
6086 return clang_getNullRange();
6087
6088 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6089}
6090
6091CXString clang_Cursor_getRawCommentText(CXCursor C) {
6092 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006093 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006094
6095 const Decl *D = getCursorDecl(C);
6096 ASTContext &Context = getCursorContext(C);
6097 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6098 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6099 StringRef();
6100
6101 // Don't duplicate the string because RawText points directly into source
6102 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006103 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006104}
6105
6106CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6107 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006108 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006109
6110 const Decl *D = getCursorDecl(C);
6111 const ASTContext &Context = getCursorContext(C);
6112 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6113
6114 if (RC) {
6115 StringRef BriefText = RC->getBriefText(Context);
6116
6117 // Don't duplicate the string because RawComment ensures that this memory
6118 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006119 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006120 }
6121
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006122 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006123}
6124
6125CXComment clang_Cursor_getParsedComment(CXCursor C) {
6126 if (!clang_isDeclaration(C.kind))
6127 return cxcomment::createCXComment(NULL, NULL);
6128
6129 const Decl *D = getCursorDecl(C);
6130 const ASTContext &Context = getCursorContext(C);
6131 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6132
6133 return cxcomment::createCXComment(FC, getCursorTU(C));
6134}
6135
6136CXModule clang_Cursor_getModule(CXCursor C) {
6137 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006138 if (const ImportDecl *ImportD =
6139 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006140 return ImportD->getImportedModule();
6141 }
6142
6143 return 0;
6144}
6145
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006146CXFile clang_Module_getASTFile(CXModule CXMod) {
6147 if (!CXMod)
6148 return 0;
6149 Module *Mod = static_cast<Module*>(CXMod);
6150 return const_cast<FileEntry *>(Mod->getASTFile());
6151}
6152
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006153CXModule clang_Module_getParent(CXModule CXMod) {
6154 if (!CXMod)
6155 return 0;
6156 Module *Mod = static_cast<Module*>(CXMod);
6157 return Mod->Parent;
6158}
6159
6160CXString clang_Module_getName(CXModule CXMod) {
6161 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006162 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006163 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006164 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006165}
6166
6167CXString clang_Module_getFullName(CXModule CXMod) {
6168 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006169 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006170 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006171 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006172}
6173
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006174unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6175 CXModule CXMod) {
6176 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006177 return 0;
6178 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006179 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6180 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6181 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006182}
6183
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006184CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6185 CXModule CXMod, unsigned Index) {
6186 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006187 return 0;
6188 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006189 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006190
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006191 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6192 if (Index < TopHeaders.size())
6193 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006194
6195 return 0;
6196}
6197
6198} // end: extern "C"
6199
6200//===----------------------------------------------------------------------===//
6201// C++ AST instrospection.
6202//===----------------------------------------------------------------------===//
6203
6204extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006205unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6206 if (!clang_isDeclaration(C.kind))
6207 return 0;
6208
6209 const CXXMethodDecl *Method = 0;
6210 const Decl *D = cxcursor::getCursorDecl(C);
6211 if (const FunctionTemplateDecl *FunTmpl =
6212 dyn_cast_or_null<FunctionTemplateDecl>(D))
6213 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6214 else
6215 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6216 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6217}
6218
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006219unsigned clang_CXXMethod_isStatic(CXCursor C) {
6220 if (!clang_isDeclaration(C.kind))
6221 return 0;
6222
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006223 const CXXMethodDecl *Method = 0;
6224 const Decl *D = cxcursor::getCursorDecl(C);
6225 if (const FunctionTemplateDecl *FunTmpl =
6226 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006227 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6228 else
6229 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6230 return (Method && Method->isStatic()) ? 1 : 0;
6231}
6232
6233unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6234 if (!clang_isDeclaration(C.kind))
6235 return 0;
6236
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006237 const CXXMethodDecl *Method = 0;
6238 const Decl *D = cxcursor::getCursorDecl(C);
6239 if (const FunctionTemplateDecl *FunTmpl =
6240 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006241 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6242 else
6243 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6244 return (Method && Method->isVirtual()) ? 1 : 0;
6245}
6246} // end: extern "C"
6247
6248//===----------------------------------------------------------------------===//
6249// Attribute introspection.
6250//===----------------------------------------------------------------------===//
6251
6252extern "C" {
6253CXType clang_getIBOutletCollectionType(CXCursor C) {
6254 if (C.kind != CXCursor_IBOutletCollectionAttr)
6255 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6256
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006257 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006258 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6259
6260 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6261}
6262} // end: extern "C"
6263
6264//===----------------------------------------------------------------------===//
6265// Inspecting memory usage.
6266//===----------------------------------------------------------------------===//
6267
6268typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6269
6270static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6271 enum CXTUResourceUsageKind k,
6272 unsigned long amount) {
6273 CXTUResourceUsageEntry entry = { k, amount };
6274 entries.push_back(entry);
6275}
6276
6277extern "C" {
6278
6279const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6280 const char *str = "";
6281 switch (kind) {
6282 case CXTUResourceUsage_AST:
6283 str = "ASTContext: expressions, declarations, and types";
6284 break;
6285 case CXTUResourceUsage_Identifiers:
6286 str = "ASTContext: identifiers";
6287 break;
6288 case CXTUResourceUsage_Selectors:
6289 str = "ASTContext: selectors";
6290 break;
6291 case CXTUResourceUsage_GlobalCompletionResults:
6292 str = "Code completion: cached global results";
6293 break;
6294 case CXTUResourceUsage_SourceManagerContentCache:
6295 str = "SourceManager: content cache allocator";
6296 break;
6297 case CXTUResourceUsage_AST_SideTables:
6298 str = "ASTContext: side tables";
6299 break;
6300 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6301 str = "SourceManager: malloc'ed memory buffers";
6302 break;
6303 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6304 str = "SourceManager: mmap'ed memory buffers";
6305 break;
6306 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6307 str = "ExternalASTSource: malloc'ed memory buffers";
6308 break;
6309 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6310 str = "ExternalASTSource: mmap'ed memory buffers";
6311 break;
6312 case CXTUResourceUsage_Preprocessor:
6313 str = "Preprocessor: malloc'ed memory";
6314 break;
6315 case CXTUResourceUsage_PreprocessingRecord:
6316 str = "Preprocessor: PreprocessingRecord";
6317 break;
6318 case CXTUResourceUsage_SourceManager_DataStructures:
6319 str = "SourceManager: data structures and tables";
6320 break;
6321 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6322 str = "Preprocessor: header search tables";
6323 break;
6324 }
6325 return str;
6326}
6327
6328CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6329 if (!TU) {
6330 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6331 return usage;
6332 }
6333
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006334 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006335 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6336 ASTContext &astContext = astUnit->getASTContext();
6337
6338 // How much memory is used by AST nodes and types?
6339 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6340 (unsigned long) astContext.getASTAllocatedMemory());
6341
6342 // How much memory is used by identifiers?
6343 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6344 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6345
6346 // How much memory is used for selectors?
6347 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6348 (unsigned long) astContext.Selectors.getTotalMemory());
6349
6350 // How much memory is used by ASTContext's side tables?
6351 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6352 (unsigned long) astContext.getSideTableAllocatedMemory());
6353
6354 // How much memory is used for caching global code completion results?
6355 unsigned long completionBytes = 0;
6356 if (GlobalCodeCompletionAllocator *completionAllocator =
6357 astUnit->getCachedCompletionAllocator().getPtr()) {
6358 completionBytes = completionAllocator->getTotalMemory();
6359 }
6360 createCXTUResourceUsageEntry(*entries,
6361 CXTUResourceUsage_GlobalCompletionResults,
6362 completionBytes);
6363
6364 // How much memory is being used by SourceManager's content cache?
6365 createCXTUResourceUsageEntry(*entries,
6366 CXTUResourceUsage_SourceManagerContentCache,
6367 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6368
6369 // How much memory is being used by the MemoryBuffer's in SourceManager?
6370 const SourceManager::MemoryBufferSizes &srcBufs =
6371 astUnit->getSourceManager().getMemoryBufferSizes();
6372
6373 createCXTUResourceUsageEntry(*entries,
6374 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6375 (unsigned long) srcBufs.malloc_bytes);
6376 createCXTUResourceUsageEntry(*entries,
6377 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6378 (unsigned long) srcBufs.mmap_bytes);
6379 createCXTUResourceUsageEntry(*entries,
6380 CXTUResourceUsage_SourceManager_DataStructures,
6381 (unsigned long) astContext.getSourceManager()
6382 .getDataStructureSizes());
6383
6384 // How much memory is being used by the ExternalASTSource?
6385 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6386 const ExternalASTSource::MemoryBufferSizes &sizes =
6387 esrc->getMemoryBufferSizes();
6388
6389 createCXTUResourceUsageEntry(*entries,
6390 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6391 (unsigned long) sizes.malloc_bytes);
6392 createCXTUResourceUsageEntry(*entries,
6393 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6394 (unsigned long) sizes.mmap_bytes);
6395 }
6396
6397 // How much memory is being used by the Preprocessor?
6398 Preprocessor &pp = astUnit->getPreprocessor();
6399 createCXTUResourceUsageEntry(*entries,
6400 CXTUResourceUsage_Preprocessor,
6401 pp.getTotalMemory());
6402
6403 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6404 createCXTUResourceUsageEntry(*entries,
6405 CXTUResourceUsage_PreprocessingRecord,
6406 pRec->getTotalMemory());
6407 }
6408
6409 createCXTUResourceUsageEntry(*entries,
6410 CXTUResourceUsage_Preprocessor_HeaderSearch,
6411 pp.getHeaderSearchInfo().getTotalMemory());
6412
6413 CXTUResourceUsage usage = { (void*) entries.get(),
6414 (unsigned) entries->size(),
6415 entries->size() ? &(*entries)[0] : 0 };
6416 entries.take();
6417 return usage;
6418}
6419
6420void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6421 if (usage.data)
6422 delete (MemUsageEntries*) usage.data;
6423}
6424
6425} // end extern "C"
6426
6427void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6428 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6429 for (unsigned I = 0; I != Usage.numEntries; ++I)
6430 fprintf(stderr, " %s: %lu\n",
6431 clang_getTUResourceUsageName(Usage.entries[I].kind),
6432 Usage.entries[I].amount);
6433
6434 clang_disposeCXTUResourceUsage(Usage);
6435}
6436
6437//===----------------------------------------------------------------------===//
6438// Misc. utility functions.
6439//===----------------------------------------------------------------------===//
6440
6441/// Default to using an 8 MB stack size on "safety" threads.
6442static unsigned SafetyStackThreadSize = 8 << 20;
6443
6444namespace clang {
6445
6446bool RunSafely(llvm::CrashRecoveryContext &CRC,
6447 void (*Fn)(void*), void *UserData,
6448 unsigned Size) {
6449 if (!Size)
6450 Size = GetSafetyThreadStackSize();
6451 if (Size)
6452 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6453 return CRC.RunSafely(Fn, UserData);
6454}
6455
6456unsigned GetSafetyThreadStackSize() {
6457 return SafetyStackThreadSize;
6458}
6459
6460void SetSafetyThreadStackSize(unsigned Value) {
6461 SafetyStackThreadSize = Value;
6462}
6463
6464}
6465
6466void clang::setThreadBackgroundPriority() {
6467 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6468 return;
6469
6470 // FIXME: Move to llvm/Support and make it cross-platform.
6471#ifdef __APPLE__
6472 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6473#endif
6474}
6475
6476void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6477 if (!Unit)
6478 return;
6479
6480 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6481 DEnd = Unit->stored_diag_end();
6482 D != DEnd; ++D) {
6483 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6484 CXString Msg = clang_formatDiagnostic(&Diag,
6485 clang_defaultDiagnosticDisplayOptions());
6486 fprintf(stderr, "%s\n", clang_getCString(Msg));
6487 clang_disposeString(Msg);
6488 }
6489#ifdef LLVM_ON_WIN32
6490 // On Windows, force a flush, since there may be multiple copies of
6491 // stderr and stdout in the file system, all with different buffers
6492 // but writing to the same device.
6493 fflush(stderr);
6494#endif
6495}
6496
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006497MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6498 SourceLocation MacroDefLoc,
6499 CXTranslationUnit TU){
6500 if (MacroDefLoc.isInvalid() || !TU)
6501 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006502 if (!II.hadMacroDefinition())
6503 return 0;
6504
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006505 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006506 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006507 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006508 if (MD) {
6509 for (MacroDirective::DefInfo
6510 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6511 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6512 return Def.getMacroInfo();
6513 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006514 }
6515
6516 return 0;
6517}
6518
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006519const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6520 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006521 if (!MacroDef || !TU)
6522 return 0;
6523 const IdentifierInfo *II = MacroDef->getName();
6524 if (!II)
6525 return 0;
6526
6527 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6528}
6529
6530MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6531 const Token &Tok,
6532 CXTranslationUnit TU) {
6533 if (!MI || !TU)
6534 return 0;
6535 if (Tok.isNot(tok::raw_identifier))
6536 return 0;
6537
6538 if (MI->getNumTokens() == 0)
6539 return 0;
6540 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6541 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006542 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006543
6544 // Check that the token is inside the definition and not its argument list.
6545 SourceManager &SM = Unit->getSourceManager();
6546 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6547 return 0;
6548 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6549 return 0;
6550
6551 Preprocessor &PP = Unit->getPreprocessor();
6552 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6553 if (!PPRec)
6554 return 0;
6555
6556 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6557 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6558 if (!II.hadMacroDefinition())
6559 return 0;
6560
6561 // Check that the identifier is not one of the macro arguments.
6562 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6563 return 0;
6564
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006565 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6566 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006567 return 0;
6568
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006569 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006570}
6571
6572MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6573 SourceLocation Loc,
6574 CXTranslationUnit TU) {
6575 if (Loc.isInvalid() || !MI || !TU)
6576 return 0;
6577
6578 if (MI->getNumTokens() == 0)
6579 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006580 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006581 Preprocessor &PP = Unit->getPreprocessor();
6582 if (!PP.getPreprocessingRecord())
6583 return 0;
6584 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6585 Token Tok;
6586 if (PP.getRawToken(Loc, Tok))
6587 return 0;
6588
6589 return checkForMacroInMacroDefinition(MI, Tok, TU);
6590}
6591
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006592extern "C" {
6593
6594CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006595 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006596}
6597
6598} // end: extern "C"
6599
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006600Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6601 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006602 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006603 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006604 if (Unit->isMainFileAST())
6605 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006606 return *this;
6607 }
6608 }
6609
6610 LogOS << "<NULL TU>";
6611 return *this;
6612}
6613
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006614Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6615 *this << FE->getName();
6616 return *this;
6617}
6618
6619Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6620 CXString cursorName = clang_getCursorDisplayName(cursor);
6621 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6622 clang_disposeString(cursorName);
6623 return *this;
6624}
6625
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006626Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6627 CXFile File;
6628 unsigned Line, Column;
6629 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6630 CXString FileName = clang_getFileName(File);
6631 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6632 clang_disposeString(FileName);
6633 return *this;
6634}
6635
6636Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6637 CXSourceLocation BLoc = clang_getRangeStart(range);
6638 CXSourceLocation ELoc = clang_getRangeEnd(range);
6639
6640 CXFile BFile;
6641 unsigned BLine, BColumn;
6642 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6643
6644 CXFile EFile;
6645 unsigned ELine, EColumn;
6646 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6647
6648 CXString BFileName = clang_getFileName(BFile);
6649 if (BFile == EFile) {
6650 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6651 BLine, BColumn, ELine, EColumn);
6652 } else {
6653 CXString EFileName = clang_getFileName(EFile);
6654 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6655 BLine, BColumn)
6656 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6657 ELine, EColumn);
6658 clang_disposeString(EFileName);
6659 }
6660 clang_disposeString(BFileName);
6661 return *this;
6662}
6663
6664Logger &cxindex::Logger::operator<<(CXString Str) {
6665 *this << clang_getCString(Str);
6666 return *this;
6667}
6668
6669Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6670 LogOS << Fmt;
6671 return *this;
6672}
6673
6674cxindex::Logger::~Logger() {
6675 LogOS.flush();
6676
6677 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6678
6679 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6680
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006681 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006682 OS << "[libclang:" << Name << ':';
6683
6684 // FIXME: Portability.
6685#if HAVE_PTHREAD_H && __APPLE__
6686 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6687 OS << tid << ':';
6688#endif
6689
6690 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6691 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6692 OS << Msg.str() << '\n';
6693
6694 if (Trace) {
6695 llvm::sys::PrintStackTrace(stderr);
6696 OS << "--------------------------------------------------\n";
6697 }
6698}