blob: 765c900012185054391afe5aa3cb1dac51f8eb1f [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());
2075 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002076 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002077 D = E->designators_rbegin(), DEnd = E->designators_rend();
2078 D != DEnd; ++D) {
2079 if (D->isFieldDesignator()) {
2080 if (FieldDecl *Field = D->getField())
2081 AddMemberRef(Field, D->getFieldLoc());
2082 continue;
2083 }
2084 if (D->isArrayDesignator()) {
2085 AddStmt(E->getArrayIndex(*D));
2086 continue;
2087 }
2088 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2089 AddStmt(E->getArrayRangeEnd(*D));
2090 AddStmt(E->getArrayRangeStart(*D));
2091 }
2092}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002094 EnqueueChildren(E);
2095 AddTypeLoc(E->getTypeInfoAsWritten());
2096}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002098 AddStmt(FS->getBody());
2099 AddStmt(FS->getInc());
2100 AddStmt(FS->getCond());
2101 AddDecl(FS->getConditionVariable());
2102 AddStmt(FS->getInit());
2103}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002105 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2106}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002108 AddStmt(If->getElse());
2109 AddStmt(If->getThen());
2110 AddStmt(If->getCond());
2111 AddDecl(If->getConditionVariable());
2112}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002114 // We care about the syntactic form of the initializer list, only.
2115 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2116 IE = Syntactic;
2117 EnqueueChildren(IE);
2118}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002120 WL.push_back(MemberExprParts(M, Parent));
2121
2122 // If the base of the member access expression is an implicit 'this', don't
2123 // visit it.
2124 // FIXME: If we ever want to show these implicit accesses, this will be
2125 // unfortunate. However, clang_getCursor() relies on this behavior.
2126 if (!M->isImplicitAccess())
2127 AddStmt(M->getBase());
2128}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002130 AddTypeLoc(E->getEncodedTypeSourceInfo());
2131}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002133 EnqueueChildren(M);
2134 AddTypeLoc(M->getClassReceiverTypeInfo());
2135}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002137 // Visit the components of the offsetof expression.
2138 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2139 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2140 const OffsetOfNode &Node = E->getComponent(I-1);
2141 switch (Node.getKind()) {
2142 case OffsetOfNode::Array:
2143 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2144 break;
2145 case OffsetOfNode::Field:
2146 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2147 break;
2148 case OffsetOfNode::Identifier:
2149 case OffsetOfNode::Base:
2150 continue;
2151 }
2152 }
2153 // Visit the type into which we're computing the offset.
2154 AddTypeLoc(E->getTypeSourceInfo());
2155}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002157 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2158 WL.push_back(OverloadExprParts(E, Parent));
2159}
2160void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002161 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002162 EnqueueChildren(E);
2163 if (E->isArgumentType())
2164 AddTypeLoc(E->getArgumentTypeInfo());
2165}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 EnqueueChildren(S);
2168}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002170 AddStmt(S->getBody());
2171 AddStmt(S->getCond());
2172 AddDecl(S->getConditionVariable());
2173}
2174
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002176 AddStmt(W->getBody());
2177 AddStmt(W->getCond());
2178 AddDecl(W->getConditionVariable());
2179}
2180
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002182 AddTypeLoc(E->getQueriedTypeSourceInfo());
2183}
2184
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002186 AddTypeLoc(E->getRhsTypeSourceInfo());
2187 AddTypeLoc(E->getLhsTypeSourceInfo());
2188}
2189
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002191 for (unsigned I = E->getNumArgs(); I > 0; --I)
2192 AddTypeLoc(E->getArg(I-1));
2193}
2194
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002196 AddTypeLoc(E->getQueriedTypeSourceInfo());
2197}
2198
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002200 EnqueueChildren(E);
2201}
2202
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002204 VisitOverloadExpr(U);
2205 if (!U->isImplicitAccess())
2206 AddStmt(U->getBase());
2207}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002209 AddStmt(E->getSubExpr());
2210 AddTypeLoc(E->getWrittenTypeInfo());
2211}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002213 WL.push_back(SizeOfPackExprParts(E, Parent));
2214}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002216 // If the opaque value has a source expression, just transparently
2217 // visit that. This is useful for (e.g.) pseudo-object expressions.
2218 if (Expr *SourceExpr = E->getSourceExpr())
2219 return Visit(SourceExpr);
2220}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002222 AddStmt(E->getBody());
2223 WL.push_back(LambdaExprParts(E, Parent));
2224}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002226 // Treat the expression like its syntactic form.
2227 Visit(E->getSyntacticForm());
2228}
2229
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002230void EnqueueVisitor::VisitOMPExecutableDirective(
2231 const OMPExecutableDirective *D) {
2232 EnqueueChildren(D);
2233 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2234 E = D->clauses().end();
2235 I != E; ++I)
2236 EnqueueChildren(*I);
2237}
2238
2239void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2240 VisitOMPExecutableDirective(D);
2241}
2242
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002243void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002244 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2245}
2246
2247bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2248 if (RegionOfInterest.isValid()) {
2249 SourceRange Range = getRawCursorExtent(C);
2250 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2251 return false;
2252 }
2253 return true;
2254}
2255
2256bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2257 while (!WL.empty()) {
2258 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002259 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002260
2261 // Set the Parent field, then back to its old value once we're done.
2262 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2263
2264 switch (LI.getKind()) {
2265 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002266 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002267 if (!D)
2268 continue;
2269
2270 // For now, perform default visitation for Decls.
2271 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2272 cast<DeclVisit>(&LI)->isFirst())))
2273 return true;
2274
2275 continue;
2276 }
2277 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2278 const ASTTemplateArgumentListInfo *ArgList =
2279 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2280 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2281 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2282 Arg != ArgEnd; ++Arg) {
2283 if (VisitTemplateArgumentLoc(*Arg))
2284 return true;
2285 }
2286 continue;
2287 }
2288 case VisitorJob::TypeLocVisitKind: {
2289 // Perform default visitation for TypeLocs.
2290 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2291 return true;
2292 continue;
2293 }
2294 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002295 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002296 if (LabelStmt *stmt = LS->getStmt()) {
2297 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2298 TU))) {
2299 return true;
2300 }
2301 }
2302 continue;
2303 }
2304
2305 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2306 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2307 if (VisitNestedNameSpecifierLoc(V->get()))
2308 return true;
2309 continue;
2310 }
2311
2312 case VisitorJob::DeclarationNameInfoVisitKind: {
2313 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2314 ->get()))
2315 return true;
2316 continue;
2317 }
2318 case VisitorJob::MemberRefVisitKind: {
2319 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2320 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2321 return true;
2322 continue;
2323 }
2324 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002325 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002326 if (!S)
2327 continue;
2328
2329 // Update the current cursor.
2330 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2331 if (!IsInRegionOfInterest(Cursor))
2332 continue;
2333 switch (Visitor(Cursor, Parent, ClientData)) {
2334 case CXChildVisit_Break: return true;
2335 case CXChildVisit_Continue: break;
2336 case CXChildVisit_Recurse:
2337 if (PostChildrenVisitor)
2338 WL.push_back(PostChildrenVisit(0, Cursor));
2339 EnqueueWorkList(WL, S);
2340 break;
2341 }
2342 continue;
2343 }
2344 case VisitorJob::MemberExprPartsKind: {
2345 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002346 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002347
2348 // Visit the nested-name-specifier
2349 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2350 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2351 return true;
2352
2353 // Visit the declaration name.
2354 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2355 return true;
2356
2357 // Visit the explicitly-specified template arguments, if any.
2358 if (M->hasExplicitTemplateArgs()) {
2359 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2360 *ArgEnd = Arg + M->getNumTemplateArgs();
2361 Arg != ArgEnd; ++Arg) {
2362 if (VisitTemplateArgumentLoc(*Arg))
2363 return true;
2364 }
2365 }
2366 continue;
2367 }
2368 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002369 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002370 // Visit nested-name-specifier, if present.
2371 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2372 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2373 return true;
2374 // Visit declaration name.
2375 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2376 return true;
2377 continue;
2378 }
2379 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002380 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002381 // Visit the nested-name-specifier.
2382 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2383 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2384 return true;
2385 // Visit the declaration name.
2386 if (VisitDeclarationNameInfo(O->getNameInfo()))
2387 return true;
2388 // Visit the overloaded declaration reference.
2389 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002394 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002395 NamedDecl *Pack = E->getPack();
2396 if (isa<TemplateTypeParmDecl>(Pack)) {
2397 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2398 E->getPackLoc(), TU)))
2399 return true;
2400
2401 continue;
2402 }
2403
2404 if (isa<TemplateTemplateParmDecl>(Pack)) {
2405 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2406 E->getPackLoc(), TU)))
2407 return true;
2408
2409 continue;
2410 }
2411
2412 // Non-type template parameter packs and function parameter packs are
2413 // treated like DeclRefExpr cursors.
2414 continue;
2415 }
2416
2417 case VisitorJob::LambdaExprPartsKind: {
2418 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002419 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002420 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2421 CEnd = E->explicit_capture_end();
2422 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002423 // FIXME: Lambda init-captures.
2424 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002425 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002426
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002427 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2428 C->getLocation(),
2429 TU)))
2430 return true;
2431 }
2432
2433 // Visit parameters and return type, if present.
2434 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2435 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2436 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2437 // Visit the whole type.
2438 if (Visit(TL))
2439 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002440 } else if (FunctionProtoTypeLoc Proto =
2441 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002442 if (E->hasExplicitParameters()) {
2443 // Visit parameters.
2444 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2445 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2446 return true;
2447 } else {
2448 // Visit result type.
2449 if (Visit(Proto.getResultLoc()))
2450 return true;
2451 }
2452 }
2453 }
2454 break;
2455 }
2456
2457 case VisitorJob::PostChildrenVisitKind:
2458 if (PostChildrenVisitor(Parent, ClientData))
2459 return true;
2460 break;
2461 }
2462 }
2463 return false;
2464}
2465
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002466bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002467 VisitorWorkList *WL = 0;
2468 if (!WorkListFreeList.empty()) {
2469 WL = WorkListFreeList.back();
2470 WL->clear();
2471 WorkListFreeList.pop_back();
2472 }
2473 else {
2474 WL = new VisitorWorkList();
2475 WorkListCache.push_back(WL);
2476 }
2477 EnqueueWorkList(*WL, S);
2478 bool result = RunVisitorWorkList(*WL);
2479 WorkListFreeList.push_back(WL);
2480 return result;
2481}
2482
2483namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002484typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002485RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2486 const DeclarationNameInfo &NI,
2487 const SourceRange &QLoc,
2488 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2489 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2490 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2491 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2492
2493 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2494
2495 RefNamePieces Pieces;
2496
2497 if (WantQualifier && QLoc.isValid())
2498 Pieces.push_back(QLoc);
2499
2500 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2501 Pieces.push_back(NI.getLoc());
2502
2503 if (WantTemplateArgs && TemplateArgs)
2504 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2505 TemplateArgs->RAngleLoc));
2506
2507 if (Kind == DeclarationName::CXXOperatorName) {
2508 Pieces.push_back(SourceLocation::getFromRawEncoding(
2509 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2510 Pieces.push_back(SourceLocation::getFromRawEncoding(
2511 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2512 }
2513
2514 if (WantSinglePiece) {
2515 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2516 Pieces.clear();
2517 Pieces.push_back(R);
2518 }
2519
2520 return Pieces;
2521}
2522}
2523
2524//===----------------------------------------------------------------------===//
2525// Misc. API hooks.
2526//===----------------------------------------------------------------------===//
2527
2528static llvm::sys::Mutex EnableMultithreadingMutex;
2529static bool EnabledMultithreading;
2530
Chad Rosier90836282013-03-27 18:28:23 +00002531static void fatal_error_handler(void *user_data, const std::string& reason,
2532 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002533 // Write the result out to stderr avoiding errs() because raw_ostreams can
2534 // call report_fatal_error.
2535 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2536 ::abort();
2537}
2538
2539extern "C" {
2540CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2541 int displayDiagnostics) {
2542 // Disable pretty stack trace functionality, which will otherwise be a very
2543 // poor citizen of the world and set up all sorts of signal handlers.
2544 llvm::DisablePrettyStackTrace = true;
2545
2546 // We use crash recovery to make some of our APIs more reliable, implicitly
2547 // enable it.
2548 llvm::CrashRecoveryContext::Enable();
2549
2550 // Enable support for multithreading in LLVM.
2551 {
2552 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2553 if (!EnabledMultithreading) {
2554 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2555 llvm::llvm_start_multithreaded();
2556 EnabledMultithreading = true;
2557 }
2558 }
2559
2560 CIndexer *CIdxr = new CIndexer();
2561 if (excludeDeclarationsFromPCH)
2562 CIdxr->setOnlyLocalDecls();
2563 if (displayDiagnostics)
2564 CIdxr->setDisplayDiagnostics();
2565
2566 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2567 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2568 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2569 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2570 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2571 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2572
2573 return CIdxr;
2574}
2575
2576void clang_disposeIndex(CXIndex CIdx) {
2577 if (CIdx)
2578 delete static_cast<CIndexer *>(CIdx);
2579}
2580
2581void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2582 if (CIdx)
2583 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2584}
2585
2586unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2587 if (CIdx)
2588 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2589 return 0;
2590}
2591
2592void clang_toggleCrashRecovery(unsigned isEnabled) {
2593 if (isEnabled)
2594 llvm::CrashRecoveryContext::Enable();
2595 else
2596 llvm::CrashRecoveryContext::Disable();
2597}
2598
2599CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2600 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002601 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002602 return 0;
2603
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002604 LOG_FUNC_SECTION {
2605 *Log << ast_filename;
2606 }
2607
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002608 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2609 FileSystemOptions FileSystemOpts;
2610
2611 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2612 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2613 CXXIdx->getOnlyLocalDecls(),
2614 0, 0,
2615 /*CaptureDiagnostics=*/true,
2616 /*AllowPCHWithCompilerErrors=*/true,
2617 /*UserFilesAreVolatile=*/true);
2618 return MakeCXTranslationUnit(CXXIdx, TU);
2619}
2620
2621unsigned clang_defaultEditingTranslationUnitOptions() {
2622 return CXTranslationUnit_PrecompiledPreamble |
2623 CXTranslationUnit_CacheCompletionResults;
2624}
2625
2626CXTranslationUnit
2627clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2628 const char *source_filename,
2629 int num_command_line_args,
2630 const char * const *command_line_args,
2631 unsigned num_unsaved_files,
2632 struct CXUnsavedFile *unsaved_files) {
2633 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2634 return clang_parseTranslationUnit(CIdx, source_filename,
2635 command_line_args, num_command_line_args,
2636 unsaved_files, num_unsaved_files,
2637 Options);
2638}
2639
2640struct ParseTranslationUnitInfo {
2641 CXIndex CIdx;
2642 const char *source_filename;
2643 const char *const *command_line_args;
2644 int num_command_line_args;
2645 struct CXUnsavedFile *unsaved_files;
2646 unsigned num_unsaved_files;
2647 unsigned options;
2648 CXTranslationUnit result;
2649};
2650static void clang_parseTranslationUnit_Impl(void *UserData) {
2651 ParseTranslationUnitInfo *PTUI =
2652 static_cast<ParseTranslationUnitInfo*>(UserData);
2653 CXIndex CIdx = PTUI->CIdx;
2654 const char *source_filename = PTUI->source_filename;
2655 const char * const *command_line_args = PTUI->command_line_args;
2656 int num_command_line_args = PTUI->num_command_line_args;
2657 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2658 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2659 unsigned options = PTUI->options;
2660 PTUI->result = 0;
2661
2662 if (!CIdx)
2663 return;
2664
2665 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2666
2667 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2668 setThreadBackgroundPriority();
2669
2670 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2671 // FIXME: Add a flag for modules.
2672 TranslationUnitKind TUKind
2673 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2674 bool CacheCodeCompetionResults
2675 = options & CXTranslationUnit_CacheCompletionResults;
2676 bool IncludeBriefCommentsInCodeCompletion
2677 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2678 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2679 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2680
2681 // Configure the diagnostics.
2682 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002683 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002684
2685 // Recover resources if we crash before exiting this function.
2686 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2687 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2688 DiagCleanup(Diags.getPtr());
2689
2690 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2691 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2692
2693 // Recover resources if we crash before exiting this function.
2694 llvm::CrashRecoveryContextCleanupRegistrar<
2695 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2696
2697 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2698 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2699 const llvm::MemoryBuffer *Buffer
2700 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2701 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2702 Buffer));
2703 }
2704
2705 OwningPtr<std::vector<const char *> >
2706 Args(new std::vector<const char*>());
2707
2708 // Recover resources if we crash before exiting this method.
2709 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2710 ArgsCleanup(Args.get());
2711
2712 // Since the Clang C library is primarily used by batch tools dealing with
2713 // (often very broken) source code, where spell-checking can have a
2714 // significant negative impact on performance (particularly when
2715 // precompiled headers are involved), we disable it by default.
2716 // Only do this if we haven't found a spell-checking-related argument.
2717 bool FoundSpellCheckingArgument = false;
2718 for (int I = 0; I != num_command_line_args; ++I) {
2719 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2720 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2721 FoundSpellCheckingArgument = true;
2722 break;
2723 }
2724 }
2725 if (!FoundSpellCheckingArgument)
2726 Args->push_back("-fno-spell-checking");
2727
2728 Args->insert(Args->end(), command_line_args,
2729 command_line_args + num_command_line_args);
2730
2731 // The 'source_filename' argument is optional. If the caller does not
2732 // specify it then it is assumed that the source file is specified
2733 // in the actual argument list.
2734 // Put the source file after command_line_args otherwise if '-x' flag is
2735 // present it will be unused.
2736 if (source_filename)
2737 Args->push_back(source_filename);
2738
2739 // Do we need the detailed preprocessing record?
2740 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2741 Args->push_back("-Xclang");
2742 Args->push_back("-detailed-preprocessing-record");
2743 }
2744
2745 unsigned NumErrors = Diags->getClient()->getNumErrors();
2746 OwningPtr<ASTUnit> ErrUnit;
2747 OwningPtr<ASTUnit> Unit(
2748 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2749 /* vector::data() not portable */,
2750 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2751 Diags,
2752 CXXIdx->getClangResourcesPath(),
2753 CXXIdx->getOnlyLocalDecls(),
2754 /*CaptureDiagnostics=*/true,
2755 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2756 RemappedFiles->size(),
2757 /*RemappedFilesKeepOriginalName=*/true,
2758 PrecompilePreamble,
2759 TUKind,
2760 CacheCodeCompetionResults,
2761 IncludeBriefCommentsInCodeCompletion,
2762 /*AllowPCHWithCompilerErrors=*/true,
2763 SkipFunctionBodies,
2764 /*UserFilesAreVolatile=*/true,
2765 ForSerialization,
2766 &ErrUnit));
2767
2768 if (NumErrors != Diags->getClient()->getNumErrors()) {
2769 // Make sure to check that 'Unit' is non-NULL.
2770 if (CXXIdx->getDisplayDiagnostics())
2771 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2772 }
2773
2774 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2775}
2776CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2777 const char *source_filename,
2778 const char * const *command_line_args,
2779 int num_command_line_args,
2780 struct CXUnsavedFile *unsaved_files,
2781 unsigned num_unsaved_files,
2782 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002783 LOG_FUNC_SECTION {
2784 *Log << source_filename << ": ";
2785 for (int i = 0; i != num_command_line_args; ++i)
2786 *Log << command_line_args[i] << " ";
2787 }
2788
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002789 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2790 num_command_line_args, unsaved_files,
2791 num_unsaved_files, options, 0 };
2792 llvm::CrashRecoveryContext CRC;
2793
2794 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2795 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2796 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2797 fprintf(stderr, " 'command_line_args' : [");
2798 for (int i = 0; i != num_command_line_args; ++i) {
2799 if (i)
2800 fprintf(stderr, ", ");
2801 fprintf(stderr, "'%s'", command_line_args[i]);
2802 }
2803 fprintf(stderr, "],\n");
2804 fprintf(stderr, " 'unsaved_files' : [");
2805 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2806 if (i)
2807 fprintf(stderr, ", ");
2808 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2809 unsaved_files[i].Length);
2810 }
2811 fprintf(stderr, "],\n");
2812 fprintf(stderr, " 'options' : %d,\n", options);
2813 fprintf(stderr, "}\n");
2814
2815 return 0;
2816 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2817 PrintLibclangResourceUsage(PTUI.result);
2818 }
2819
2820 return PTUI.result;
2821}
2822
2823unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2824 return CXSaveTranslationUnit_None;
2825}
2826
2827namespace {
2828
2829struct SaveTranslationUnitInfo {
2830 CXTranslationUnit TU;
2831 const char *FileName;
2832 unsigned options;
2833 CXSaveError result;
2834};
2835
2836}
2837
2838static void clang_saveTranslationUnit_Impl(void *UserData) {
2839 SaveTranslationUnitInfo *STUI =
2840 static_cast<SaveTranslationUnitInfo*>(UserData);
2841
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002842 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002843 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2844 setThreadBackgroundPriority();
2845
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002846 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002847 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2848}
2849
2850int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2851 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002852 LOG_FUNC_SECTION {
2853 *Log << TU << ' ' << FileName;
2854 }
2855
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002856 if (!TU)
2857 return CXSaveError_InvalidTU;
2858
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002860 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2861 if (!CXXUnit->hasSema())
2862 return CXSaveError_InvalidTU;
2863
2864 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2865
2866 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2867 getenv("LIBCLANG_NOTHREADS")) {
2868 clang_saveTranslationUnit_Impl(&STUI);
2869
2870 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2871 PrintLibclangResourceUsage(TU);
2872
2873 return STUI.result;
2874 }
2875
2876 // We have an AST that has invalid nodes due to compiler errors.
2877 // Use a crash recovery thread for protection.
2878
2879 llvm::CrashRecoveryContext CRC;
2880
2881 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2882 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2883 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2884 fprintf(stderr, " 'options' : %d,\n", options);
2885 fprintf(stderr, "}\n");
2886
2887 return CXSaveError_Unknown;
2888
2889 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2890 PrintLibclangResourceUsage(TU);
2891 }
2892
2893 return STUI.result;
2894}
2895
2896void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2897 if (CTUnit) {
2898 // If the translation unit has been marked as unsafe to free, just discard
2899 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002900 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002901 return;
2902
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002903 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002904 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002905 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2906 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002907 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002908 delete CTUnit;
2909 }
2910}
2911
2912unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2913 return CXReparse_None;
2914}
2915
2916struct ReparseTranslationUnitInfo {
2917 CXTranslationUnit TU;
2918 unsigned num_unsaved_files;
2919 struct CXUnsavedFile *unsaved_files;
2920 unsigned options;
2921 int result;
2922};
2923
2924static void clang_reparseTranslationUnit_Impl(void *UserData) {
2925 ReparseTranslationUnitInfo *RTUI =
2926 static_cast<ReparseTranslationUnitInfo*>(UserData);
2927 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002928 if (!TU)
2929 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002930
2931 // Reset the associated diagnostics.
2932 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2933 TU->Diagnostics = 0;
2934
2935 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2936 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2937 unsigned options = RTUI->options;
2938 (void) options;
2939 RTUI->result = 1;
2940
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002941 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002942 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2943 setThreadBackgroundPriority();
2944
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002946 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2947
2948 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2949 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2950
2951 // Recover resources if we crash before exiting this function.
2952 llvm::CrashRecoveryContextCleanupRegistrar<
2953 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2954
2955 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2956 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2957 const llvm::MemoryBuffer *Buffer
2958 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2959 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2960 Buffer));
2961 }
2962
2963 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2964 RemappedFiles->size()))
2965 RTUI->result = 0;
2966}
2967
2968int clang_reparseTranslationUnit(CXTranslationUnit TU,
2969 unsigned num_unsaved_files,
2970 struct CXUnsavedFile *unsaved_files,
2971 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002972 LOG_FUNC_SECTION {
2973 *Log << TU;
2974 }
2975
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002976 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2977 options, 0 };
2978
2979 if (getenv("LIBCLANG_NOTHREADS")) {
2980 clang_reparseTranslationUnit_Impl(&RTUI);
2981 return RTUI.result;
2982 }
2983
2984 llvm::CrashRecoveryContext CRC;
2985
2986 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2987 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002988 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002989 return 1;
2990 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2991 PrintLibclangResourceUsage(TU);
2992
2993 return RTUI.result;
2994}
2995
2996
2997CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2998 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002999 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003000
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003001 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003002 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003003}
3004
3005CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003006 if (!TU)
3007 return clang_getNullCursor();
3008
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003010 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3011}
3012
3013} // end: extern "C"
3014
3015//===----------------------------------------------------------------------===//
3016// CXFile Operations.
3017//===----------------------------------------------------------------------===//
3018
3019extern "C" {
3020CXString clang_getFileName(CXFile SFile) {
3021 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00003022 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003023
3024 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003025 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003026}
3027
3028time_t clang_getFileTime(CXFile SFile) {
3029 if (!SFile)
3030 return 0;
3031
3032 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3033 return FEnt->getModificationTime();
3034}
3035
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003036CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3037 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003038 return 0;
3039
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003041
3042 FileManager &FMgr = CXXUnit->getFileManager();
3043 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3044}
3045
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003046unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3047 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003048 return 0;
3049
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003050 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 FileEntry *FEnt = static_cast<FileEntry *>(file);
3052 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3053 .isFileMultipleIncludeGuarded(FEnt);
3054}
3055
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003056int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3057 if (!file || !outID)
3058 return 1;
3059
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003060 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-08-01 21:42:11 +00003061 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3062 outID->data[0] = ID.getDevice();
3063 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003064 outID->data[2] = FEnt->getModificationTime();
3065 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003066}
3067
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003068} // end: extern "C"
3069
3070//===----------------------------------------------------------------------===//
3071// CXCursor Operations.
3072//===----------------------------------------------------------------------===//
3073
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003074static const Decl *getDeclFromExpr(const Stmt *E) {
3075 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003076 return getDeclFromExpr(CE->getSubExpr());
3077
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003078 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003079 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003080 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003081 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003082 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003083 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003084 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003085 if (PRE->isExplicitProperty())
3086 return PRE->getExplicitProperty();
3087 // It could be messaging both getter and setter as in:
3088 // ++myobj.myprop;
3089 // in which case prefer to associate the setter since it is less obvious
3090 // from inspecting the source that the setter is going to get called.
3091 if (PRE->isMessagingSetter())
3092 return PRE->getImplicitPropertySetter();
3093 return PRE->getImplicitPropertyGetter();
3094 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003095 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003096 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003097 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003098 if (Expr *Src = OVE->getSourceExpr())
3099 return getDeclFromExpr(Src);
3100
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003101 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003102 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003103 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003104 if (!CE->isElidable())
3105 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003106 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003107 return OME->getMethodDecl();
3108
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003109 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003110 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003111 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003112 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3113 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003114 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003115 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3116 isa<ParmVarDecl>(SizeOfPack->getPack()))
3117 return SizeOfPack->getPack();
3118
3119 return 0;
3120}
3121
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003122static SourceLocation getLocationFromExpr(const Expr *E) {
3123 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003124 return getLocationFromExpr(CE->getSubExpr());
3125
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003126 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003127 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003128 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003129 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003130 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003131 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003132 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003134 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003136 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003137 return PropRef->getLocation();
3138
3139 return E->getLocStart();
3140}
3141
3142extern "C" {
3143
3144unsigned clang_visitChildren(CXCursor parent,
3145 CXCursorVisitor visitor,
3146 CXClientData client_data) {
3147 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3148 /*VisitPreprocessorLast=*/false);
3149 return CursorVis.VisitChildren(parent);
3150}
3151
3152#ifndef __has_feature
3153#define __has_feature(x) 0
3154#endif
3155#if __has_feature(blocks)
3156typedef enum CXChildVisitResult
3157 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3158
3159static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3160 CXClientData client_data) {
3161 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3162 return block(cursor, parent);
3163}
3164#else
3165// If we are compiled with a compiler that doesn't have native blocks support,
3166// define and call the block manually, so the
3167typedef struct _CXChildVisitResult
3168{
3169 void *isa;
3170 int flags;
3171 int reserved;
3172 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3173 CXCursor);
3174} *CXCursorVisitorBlock;
3175
3176static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3177 CXClientData client_data) {
3178 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3179 return block->invoke(block, cursor, parent);
3180}
3181#endif
3182
3183
3184unsigned clang_visitChildrenWithBlock(CXCursor parent,
3185 CXCursorVisitorBlock block) {
3186 return clang_visitChildren(parent, visitWithBlock, block);
3187}
3188
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003189static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003190 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003191 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003193 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003194 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003195 if (const ObjCPropertyImplDecl *PropImpl =
3196 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003198 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003200 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003201 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003202 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003204 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205 }
3206
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003207 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003208 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003210 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003211 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3212 // and returns different names. NamedDecl returns the class name and
3213 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003214 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003215
3216 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003217 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003218
3219 SmallString<1024> S;
3220 llvm::raw_svector_ostream os(S);
3221 ND->printName(os);
3222
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003223 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003224}
3225
3226CXString clang_getCursorSpelling(CXCursor C) {
3227 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003228 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003229
3230 if (clang_isReference(C.kind)) {
3231 switch (C.kind) {
3232 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003233 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003234 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003235 }
3236 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003237 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003238 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003239 }
3240 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003241 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003243 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003244 }
3245 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003246 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003247 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003248 }
3249 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003250 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003251 assert(Type && "Missing type decl");
3252
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003253 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003254 getAsString());
3255 }
3256 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003257 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 assert(Template && "Missing template decl");
3259
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003260 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003261 }
3262
3263 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003264 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003265 assert(NS && "Missing namespace decl");
3266
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003267 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003268 }
3269
3270 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003271 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003272 assert(Field && "Missing member decl");
3273
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003274 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003275 }
3276
3277 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003278 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003279 assert(Label && "Missing label");
3280
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003281 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282 }
3283
3284 case CXCursor_OverloadedDeclRef: {
3285 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003286 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3287 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003288 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003289 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003290 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003291 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003292 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293 OverloadedTemplateStorage *Ovl
3294 = Storage.get<OverloadedTemplateStorage*>();
3295 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003297 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003298 }
3299
3300 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003301 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003302 assert(Var && "Missing variable decl");
3303
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003304 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003305 }
3306
3307 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003308 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003309 }
3310 }
3311
3312 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003313 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003314 if (D)
3315 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003316 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003317 }
3318
3319 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003320 const Stmt *S = getCursorStmt(C);
3321 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003322 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003323
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003325 }
3326
3327 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003328 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003329 ->getNameStart());
3330
3331 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003332 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003333 ->getNameStart());
3334
3335 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003336 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003337
3338 if (clang_isDeclaration(C.kind))
3339 return getDeclSpelling(getCursorDecl(C));
3340
3341 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003342 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003343 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003344 }
3345
3346 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003347 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003348 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003349 }
3350
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003351 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003352}
3353
3354CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3355 unsigned pieceIndex,
3356 unsigned options) {
3357 if (clang_Cursor_isNull(C))
3358 return clang_getNullRange();
3359
3360 ASTContext &Ctx = getCursorContext(C);
3361
3362 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003363 const Stmt *S = getCursorStmt(C);
3364 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003365 if (pieceIndex > 0)
3366 return clang_getNullRange();
3367 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3368 }
3369
3370 return clang_getNullRange();
3371 }
3372
3373 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003374 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003375 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3376 if (pieceIndex >= ME->getNumSelectorLocs())
3377 return clang_getNullRange();
3378 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3379 }
3380 }
3381
3382 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3383 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003384 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003385 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3386 if (pieceIndex >= MD->getNumSelectorLocs())
3387 return clang_getNullRange();
3388 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3389 }
3390 }
3391
3392 if (C.kind == CXCursor_ObjCCategoryDecl ||
3393 C.kind == CXCursor_ObjCCategoryImplDecl) {
3394 if (pieceIndex > 0)
3395 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003396 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003397 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3398 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003399 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003400 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3401 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3402 }
3403
3404 if (C.kind == CXCursor_ModuleImportDecl) {
3405 if (pieceIndex > 0)
3406 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003407 if (const ImportDecl *ImportD =
3408 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003409 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3410 if (!Locs.empty())
3411 return cxloc::translateSourceRange(Ctx,
3412 SourceRange(Locs.front(), Locs.back()));
3413 }
3414 return clang_getNullRange();
3415 }
3416
3417 // FIXME: A CXCursor_InclusionDirective should give the location of the
3418 // filename, but we don't keep track of this.
3419
3420 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3421 // but we don't keep track of this.
3422
3423 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3424 // but we don't keep track of this.
3425
3426 // Default handling, give the location of the cursor.
3427
3428 if (pieceIndex > 0)
3429 return clang_getNullRange();
3430
3431 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3432 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3433 return cxloc::translateSourceRange(Ctx, Loc);
3434}
3435
3436CXString clang_getCursorDisplayName(CXCursor C) {
3437 if (!clang_isDeclaration(C.kind))
3438 return clang_getCursorSpelling(C);
3439
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003440 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003441 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003442 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003443
3444 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003445 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003446 D = FunTmpl->getTemplatedDecl();
3447
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003448 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003449 SmallString<64> Str;
3450 llvm::raw_svector_ostream OS(Str);
3451 OS << *Function;
3452 if (Function->getPrimaryTemplate())
3453 OS << "<>";
3454 OS << "(";
3455 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3456 if (I)
3457 OS << ", ";
3458 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3459 }
3460
3461 if (Function->isVariadic()) {
3462 if (Function->getNumParams())
3463 OS << ", ";
3464 OS << "...";
3465 }
3466 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003467 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003468 }
3469
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003470 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 SmallString<64> Str;
3472 llvm::raw_svector_ostream OS(Str);
3473 OS << *ClassTemplate;
3474 OS << "<";
3475 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3476 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3477 if (I)
3478 OS << ", ";
3479
3480 NamedDecl *Param = Params->getParam(I);
3481 if (Param->getIdentifier()) {
3482 OS << Param->getIdentifier()->getName();
3483 continue;
3484 }
3485
3486 // There is no parameter name, which makes this tricky. Try to come up
3487 // with something useful that isn't too long.
3488 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3489 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3490 else if (NonTypeTemplateParmDecl *NTTP
3491 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3492 OS << NTTP->getType().getAsString(Policy);
3493 else
3494 OS << "template<...> class";
3495 }
3496
3497 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003498 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 }
3500
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003501 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003502 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3503 // If the type was explicitly written, use that.
3504 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003505 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003506
Benjamin Kramer5eada842013-02-22 15:46:01 +00003507 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003508 llvm::raw_svector_ostream OS(Str);
3509 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003510 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 ClassSpec->getTemplateArgs().data(),
3512 ClassSpec->getTemplateArgs().size(),
3513 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003514 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 }
3516
3517 return clang_getCursorSpelling(C);
3518}
3519
3520CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3521 switch (Kind) {
3522 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003523 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003524 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003525 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003526 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003650 case CXCursor_ObjCSelfExpr:
3651 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003739 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003740 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003741 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003742 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003743 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003744 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003745 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003746 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003747 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003748 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003749 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003750 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003751 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003752 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003753 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003754 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003755 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003756 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003757 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003758 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003759 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003760 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003761 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003762 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003763 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003764 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003765 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003766 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003767 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003768 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003769 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003770 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003771 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003772 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003773 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003774 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003775 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003776 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003777 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003778 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003779 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003780 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003781 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003782 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003783 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003784 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003786 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003788 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003789 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003790 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003791 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003792 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003793 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003794 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003795 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003797 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003798 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003799 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003801 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003802 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003803 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003804 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003805 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003806 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003807 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003808 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003810 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003812 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003813 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003814 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003815 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003816 case CXCursor_OMPParallelDirective:
3817 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003818 }
3819
3820 llvm_unreachable("Unhandled CXCursorKind");
3821}
3822
3823struct GetCursorData {
3824 SourceLocation TokenBeginLoc;
3825 bool PointsAtMacroArgExpansion;
3826 bool VisitedObjCPropertyImplDecl;
3827 SourceLocation VisitedDeclaratorDeclStartLoc;
3828 CXCursor &BestCursor;
3829
3830 GetCursorData(SourceManager &SM,
3831 SourceLocation tokenBegin, CXCursor &outputCursor)
3832 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3833 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3834 VisitedObjCPropertyImplDecl = false;
3835 }
3836};
3837
3838static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3839 CXCursor parent,
3840 CXClientData client_data) {
3841 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3842 CXCursor *BestCursor = &Data->BestCursor;
3843
3844 // If we point inside a macro argument we should provide info of what the
3845 // token is so use the actual cursor, don't replace it with a macro expansion
3846 // cursor.
3847 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3848 return CXChildVisit_Recurse;
3849
3850 if (clang_isDeclaration(cursor.kind)) {
3851 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003852 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003853 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3854 if (MD->isImplicit())
3855 return CXChildVisit_Break;
3856
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003857 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003858 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3859 // Check that when we have multiple @class references in the same line,
3860 // that later ones do not override the previous ones.
3861 // If we have:
3862 // @class Foo, Bar;
3863 // source ranges for both start at '@', so 'Bar' will end up overriding
3864 // 'Foo' even though the cursor location was at 'Foo'.
3865 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3866 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003867 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003868 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3869 if (PrevID != ID &&
3870 !PrevID->isThisDeclarationADefinition() &&
3871 !ID->isThisDeclarationADefinition())
3872 return CXChildVisit_Break;
3873 }
3874
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003875 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003876 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3877 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3878 // Check that when we have multiple declarators in the same line,
3879 // that later ones do not override the previous ones.
3880 // If we have:
3881 // int Foo, Bar;
3882 // source ranges for both start at 'int', so 'Bar' will end up overriding
3883 // 'Foo' even though the cursor location was at 'Foo'.
3884 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3885 return CXChildVisit_Break;
3886 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3887
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003888 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003889 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3890 (void)PropImp;
3891 // Check that when we have multiple @synthesize in the same line,
3892 // that later ones do not override the previous ones.
3893 // If we have:
3894 // @synthesize Foo, Bar;
3895 // source ranges for both start at '@', so 'Bar' will end up overriding
3896 // 'Foo' even though the cursor location was at 'Foo'.
3897 if (Data->VisitedObjCPropertyImplDecl)
3898 return CXChildVisit_Break;
3899 Data->VisitedObjCPropertyImplDecl = true;
3900 }
3901 }
3902
3903 if (clang_isExpression(cursor.kind) &&
3904 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003905 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003906 // Avoid having the cursor of an expression replace the declaration cursor
3907 // when the expression source range overlaps the declaration range.
3908 // This can happen for C++ constructor expressions whose range generally
3909 // include the variable declaration, e.g.:
3910 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3911 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3912 D->getLocation() == Data->TokenBeginLoc)
3913 return CXChildVisit_Break;
3914 }
3915 }
3916
3917 // If our current best cursor is the construction of a temporary object,
3918 // don't replace that cursor with a type reference, because we want
3919 // clang_getCursor() to point at the constructor.
3920 if (clang_isExpression(BestCursor->kind) &&
3921 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3922 cursor.kind == CXCursor_TypeRef) {
3923 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3924 // as having the actual point on the type reference.
3925 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3926 return CXChildVisit_Recurse;
3927 }
3928
3929 *BestCursor = cursor;
3930 return CXChildVisit_Recurse;
3931}
3932
3933CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3934 if (!TU)
3935 return clang_getNullCursor();
3936
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003937 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003938 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3939
3940 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3941 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3942
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003943 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003944 CXFile SearchFile;
3945 unsigned SearchLine, SearchColumn;
3946 CXFile ResultFile;
3947 unsigned ResultLine, ResultColumn;
3948 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3949 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3950 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3951
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003952 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3953 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003954 &ResultColumn, 0);
3955 SearchFileName = clang_getFileName(SearchFile);
3956 ResultFileName = clang_getFileName(ResultFile);
3957 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3958 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003959 *Log << llvm::format("(%s:%d:%d) = %s",
3960 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3961 clang_getCString(KindSpelling))
3962 << llvm::format("(%s:%d:%d):%s%s",
3963 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3964 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003965 clang_disposeString(SearchFileName);
3966 clang_disposeString(ResultFileName);
3967 clang_disposeString(KindSpelling);
3968 clang_disposeString(USR);
3969
3970 CXCursor Definition = clang_getCursorDefinition(Result);
3971 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3972 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3973 CXString DefinitionKindSpelling
3974 = clang_getCursorKindSpelling(Definition.kind);
3975 CXFile DefinitionFile;
3976 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003977 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003978 &DefinitionLine, &DefinitionColumn, 0);
3979 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003980 *Log << llvm::format(" -> %s(%s:%d:%d)",
3981 clang_getCString(DefinitionKindSpelling),
3982 clang_getCString(DefinitionFileName),
3983 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003984 clang_disposeString(DefinitionFileName);
3985 clang_disposeString(DefinitionKindSpelling);
3986 }
3987 }
3988
3989 return Result;
3990}
3991
3992CXCursor clang_getNullCursor(void) {
3993 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3994}
3995
3996unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003997 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3998 // can't set consistently. For example, when visiting a DeclStmt we will set
3999 // it but we don't set it on the result of clang_getCursorDefinition for
4000 // a reference of the same declaration.
4001 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4002 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4003 // to provide that kind of info.
4004 if (clang_isDeclaration(X.kind))
4005 X.data[1] = 0;
4006 if (clang_isDeclaration(Y.kind))
4007 Y.data[1] = 0;
4008
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004009 return X == Y;
4010}
4011
4012unsigned clang_hashCursor(CXCursor C) {
4013 unsigned Index = 0;
4014 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4015 Index = 1;
4016
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004017 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004018 std::make_pair(C.kind, C.data[Index]));
4019}
4020
4021unsigned clang_isInvalid(enum CXCursorKind K) {
4022 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4023}
4024
4025unsigned clang_isDeclaration(enum CXCursorKind K) {
4026 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4027 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4028}
4029
4030unsigned clang_isReference(enum CXCursorKind K) {
4031 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4032}
4033
4034unsigned clang_isExpression(enum CXCursorKind K) {
4035 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4036}
4037
4038unsigned clang_isStatement(enum CXCursorKind K) {
4039 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4040}
4041
4042unsigned clang_isAttribute(enum CXCursorKind K) {
4043 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4044}
4045
4046unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4047 return K == CXCursor_TranslationUnit;
4048}
4049
4050unsigned clang_isPreprocessing(enum CXCursorKind K) {
4051 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4052}
4053
4054unsigned clang_isUnexposed(enum CXCursorKind K) {
4055 switch (K) {
4056 case CXCursor_UnexposedDecl:
4057 case CXCursor_UnexposedExpr:
4058 case CXCursor_UnexposedStmt:
4059 case CXCursor_UnexposedAttr:
4060 return true;
4061 default:
4062 return false;
4063 }
4064}
4065
4066CXCursorKind clang_getCursorKind(CXCursor C) {
4067 return C.kind;
4068}
4069
4070CXSourceLocation clang_getCursorLocation(CXCursor C) {
4071 if (clang_isReference(C.kind)) {
4072 switch (C.kind) {
4073 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004074 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004075 = getCursorObjCSuperClassRef(C);
4076 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4077 }
4078
4079 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004080 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004081 = getCursorObjCProtocolRef(C);
4082 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4083 }
4084
4085 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004086 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004087 = getCursorObjCClassRef(C);
4088 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4089 }
4090
4091 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004092 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004093 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4094 }
4095
4096 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004097 std::pair<const TemplateDecl *, SourceLocation> P =
4098 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004099 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4100 }
4101
4102 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004103 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004104 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4105 }
4106
4107 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004108 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4110 }
4111
4112 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004113 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4115 }
4116
4117 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004118 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004119 if (!BaseSpec)
4120 return clang_getNullLocation();
4121
4122 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4123 return cxloc::translateSourceLocation(getCursorContext(C),
4124 TSInfo->getTypeLoc().getBeginLoc());
4125
4126 return cxloc::translateSourceLocation(getCursorContext(C),
4127 BaseSpec->getLocStart());
4128 }
4129
4130 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004131 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004132 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4133 }
4134
4135 case CXCursor_OverloadedDeclRef:
4136 return cxloc::translateSourceLocation(getCursorContext(C),
4137 getCursorOverloadedDeclRef(C).second);
4138
4139 default:
4140 // FIXME: Need a way to enumerate all non-reference cases.
4141 llvm_unreachable("Missed a reference kind");
4142 }
4143 }
4144
4145 if (clang_isExpression(C.kind))
4146 return cxloc::translateSourceLocation(getCursorContext(C),
4147 getLocationFromExpr(getCursorExpr(C)));
4148
4149 if (clang_isStatement(C.kind))
4150 return cxloc::translateSourceLocation(getCursorContext(C),
4151 getCursorStmt(C)->getLocStart());
4152
4153 if (C.kind == CXCursor_PreprocessingDirective) {
4154 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4155 return cxloc::translateSourceLocation(getCursorContext(C), L);
4156 }
4157
4158 if (C.kind == CXCursor_MacroExpansion) {
4159 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004160 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004161 return cxloc::translateSourceLocation(getCursorContext(C), L);
4162 }
4163
4164 if (C.kind == CXCursor_MacroDefinition) {
4165 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4166 return cxloc::translateSourceLocation(getCursorContext(C), L);
4167 }
4168
4169 if (C.kind == CXCursor_InclusionDirective) {
4170 SourceLocation L
4171 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4172 return cxloc::translateSourceLocation(getCursorContext(C), L);
4173 }
4174
4175 if (!clang_isDeclaration(C.kind))
4176 return clang_getNullLocation();
4177
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004178 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004179 if (!D)
4180 return clang_getNullLocation();
4181
4182 SourceLocation Loc = D->getLocation();
4183 // FIXME: Multiple variables declared in a single declaration
4184 // currently lack the information needed to correctly determine their
4185 // ranges when accounting for the type-specifier. We use context
4186 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4187 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004188 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004189 if (!cxcursor::isFirstInDeclGroup(C))
4190 Loc = VD->getLocation();
4191 }
4192
4193 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004194 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004195 Loc = MD->getSelectorStartLoc();
4196
4197 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4198}
4199
4200} // end extern "C"
4201
4202CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4203 assert(TU);
4204
4205 // Guard against an invalid SourceLocation, or we may assert in one
4206 // of the following calls.
4207 if (SLoc.isInvalid())
4208 return clang_getNullCursor();
4209
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004210 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004211
4212 // Translate the given source location to make it point at the beginning of
4213 // the token under the cursor.
4214 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4215 CXXUnit->getASTContext().getLangOpts());
4216
4217 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4218 if (SLoc.isValid()) {
4219 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4220 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4221 /*VisitPreprocessorLast=*/true,
4222 /*VisitIncludedEntities=*/false,
4223 SourceLocation(SLoc));
4224 CursorVis.visitFileRegion();
4225 }
4226
4227 return Result;
4228}
4229
4230static SourceRange getRawCursorExtent(CXCursor C) {
4231 if (clang_isReference(C.kind)) {
4232 switch (C.kind) {
4233 case CXCursor_ObjCSuperClassRef:
4234 return getCursorObjCSuperClassRef(C).second;
4235
4236 case CXCursor_ObjCProtocolRef:
4237 return getCursorObjCProtocolRef(C).second;
4238
4239 case CXCursor_ObjCClassRef:
4240 return getCursorObjCClassRef(C).second;
4241
4242 case CXCursor_TypeRef:
4243 return getCursorTypeRef(C).second;
4244
4245 case CXCursor_TemplateRef:
4246 return getCursorTemplateRef(C).second;
4247
4248 case CXCursor_NamespaceRef:
4249 return getCursorNamespaceRef(C).second;
4250
4251 case CXCursor_MemberRef:
4252 return getCursorMemberRef(C).second;
4253
4254 case CXCursor_CXXBaseSpecifier:
4255 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4256
4257 case CXCursor_LabelRef:
4258 return getCursorLabelRef(C).second;
4259
4260 case CXCursor_OverloadedDeclRef:
4261 return getCursorOverloadedDeclRef(C).second;
4262
4263 case CXCursor_VariableRef:
4264 return getCursorVariableRef(C).second;
4265
4266 default:
4267 // FIXME: Need a way to enumerate all non-reference cases.
4268 llvm_unreachable("Missed a reference kind");
4269 }
4270 }
4271
4272 if (clang_isExpression(C.kind))
4273 return getCursorExpr(C)->getSourceRange();
4274
4275 if (clang_isStatement(C.kind))
4276 return getCursorStmt(C)->getSourceRange();
4277
4278 if (clang_isAttribute(C.kind))
4279 return getCursorAttr(C)->getRange();
4280
4281 if (C.kind == CXCursor_PreprocessingDirective)
4282 return cxcursor::getCursorPreprocessingDirective(C);
4283
4284 if (C.kind == CXCursor_MacroExpansion) {
4285 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004286 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004287 return TU->mapRangeFromPreamble(Range);
4288 }
4289
4290 if (C.kind == CXCursor_MacroDefinition) {
4291 ASTUnit *TU = getCursorASTUnit(C);
4292 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4293 return TU->mapRangeFromPreamble(Range);
4294 }
4295
4296 if (C.kind == CXCursor_InclusionDirective) {
4297 ASTUnit *TU = getCursorASTUnit(C);
4298 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4299 return TU->mapRangeFromPreamble(Range);
4300 }
4301
4302 if (C.kind == CXCursor_TranslationUnit) {
4303 ASTUnit *TU = getCursorASTUnit(C);
4304 FileID MainID = TU->getSourceManager().getMainFileID();
4305 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4306 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4307 return SourceRange(Start, End);
4308 }
4309
4310 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004311 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004312 if (!D)
4313 return SourceRange();
4314
4315 SourceRange R = D->getSourceRange();
4316 // FIXME: Multiple variables declared in a single declaration
4317 // currently lack the information needed to correctly determine their
4318 // ranges when accounting for the type-specifier. We use context
4319 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4320 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004321 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004322 if (!cxcursor::isFirstInDeclGroup(C))
4323 R.setBegin(VD->getLocation());
4324 }
4325 return R;
4326 }
4327 return SourceRange();
4328}
4329
4330/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4331/// the decl-specifier-seq for declarations.
4332static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4333 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004334 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004335 if (!D)
4336 return SourceRange();
4337
4338 SourceRange R = D->getSourceRange();
4339
4340 // Adjust the start of the location for declarations preceded by
4341 // declaration specifiers.
4342 SourceLocation StartLoc;
4343 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4344 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4345 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004346 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004347 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4348 StartLoc = TI->getTypeLoc().getLocStart();
4349 }
4350
4351 if (StartLoc.isValid() && R.getBegin().isValid() &&
4352 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4353 R.setBegin(StartLoc);
4354
4355 // FIXME: Multiple variables declared in a single declaration
4356 // currently lack the information needed to correctly determine their
4357 // ranges when accounting for the type-specifier. We use context
4358 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4359 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004360 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004361 if (!cxcursor::isFirstInDeclGroup(C))
4362 R.setBegin(VD->getLocation());
4363 }
4364
4365 return R;
4366 }
4367
4368 return getRawCursorExtent(C);
4369}
4370
4371extern "C" {
4372
4373CXSourceRange clang_getCursorExtent(CXCursor C) {
4374 SourceRange R = getRawCursorExtent(C);
4375 if (R.isInvalid())
4376 return clang_getNullRange();
4377
4378 return cxloc::translateSourceRange(getCursorContext(C), R);
4379}
4380
4381CXCursor clang_getCursorReferenced(CXCursor C) {
4382 if (clang_isInvalid(C.kind))
4383 return clang_getNullCursor();
4384
4385 CXTranslationUnit tu = getCursorTU(C);
4386 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004387 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004388 if (!D)
4389 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004390 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004391 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004392 if (const ObjCPropertyImplDecl *PropImpl =
4393 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004394 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4395 return MakeCXCursor(Property, tu);
4396
4397 return C;
4398 }
4399
4400 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004401 const Expr *E = getCursorExpr(C);
4402 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004403 if (D) {
4404 CXCursor declCursor = MakeCXCursor(D, tu);
4405 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4406 declCursor);
4407 return declCursor;
4408 }
4409
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004410 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004411 return MakeCursorOverloadedDeclRef(Ovl, tu);
4412
4413 return clang_getNullCursor();
4414 }
4415
4416 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004417 const Stmt *S = getCursorStmt(C);
4418 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004419 if (LabelDecl *label = Goto->getLabel())
4420 if (LabelStmt *labelS = label->getStmt())
4421 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4422
4423 return clang_getNullCursor();
4424 }
4425
4426 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004427 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004428 return MakeMacroDefinitionCursor(Def, tu);
4429 }
4430
4431 if (!clang_isReference(C.kind))
4432 return clang_getNullCursor();
4433
4434 switch (C.kind) {
4435 case CXCursor_ObjCSuperClassRef:
4436 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4437
4438 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004439 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4440 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004441 return MakeCXCursor(Def, tu);
4442
4443 return MakeCXCursor(Prot, tu);
4444 }
4445
4446 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004447 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4448 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004449 return MakeCXCursor(Def, tu);
4450
4451 return MakeCXCursor(Class, tu);
4452 }
4453
4454 case CXCursor_TypeRef:
4455 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4456
4457 case CXCursor_TemplateRef:
4458 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4459
4460 case CXCursor_NamespaceRef:
4461 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4462
4463 case CXCursor_MemberRef:
4464 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4465
4466 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004467 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004468 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4469 tu ));
4470 }
4471
4472 case CXCursor_LabelRef:
4473 // FIXME: We end up faking the "parent" declaration here because we
4474 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004475 return MakeCXCursor(getCursorLabelRef(C).first,
4476 cxtu::getASTUnit(tu)->getASTContext()
4477 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004478 tu);
4479
4480 case CXCursor_OverloadedDeclRef:
4481 return C;
4482
4483 case CXCursor_VariableRef:
4484 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4485
4486 default:
4487 // We would prefer to enumerate all non-reference cursor kinds here.
4488 llvm_unreachable("Unhandled reference cursor kind");
4489 }
4490}
4491
4492CXCursor clang_getCursorDefinition(CXCursor C) {
4493 if (clang_isInvalid(C.kind))
4494 return clang_getNullCursor();
4495
4496 CXTranslationUnit TU = getCursorTU(C);
4497
4498 bool WasReference = false;
4499 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4500 C = clang_getCursorReferenced(C);
4501 WasReference = true;
4502 }
4503
4504 if (C.kind == CXCursor_MacroExpansion)
4505 return clang_getCursorReferenced(C);
4506
4507 if (!clang_isDeclaration(C.kind))
4508 return clang_getNullCursor();
4509
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004510 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004511 if (!D)
4512 return clang_getNullCursor();
4513
4514 switch (D->getKind()) {
4515 // Declaration kinds that don't really separate the notions of
4516 // declaration and definition.
4517 case Decl::Namespace:
4518 case Decl::Typedef:
4519 case Decl::TypeAlias:
4520 case Decl::TypeAliasTemplate:
4521 case Decl::TemplateTypeParm:
4522 case Decl::EnumConstant:
4523 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004524 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004525 case Decl::IndirectField:
4526 case Decl::ObjCIvar:
4527 case Decl::ObjCAtDefsField:
4528 case Decl::ImplicitParam:
4529 case Decl::ParmVar:
4530 case Decl::NonTypeTemplateParm:
4531 case Decl::TemplateTemplateParm:
4532 case Decl::ObjCCategoryImpl:
4533 case Decl::ObjCImplementation:
4534 case Decl::AccessSpec:
4535 case Decl::LinkageSpec:
4536 case Decl::ObjCPropertyImpl:
4537 case Decl::FileScopeAsm:
4538 case Decl::StaticAssert:
4539 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004540 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004541 case Decl::Label: // FIXME: Is this right??
4542 case Decl::ClassScopeFunctionSpecialization:
4543 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004544 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004545 return C;
4546
4547 // Declaration kinds that don't make any sense here, but are
4548 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004549 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004550 case Decl::TranslationUnit:
4551 break;
4552
4553 // Declaration kinds for which the definition is not resolvable.
4554 case Decl::UnresolvedUsingTypename:
4555 case Decl::UnresolvedUsingValue:
4556 break;
4557
4558 case Decl::UsingDirective:
4559 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4560 TU);
4561
4562 case Decl::NamespaceAlias:
4563 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4564
4565 case Decl::Enum:
4566 case Decl::Record:
4567 case Decl::CXXRecord:
4568 case Decl::ClassTemplateSpecialization:
4569 case Decl::ClassTemplatePartialSpecialization:
4570 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4571 return MakeCXCursor(Def, TU);
4572 return clang_getNullCursor();
4573
4574 case Decl::Function:
4575 case Decl::CXXMethod:
4576 case Decl::CXXConstructor:
4577 case Decl::CXXDestructor:
4578 case Decl::CXXConversion: {
4579 const FunctionDecl *Def = 0;
4580 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004581 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004582 return clang_getNullCursor();
4583 }
4584
Larisse Voufoef4579c2013-08-06 01:03:05 +00004585 case Decl::Var:
4586 case Decl::VarTemplateSpecialization:
4587 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004588 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004589 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004590 return MakeCXCursor(Def, TU);
4591 return clang_getNullCursor();
4592 }
4593
4594 case Decl::FunctionTemplate: {
4595 const FunctionDecl *Def = 0;
4596 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4597 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4598 return clang_getNullCursor();
4599 }
4600
4601 case Decl::ClassTemplate: {
4602 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4603 ->getDefinition())
4604 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4605 TU);
4606 return clang_getNullCursor();
4607 }
4608
Larisse Voufoef4579c2013-08-06 01:03:05 +00004609 case Decl::VarTemplate: {
4610 if (VarDecl *Def =
4611 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4612 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4613 return clang_getNullCursor();
4614 }
4615
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004616 case Decl::Using:
4617 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4618 D->getLocation(), TU);
4619
4620 case Decl::UsingShadow:
4621 return clang_getCursorDefinition(
4622 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4623 TU));
4624
4625 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004626 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004627 if (Method->isThisDeclarationADefinition())
4628 return C;
4629
4630 // Dig out the method definition in the associated
4631 // @implementation, if we have it.
4632 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004633 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004634 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4635 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4636 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4637 Method->isInstanceMethod()))
4638 if (Def->isThisDeclarationADefinition())
4639 return MakeCXCursor(Def, TU);
4640
4641 return clang_getNullCursor();
4642 }
4643
4644 case Decl::ObjCCategory:
4645 if (ObjCCategoryImplDecl *Impl
4646 = cast<ObjCCategoryDecl>(D)->getImplementation())
4647 return MakeCXCursor(Impl, TU);
4648 return clang_getNullCursor();
4649
4650 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004651 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004652 return MakeCXCursor(Def, TU);
4653 return clang_getNullCursor();
4654
4655 case Decl::ObjCInterface: {
4656 // There are two notions of a "definition" for an Objective-C
4657 // class: the interface and its implementation. When we resolved a
4658 // reference to an Objective-C class, produce the @interface as
4659 // the definition; when we were provided with the interface,
4660 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004661 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004662 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004663 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004664 return MakeCXCursor(Def, TU);
4665 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4666 return MakeCXCursor(Impl, TU);
4667 return clang_getNullCursor();
4668 }
4669
4670 case Decl::ObjCProperty:
4671 // FIXME: We don't really know where to find the
4672 // ObjCPropertyImplDecls that implement this property.
4673 return clang_getNullCursor();
4674
4675 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004676 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004677 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004678 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004679 return MakeCXCursor(Def, TU);
4680
4681 return clang_getNullCursor();
4682
4683 case Decl::Friend:
4684 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4685 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4686 return clang_getNullCursor();
4687
4688 case Decl::FriendTemplate:
4689 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4690 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4691 return clang_getNullCursor();
4692 }
4693
4694 return clang_getNullCursor();
4695}
4696
4697unsigned clang_isCursorDefinition(CXCursor C) {
4698 if (!clang_isDeclaration(C.kind))
4699 return 0;
4700
4701 return clang_getCursorDefinition(C) == C;
4702}
4703
4704CXCursor clang_getCanonicalCursor(CXCursor C) {
4705 if (!clang_isDeclaration(C.kind))
4706 return C;
4707
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004708 if (const Decl *D = getCursorDecl(C)) {
4709 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004710 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4711 return MakeCXCursor(CatD, getCursorTU(C));
4712
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004713 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4714 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004715 return MakeCXCursor(IFD, getCursorTU(C));
4716
4717 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4718 }
4719
4720 return C;
4721}
4722
4723int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4724 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4725}
4726
4727unsigned clang_getNumOverloadedDecls(CXCursor C) {
4728 if (C.kind != CXCursor_OverloadedDeclRef)
4729 return 0;
4730
4731 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004732 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004733 return E->getNumDecls();
4734
4735 if (OverloadedTemplateStorage *S
4736 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4737 return S->size();
4738
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004739 const Decl *D = Storage.get<const Decl *>();
4740 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004741 return Using->shadow_size();
4742
4743 return 0;
4744}
4745
4746CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4747 if (cursor.kind != CXCursor_OverloadedDeclRef)
4748 return clang_getNullCursor();
4749
4750 if (index >= clang_getNumOverloadedDecls(cursor))
4751 return clang_getNullCursor();
4752
4753 CXTranslationUnit TU = getCursorTU(cursor);
4754 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004755 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004756 return MakeCXCursor(E->decls_begin()[index], TU);
4757
4758 if (OverloadedTemplateStorage *S
4759 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4760 return MakeCXCursor(S->begin()[index], TU);
4761
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004762 const Decl *D = Storage.get<const Decl *>();
4763 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004764 // FIXME: This is, unfortunately, linear time.
4765 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4766 std::advance(Pos, index);
4767 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4768 }
4769
4770 return clang_getNullCursor();
4771}
4772
4773void clang_getDefinitionSpellingAndExtent(CXCursor C,
4774 const char **startBuf,
4775 const char **endBuf,
4776 unsigned *startLine,
4777 unsigned *startColumn,
4778 unsigned *endLine,
4779 unsigned *endColumn) {
4780 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004781 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004782 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4783
4784 SourceManager &SM = FD->getASTContext().getSourceManager();
4785 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4786 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4787 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4788 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4789 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4790 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4791}
4792
4793
4794CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4795 unsigned PieceIndex) {
4796 RefNamePieces Pieces;
4797
4798 switch (C.kind) {
4799 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004800 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004801 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4802 E->getQualifierLoc().getSourceRange());
4803 break;
4804
4805 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004806 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004807 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4808 E->getQualifierLoc().getSourceRange(),
4809 E->getOptionalExplicitTemplateArgs());
4810 break;
4811
4812 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004813 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004814 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004815 const Expr *Callee = OCE->getCallee();
4816 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004817 Callee = ICE->getSubExpr();
4818
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004819 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004820 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4821 DRE->getQualifierLoc().getSourceRange());
4822 }
4823 break;
4824
4825 default:
4826 break;
4827 }
4828
4829 if (Pieces.empty()) {
4830 if (PieceIndex == 0)
4831 return clang_getCursorExtent(C);
4832 } else if (PieceIndex < Pieces.size()) {
4833 SourceRange R = Pieces[PieceIndex];
4834 if (R.isValid())
4835 return cxloc::translateSourceRange(getCursorContext(C), R);
4836 }
4837
4838 return clang_getNullRange();
4839}
4840
4841void clang_enableStackTraces(void) {
4842 llvm::sys::PrintStackTraceOnErrorSignal();
4843}
4844
4845void clang_executeOnThread(void (*fn)(void*), void *user_data,
4846 unsigned stack_size) {
4847 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4848}
4849
4850} // end: extern "C"
4851
4852//===----------------------------------------------------------------------===//
4853// Token-based Operations.
4854//===----------------------------------------------------------------------===//
4855
4856/* CXToken layout:
4857 * int_data[0]: a CXTokenKind
4858 * int_data[1]: starting token location
4859 * int_data[2]: token length
4860 * int_data[3]: reserved
4861 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4862 * otherwise unused.
4863 */
4864extern "C" {
4865
4866CXTokenKind clang_getTokenKind(CXToken CXTok) {
4867 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4868}
4869
4870CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4871 switch (clang_getTokenKind(CXTok)) {
4872 case CXToken_Identifier:
4873 case CXToken_Keyword:
4874 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004875 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004876 ->getNameStart());
4877
4878 case CXToken_Literal: {
4879 // We have stashed the starting pointer in the ptr_data field. Use it.
4880 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004881 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004882 }
4883
4884 case CXToken_Punctuation:
4885 case CXToken_Comment:
4886 break;
4887 }
4888
4889 // We have to find the starting buffer pointer the hard way, by
4890 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004891 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004892 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004893 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004894
4895 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4896 std::pair<FileID, unsigned> LocInfo
4897 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4898 bool Invalid = false;
4899 StringRef Buffer
4900 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4901 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004902 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004903
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004904 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004905}
4906
4907CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004908 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004909 if (!CXXUnit)
4910 return clang_getNullLocation();
4911
4912 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4913 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4914}
4915
4916CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004917 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004918 if (!CXXUnit)
4919 return clang_getNullRange();
4920
4921 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4922 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4923}
4924
4925static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4926 SmallVectorImpl<CXToken> &CXTokens) {
4927 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4928 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004929 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004930 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004931 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004932
4933 // Cannot tokenize across files.
4934 if (BeginLocInfo.first != EndLocInfo.first)
4935 return;
4936
4937 // Create a lexer
4938 bool Invalid = false;
4939 StringRef Buffer
4940 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4941 if (Invalid)
4942 return;
4943
4944 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4945 CXXUnit->getASTContext().getLangOpts(),
4946 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4947 Lex.SetCommentRetentionState(true);
4948
4949 // Lex tokens until we hit the end of the range.
4950 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4951 Token Tok;
4952 bool previousWasAt = false;
4953 do {
4954 // Lex the next token
4955 Lex.LexFromRawLexer(Tok);
4956 if (Tok.is(tok::eof))
4957 break;
4958
4959 // Initialize the CXToken.
4960 CXToken CXTok;
4961
4962 // - Common fields
4963 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4964 CXTok.int_data[2] = Tok.getLength();
4965 CXTok.int_data[3] = 0;
4966
4967 // - Kind-specific fields
4968 if (Tok.isLiteral()) {
4969 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004970 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004971 } else if (Tok.is(tok::raw_identifier)) {
4972 // Lookup the identifier to determine whether we have a keyword.
4973 IdentifierInfo *II
4974 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4975
4976 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4977 CXTok.int_data[0] = CXToken_Keyword;
4978 }
4979 else {
4980 CXTok.int_data[0] = Tok.is(tok::identifier)
4981 ? CXToken_Identifier
4982 : CXToken_Keyword;
4983 }
4984 CXTok.ptr_data = II;
4985 } else if (Tok.is(tok::comment)) {
4986 CXTok.int_data[0] = CXToken_Comment;
4987 CXTok.ptr_data = 0;
4988 } else {
4989 CXTok.int_data[0] = CXToken_Punctuation;
4990 CXTok.ptr_data = 0;
4991 }
4992 CXTokens.push_back(CXTok);
4993 previousWasAt = Tok.is(tok::at);
4994 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4995}
4996
4997void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4998 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004999 LOG_FUNC_SECTION {
5000 *Log << TU << ' ' << Range;
5001 }
5002
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005003 if (Tokens)
5004 *Tokens = 0;
5005 if (NumTokens)
5006 *NumTokens = 0;
5007
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005008 if (!TU)
5009 return;
5010
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005011 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005012 if (!CXXUnit || !Tokens || !NumTokens)
5013 return;
5014
5015 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5016
5017 SourceRange R = cxloc::translateCXSourceRange(Range);
5018 if (R.isInvalid())
5019 return;
5020
5021 SmallVector<CXToken, 32> CXTokens;
5022 getTokens(CXXUnit, R, CXTokens);
5023
5024 if (CXTokens.empty())
5025 return;
5026
5027 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5028 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5029 *NumTokens = CXTokens.size();
5030}
5031
5032void clang_disposeTokens(CXTranslationUnit TU,
5033 CXToken *Tokens, unsigned NumTokens) {
5034 free(Tokens);
5035}
5036
5037} // end: extern "C"
5038
5039//===----------------------------------------------------------------------===//
5040// Token annotation APIs.
5041//===----------------------------------------------------------------------===//
5042
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005043static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5044 CXCursor parent,
5045 CXClientData client_data);
5046static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5047 CXClientData client_data);
5048
5049namespace {
5050class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005051 CXToken *Tokens;
5052 CXCursor *Cursors;
5053 unsigned NumTokens;
5054 unsigned TokIdx;
5055 unsigned PreprocessingTokIdx;
5056 CursorVisitor AnnotateVis;
5057 SourceManager &SrcMgr;
5058 bool HasContextSensitiveKeywords;
5059
5060 struct PostChildrenInfo {
5061 CXCursor Cursor;
5062 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005063 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005064 unsigned BeforeChildrenTokenIdx;
5065 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005066 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005067
5068 bool MoreTokens() const { return TokIdx < NumTokens; }
5069 unsigned NextToken() const { return TokIdx; }
5070 void AdvanceToken() { ++TokIdx; }
5071 SourceLocation GetTokenLoc(unsigned tokI) {
5072 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5073 }
5074 bool isFunctionMacroToken(unsigned tokI) const {
5075 return Tokens[tokI].int_data[3] != 0;
5076 }
5077 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5078 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5079 }
5080
5081 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005082 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005083 SourceRange);
5084
5085public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005086 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005087 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005088 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005089 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005090 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005091 AnnotateTokensVisitor, this,
5092 /*VisitPreprocessorLast=*/true,
5093 /*VisitIncludedEntities=*/false,
5094 RegionOfInterest,
5095 /*VisitDeclsOnly=*/false,
5096 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005097 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005098 HasContextSensitiveKeywords(false) { }
5099
5100 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5101 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5102 bool postVisitChildren(CXCursor cursor);
5103 void AnnotateTokens();
5104
5105 /// \brief Determine whether the annotator saw any cursors that have
5106 /// context-sensitive keywords.
5107 bool hasContextSensitiveKeywords() const {
5108 return HasContextSensitiveKeywords;
5109 }
5110
5111 ~AnnotateTokensWorker() {
5112 assert(PostChildrenInfos.empty());
5113 }
5114};
5115}
5116
5117void AnnotateTokensWorker::AnnotateTokens() {
5118 // Walk the AST within the region of interest, annotating tokens
5119 // along the way.
5120 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005121}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005122
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005123static inline void updateCursorAnnotation(CXCursor &Cursor,
5124 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005125 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005126 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005127 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005128}
5129
5130/// \brief It annotates and advances tokens with a cursor until the comparison
5131//// between the cursor location and the source range is the same as
5132/// \arg compResult.
5133///
5134/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5135/// Pass RangeOverlap to annotate tokens inside a range.
5136void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5137 RangeComparisonResult compResult,
5138 SourceRange range) {
5139 while (MoreTokens()) {
5140 const unsigned I = NextToken();
5141 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005142 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5143 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005144
5145 SourceLocation TokLoc = GetTokenLoc(I);
5146 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005147 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005148 AdvanceToken();
5149 continue;
5150 }
5151 break;
5152 }
5153}
5154
5155/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005156/// \returns true if it advanced beyond all macro tokens, false otherwise.
5157bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005158 CXCursor updateC,
5159 RangeComparisonResult compResult,
5160 SourceRange range) {
5161 assert(MoreTokens());
5162 assert(isFunctionMacroToken(NextToken()) &&
5163 "Should be called only for macro arg tokens");
5164
5165 // This works differently than annotateAndAdvanceTokens; because expanded
5166 // macro arguments can have arbitrary translation-unit source order, we do not
5167 // advance the token index one by one until a token fails the range test.
5168 // We only advance once past all of the macro arg tokens if all of them
5169 // pass the range test. If one of them fails we keep the token index pointing
5170 // at the start of the macro arg tokens so that the failing token will be
5171 // annotated by a subsequent annotation try.
5172
5173 bool atLeastOneCompFail = false;
5174
5175 unsigned I = NextToken();
5176 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5177 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5178 if (TokLoc.isFileID())
5179 continue; // not macro arg token, it's parens or comma.
5180 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5181 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5182 Cursors[I] = updateC;
5183 } else
5184 atLeastOneCompFail = true;
5185 }
5186
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005187 if (atLeastOneCompFail)
5188 return false;
5189
5190 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5191 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005192}
5193
5194enum CXChildVisitResult
5195AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005196 SourceRange cursorRange = getRawCursorExtent(cursor);
5197 if (cursorRange.isInvalid())
5198 return CXChildVisit_Recurse;
5199
5200 if (!HasContextSensitiveKeywords) {
5201 // Objective-C properties can have context-sensitive keywords.
5202 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005203 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005204 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5205 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5206 }
5207 // Objective-C methods can have context-sensitive keywords.
5208 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5209 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005210 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005211 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5212 if (Method->getObjCDeclQualifier())
5213 HasContextSensitiveKeywords = true;
5214 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005215 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5216 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005217 P != PEnd; ++P) {
5218 if ((*P)->getObjCDeclQualifier()) {
5219 HasContextSensitiveKeywords = true;
5220 break;
5221 }
5222 }
5223 }
5224 }
5225 }
5226 // C++ methods can have context-sensitive keywords.
5227 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005228 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005229 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5230 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5231 HasContextSensitiveKeywords = true;
5232 }
5233 }
5234 // C++ classes can have context-sensitive keywords.
5235 else if (cursor.kind == CXCursor_StructDecl ||
5236 cursor.kind == CXCursor_ClassDecl ||
5237 cursor.kind == CXCursor_ClassTemplate ||
5238 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005239 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005240 if (D->hasAttr<FinalAttr>())
5241 HasContextSensitiveKeywords = true;
5242 }
5243 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005244
5245 // Don't override a property annotation with its getter/setter method.
5246 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5247 parent.kind == CXCursor_ObjCPropertyDecl)
5248 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005249
5250 if (clang_isPreprocessing(cursor.kind)) {
5251 // Items in the preprocessing record are kept separate from items in
5252 // declarations, so we keep a separate token index.
5253 unsigned SavedTokIdx = TokIdx;
5254 TokIdx = PreprocessingTokIdx;
5255
5256 // Skip tokens up until we catch up to the beginning of the preprocessing
5257 // entry.
5258 while (MoreTokens()) {
5259 const unsigned I = NextToken();
5260 SourceLocation TokLoc = GetTokenLoc(I);
5261 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5262 case RangeBefore:
5263 AdvanceToken();
5264 continue;
5265 case RangeAfter:
5266 case RangeOverlap:
5267 break;
5268 }
5269 break;
5270 }
5271
5272 // Look at all of the tokens within this range.
5273 while (MoreTokens()) {
5274 const unsigned I = NextToken();
5275 SourceLocation TokLoc = GetTokenLoc(I);
5276 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5277 case RangeBefore:
5278 llvm_unreachable("Infeasible");
5279 case RangeAfter:
5280 break;
5281 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005282 // For macro expansions, just note where the beginning of the macro
5283 // expansion occurs.
5284 if (cursor.kind == CXCursor_MacroExpansion) {
5285 if (TokLoc == cursorRange.getBegin())
5286 Cursors[I] = cursor;
5287 AdvanceToken();
5288 break;
5289 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005290 // We may have already annotated macro names inside macro definitions.
5291 if (Cursors[I].kind != CXCursor_MacroExpansion)
5292 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005293 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005294 continue;
5295 }
5296 break;
5297 }
5298
5299 // Save the preprocessing token index; restore the non-preprocessing
5300 // token index.
5301 PreprocessingTokIdx = TokIdx;
5302 TokIdx = SavedTokIdx;
5303 return CXChildVisit_Recurse;
5304 }
5305
5306 if (cursorRange.isInvalid())
5307 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005308
5309 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005310 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005311 const enum CXCursorKind K = clang_getCursorKind(parent);
5312 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005313 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5314 // Attributes are annotated out-of-order, skip tokens until we reach it.
5315 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005316 ? clang_getNullCursor() : parent;
5317
5318 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5319
5320 // Avoid having the cursor of an expression "overwrite" the annotation of the
5321 // variable declaration that it belongs to.
5322 // This can happen for C++ constructor expressions whose range generally
5323 // include the variable declaration, e.g.:
5324 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5325 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005326 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005327 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005328 const unsigned I = NextToken();
5329 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5330 E->getLocStart() == D->getLocation() &&
5331 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005332 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005333 AdvanceToken();
5334 }
5335 }
5336 }
5337
5338 // Before recursing into the children keep some state that we are going
5339 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5340 // extra work after the child nodes are visited.
5341 // Note that we don't call VisitChildren here to avoid traversing statements
5342 // code-recursively which can blow the stack.
5343
5344 PostChildrenInfo Info;
5345 Info.Cursor = cursor;
5346 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005347 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005348 Info.BeforeChildrenTokenIdx = NextToken();
5349 PostChildrenInfos.push_back(Info);
5350
5351 return CXChildVisit_Recurse;
5352}
5353
5354bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5355 if (PostChildrenInfos.empty())
5356 return false;
5357 const PostChildrenInfo &Info = PostChildrenInfos.back();
5358 if (!clang_equalCursors(Info.Cursor, cursor))
5359 return false;
5360
5361 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5362 const unsigned AfterChildren = NextToken();
5363 SourceRange cursorRange = Info.CursorRange;
5364
5365 // Scan the tokens that are at the end of the cursor, but are not captured
5366 // but the child cursors.
5367 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5368
5369 // Scan the tokens that are at the beginning of the cursor, but are not
5370 // capture by the child cursors.
5371 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5372 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5373 break;
5374
5375 Cursors[I] = cursor;
5376 }
5377
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005378 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5379 // encountered the attribute cursor.
5380 if (clang_isAttribute(cursor.kind))
5381 TokIdx = Info.BeforeReachingCursorIdx;
5382
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005383 PostChildrenInfos.pop_back();
5384 return false;
5385}
5386
5387static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5388 CXCursor parent,
5389 CXClientData client_data) {
5390 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5391}
5392
5393static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5394 CXClientData client_data) {
5395 return static_cast<AnnotateTokensWorker*>(client_data)->
5396 postVisitChildren(cursor);
5397}
5398
5399namespace {
5400
5401/// \brief Uses the macro expansions in the preprocessing record to find
5402/// and mark tokens that are macro arguments. This info is used by the
5403/// AnnotateTokensWorker.
5404class MarkMacroArgTokensVisitor {
5405 SourceManager &SM;
5406 CXToken *Tokens;
5407 unsigned NumTokens;
5408 unsigned CurIdx;
5409
5410public:
5411 MarkMacroArgTokensVisitor(SourceManager &SM,
5412 CXToken *tokens, unsigned numTokens)
5413 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5414
5415 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5416 if (cursor.kind != CXCursor_MacroExpansion)
5417 return CXChildVisit_Continue;
5418
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005419 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005420 if (macroRange.getBegin() == macroRange.getEnd())
5421 return CXChildVisit_Continue; // it's not a function macro.
5422
5423 for (; CurIdx < NumTokens; ++CurIdx) {
5424 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5425 macroRange.getBegin()))
5426 break;
5427 }
5428
5429 if (CurIdx == NumTokens)
5430 return CXChildVisit_Break;
5431
5432 for (; CurIdx < NumTokens; ++CurIdx) {
5433 SourceLocation tokLoc = getTokenLoc(CurIdx);
5434 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5435 break;
5436
5437 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5438 }
5439
5440 if (CurIdx == NumTokens)
5441 return CXChildVisit_Break;
5442
5443 return CXChildVisit_Continue;
5444 }
5445
5446private:
5447 SourceLocation getTokenLoc(unsigned tokI) {
5448 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5449 }
5450
5451 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5452 // The third field is reserved and currently not used. Use it here
5453 // to mark macro arg expanded tokens with their expanded locations.
5454 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5455 }
5456};
5457
5458} // end anonymous namespace
5459
5460static CXChildVisitResult
5461MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5462 CXClientData client_data) {
5463 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5464 parent);
5465}
5466
5467namespace {
5468 struct clang_annotateTokens_Data {
5469 CXTranslationUnit TU;
5470 ASTUnit *CXXUnit;
5471 CXToken *Tokens;
5472 unsigned NumTokens;
5473 CXCursor *Cursors;
5474 };
5475}
5476
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005477/// \brief Used by \c annotatePreprocessorTokens.
5478/// \returns true if lexing was finished, false otherwise.
5479static bool lexNext(Lexer &Lex, Token &Tok,
5480 unsigned &NextIdx, unsigned NumTokens) {
5481 if (NextIdx >= NumTokens)
5482 return true;
5483
5484 ++NextIdx;
5485 Lex.LexFromRawLexer(Tok);
5486 if (Tok.is(tok::eof))
5487 return true;
5488
5489 return false;
5490}
5491
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005492static void annotatePreprocessorTokens(CXTranslationUnit TU,
5493 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005494 CXCursor *Cursors,
5495 CXToken *Tokens,
5496 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005497 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005498
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005499 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005500 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5501 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005502 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005503 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005504 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005505
5506 if (BeginLocInfo.first != EndLocInfo.first)
5507 return;
5508
5509 StringRef Buffer;
5510 bool Invalid = false;
5511 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5512 if (Buffer.empty() || Invalid)
5513 return;
5514
5515 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5516 CXXUnit->getASTContext().getLangOpts(),
5517 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5518 Buffer.end());
5519 Lex.SetCommentRetentionState(true);
5520
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005521 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005522 // Lex tokens in raw mode until we hit the end of the range, to avoid
5523 // entering #includes or expanding macros.
5524 while (true) {
5525 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005526 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5527 break;
5528 unsigned TokIdx = NextIdx-1;
5529 assert(Tok.getLocation() ==
5530 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005531
5532 reprocess:
5533 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005534 // We have found a preprocessing directive. Annotate the tokens
5535 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005536 //
5537 // FIXME: Some simple tests here could identify macro definitions and
5538 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005539
5540 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005541 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5542 break;
5543
5544 MacroInfo *MI = 0;
5545 if (Tok.is(tok::raw_identifier) &&
5546 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5547 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5548 break;
5549
5550 if (Tok.is(tok::raw_identifier)) {
5551 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5552 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5553 SourceLocation MappedTokLoc =
5554 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5555 MI = getMacroInfo(II, MappedTokLoc, TU);
5556 }
5557 }
5558
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005559 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005560 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005561 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5562 finished = true;
5563 break;
5564 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005565 // If we are in a macro definition, check if the token was ever a
5566 // macro name and annotate it if that's the case.
5567 if (MI) {
5568 SourceLocation SaveLoc = Tok.getLocation();
5569 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5570 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5571 Tok.setLocation(SaveLoc);
5572 if (MacroDef)
5573 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5574 Tok.getLocation(), TU);
5575 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005576 } while (!Tok.isAtStartOfLine());
5577
5578 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5579 assert(TokIdx <= LastIdx);
5580 SourceLocation EndLoc =
5581 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5582 CXCursor Cursor =
5583 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5584
5585 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005586 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005587
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005588 if (finished)
5589 break;
5590 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005591 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005592 }
5593}
5594
5595// This gets run a separate thread to avoid stack blowout.
5596static void clang_annotateTokensImpl(void *UserData) {
5597 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5598 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5599 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5600 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5601 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5602
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005603 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005604 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5605 setThreadBackgroundPriority();
5606
5607 // Determine the region of interest, which contains all of the tokens.
5608 SourceRange RegionOfInterest;
5609 RegionOfInterest.setBegin(
5610 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5611 RegionOfInterest.setEnd(
5612 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5613 Tokens[NumTokens-1])));
5614
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005615 // Relex the tokens within the source range to look for preprocessing
5616 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005617 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005618
5619 // If begin location points inside a macro argument, set it to the expansion
5620 // location so we can have the full context when annotating semantically.
5621 {
5622 SourceManager &SM = CXXUnit->getSourceManager();
5623 SourceLocation Loc =
5624 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5625 if (Loc.isMacroID())
5626 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5627 }
5628
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005629 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5630 // Search and mark tokens that are macro argument expansions.
5631 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5632 Tokens, NumTokens);
5633 CursorVisitor MacroArgMarker(TU,
5634 MarkMacroArgTokensVisitorDelegate, &Visitor,
5635 /*VisitPreprocessorLast=*/true,
5636 /*VisitIncludedEntities=*/false,
5637 RegionOfInterest);
5638 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5639 }
5640
5641 // Annotate all of the source locations in the region of interest that map to
5642 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005643 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005644
5645 // FIXME: We use a ridiculous stack size here because the data-recursion
5646 // algorithm uses a large stack frame than the non-data recursive version,
5647 // and AnnotationTokensWorker currently transforms the data-recursion
5648 // algorithm back into a traditional recursion by explicitly calling
5649 // VisitChildren(). We will need to remove this explicit recursive call.
5650 W.AnnotateTokens();
5651
5652 // If we ran into any entities that involve context-sensitive keywords,
5653 // take another pass through the tokens to mark them as such.
5654 if (W.hasContextSensitiveKeywords()) {
5655 for (unsigned I = 0; I != NumTokens; ++I) {
5656 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5657 continue;
5658
5659 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5660 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005661 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005662 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5663 if (Property->getPropertyAttributesAsWritten() != 0 &&
5664 llvm::StringSwitch<bool>(II->getName())
5665 .Case("readonly", true)
5666 .Case("assign", true)
5667 .Case("unsafe_unretained", true)
5668 .Case("readwrite", true)
5669 .Case("retain", true)
5670 .Case("copy", true)
5671 .Case("nonatomic", true)
5672 .Case("atomic", true)
5673 .Case("getter", true)
5674 .Case("setter", true)
5675 .Case("strong", true)
5676 .Case("weak", true)
5677 .Default(false))
5678 Tokens[I].int_data[0] = CXToken_Keyword;
5679 }
5680 continue;
5681 }
5682
5683 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5684 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5685 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5686 if (llvm::StringSwitch<bool>(II->getName())
5687 .Case("in", true)
5688 .Case("out", true)
5689 .Case("inout", true)
5690 .Case("oneway", true)
5691 .Case("bycopy", true)
5692 .Case("byref", true)
5693 .Default(false))
5694 Tokens[I].int_data[0] = CXToken_Keyword;
5695 continue;
5696 }
5697
5698 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5699 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5700 Tokens[I].int_data[0] = CXToken_Keyword;
5701 continue;
5702 }
5703 }
5704 }
5705}
5706
5707extern "C" {
5708
5709void clang_annotateTokens(CXTranslationUnit TU,
5710 CXToken *Tokens, unsigned NumTokens,
5711 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005712 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005713 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005714 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005715 }
5716
5717 LOG_FUNC_SECTION {
5718 *Log << TU << ' ';
5719 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5720 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5721 *Log << clang_getRange(bloc, eloc);
5722 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005723
5724 // Any token we don't specifically annotate will have a NULL cursor.
5725 CXCursor C = clang_getNullCursor();
5726 for (unsigned I = 0; I != NumTokens; ++I)
5727 Cursors[I] = C;
5728
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005729 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005730 if (!CXXUnit)
5731 return;
5732
5733 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5734
5735 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5736 llvm::CrashRecoveryContext CRC;
5737 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5738 GetSafetyThreadStackSize() * 2)) {
5739 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5740 }
5741}
5742
5743} // end: extern "C"
5744
5745//===----------------------------------------------------------------------===//
5746// Operations for querying linkage of a cursor.
5747//===----------------------------------------------------------------------===//
5748
5749extern "C" {
5750CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5751 if (!clang_isDeclaration(cursor.kind))
5752 return CXLinkage_Invalid;
5753
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005754 const Decl *D = cxcursor::getCursorDecl(cursor);
5755 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005756 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005757 case NoLinkage:
5758 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005759 case InternalLinkage: return CXLinkage_Internal;
5760 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5761 case ExternalLinkage: return CXLinkage_External;
5762 };
5763
5764 return CXLinkage_Invalid;
5765}
5766} // end: extern "C"
5767
5768//===----------------------------------------------------------------------===//
5769// Operations for querying language of a cursor.
5770//===----------------------------------------------------------------------===//
5771
5772static CXLanguageKind getDeclLanguage(const Decl *D) {
5773 if (!D)
5774 return CXLanguage_C;
5775
5776 switch (D->getKind()) {
5777 default:
5778 break;
5779 case Decl::ImplicitParam:
5780 case Decl::ObjCAtDefsField:
5781 case Decl::ObjCCategory:
5782 case Decl::ObjCCategoryImpl:
5783 case Decl::ObjCCompatibleAlias:
5784 case Decl::ObjCImplementation:
5785 case Decl::ObjCInterface:
5786 case Decl::ObjCIvar:
5787 case Decl::ObjCMethod:
5788 case Decl::ObjCProperty:
5789 case Decl::ObjCPropertyImpl:
5790 case Decl::ObjCProtocol:
5791 return CXLanguage_ObjC;
5792 case Decl::CXXConstructor:
5793 case Decl::CXXConversion:
5794 case Decl::CXXDestructor:
5795 case Decl::CXXMethod:
5796 case Decl::CXXRecord:
5797 case Decl::ClassTemplate:
5798 case Decl::ClassTemplatePartialSpecialization:
5799 case Decl::ClassTemplateSpecialization:
5800 case Decl::Friend:
5801 case Decl::FriendTemplate:
5802 case Decl::FunctionTemplate:
5803 case Decl::LinkageSpec:
5804 case Decl::Namespace:
5805 case Decl::NamespaceAlias:
5806 case Decl::NonTypeTemplateParm:
5807 case Decl::StaticAssert:
5808 case Decl::TemplateTemplateParm:
5809 case Decl::TemplateTypeParm:
5810 case Decl::UnresolvedUsingTypename:
5811 case Decl::UnresolvedUsingValue:
5812 case Decl::Using:
5813 case Decl::UsingDirective:
5814 case Decl::UsingShadow:
5815 return CXLanguage_CPlusPlus;
5816 }
5817
5818 return CXLanguage_C;
5819}
5820
5821extern "C" {
5822
5823enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5824 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005825 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005826 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5827 return CXAvailability_Available;
5828
5829 switch (D->getAvailability()) {
5830 case AR_Available:
5831 case AR_NotYetIntroduced:
5832 return CXAvailability_Available;
5833
5834 case AR_Deprecated:
5835 return CXAvailability_Deprecated;
5836
5837 case AR_Unavailable:
5838 return CXAvailability_NotAvailable;
5839 }
5840 }
5841
5842 return CXAvailability_Available;
5843}
5844
5845static CXVersion convertVersion(VersionTuple In) {
5846 CXVersion Out = { -1, -1, -1 };
5847 if (In.empty())
5848 return Out;
5849
5850 Out.Major = In.getMajor();
5851
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005852 Optional<unsigned> Minor = In.getMinor();
5853 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005854 Out.Minor = *Minor;
5855 else
5856 return Out;
5857
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005858 Optional<unsigned> Subminor = In.getSubminor();
5859 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005860 Out.Subminor = *Subminor;
5861
5862 return Out;
5863}
5864
5865int clang_getCursorPlatformAvailability(CXCursor cursor,
5866 int *always_deprecated,
5867 CXString *deprecated_message,
5868 int *always_unavailable,
5869 CXString *unavailable_message,
5870 CXPlatformAvailability *availability,
5871 int availability_size) {
5872 if (always_deprecated)
5873 *always_deprecated = 0;
5874 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005875 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005876 if (always_unavailable)
5877 *always_unavailable = 0;
5878 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005879 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005880
5881 if (!clang_isDeclaration(cursor.kind))
5882 return 0;
5883
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005884 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005885 if (!D)
5886 return 0;
5887
5888 int N = 0;
5889 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5890 ++A) {
5891 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5892 if (always_deprecated)
5893 *always_deprecated = 1;
5894 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005895 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005896 continue;
5897 }
5898
5899 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5900 if (always_unavailable)
5901 *always_unavailable = 1;
5902 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005903 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005904 }
5905 continue;
5906 }
5907
5908 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5909 if (N < availability_size) {
5910 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005911 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005912 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5913 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5914 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5915 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005916 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005917 }
5918 ++N;
5919 }
5920 }
5921
5922 return N;
5923}
5924
5925void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5926 clang_disposeString(availability->Platform);
5927 clang_disposeString(availability->Message);
5928}
5929
5930CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5931 if (clang_isDeclaration(cursor.kind))
5932 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5933
5934 return CXLanguage_Invalid;
5935}
5936
5937 /// \brief If the given cursor is the "templated" declaration
5938 /// descibing a class or function template, return the class or
5939 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005940static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005941 if (!D)
5942 return 0;
5943
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005944 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005945 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5946 return FunTmpl;
5947
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005948 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005949 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5950 return ClassTmpl;
5951
5952 return D;
5953}
5954
5955CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5956 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005957 if (const Decl *D = getCursorDecl(cursor)) {
5958 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005959 if (!DC)
5960 return clang_getNullCursor();
5961
5962 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5963 getCursorTU(cursor));
5964 }
5965 }
5966
5967 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005968 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005969 return MakeCXCursor(D, getCursorTU(cursor));
5970 }
5971
5972 return clang_getNullCursor();
5973}
5974
5975CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5976 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005977 if (const Decl *D = getCursorDecl(cursor)) {
5978 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005979 if (!DC)
5980 return clang_getNullCursor();
5981
5982 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5983 getCursorTU(cursor));
5984 }
5985 }
5986
5987 // FIXME: Note that we can't easily compute the lexical context of a
5988 // statement or expression, so we return nothing.
5989 return clang_getNullCursor();
5990}
5991
5992CXFile clang_getIncludedFile(CXCursor cursor) {
5993 if (cursor.kind != CXCursor_InclusionDirective)
5994 return 0;
5995
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005996 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005997 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005998}
5999
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00006000unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6001 if (C.kind != CXCursor_ObjCPropertyDecl)
6002 return CXObjCPropertyAttr_noattr;
6003
6004 unsigned Result = CXObjCPropertyAttr_noattr;
6005 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6006 ObjCPropertyDecl::PropertyAttributeKind Attr =
6007 PD->getPropertyAttributesAsWritten();
6008
6009#define SET_CXOBJCPROP_ATTR(A) \
6010 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6011 Result |= CXObjCPropertyAttr_##A
6012 SET_CXOBJCPROP_ATTR(readonly);
6013 SET_CXOBJCPROP_ATTR(getter);
6014 SET_CXOBJCPROP_ATTR(assign);
6015 SET_CXOBJCPROP_ATTR(readwrite);
6016 SET_CXOBJCPROP_ATTR(retain);
6017 SET_CXOBJCPROP_ATTR(copy);
6018 SET_CXOBJCPROP_ATTR(nonatomic);
6019 SET_CXOBJCPROP_ATTR(setter);
6020 SET_CXOBJCPROP_ATTR(atomic);
6021 SET_CXOBJCPROP_ATTR(weak);
6022 SET_CXOBJCPROP_ATTR(strong);
6023 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6024#undef SET_CXOBJCPROP_ATTR
6025
6026 return Result;
6027}
6028
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006029unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6030 if (!clang_isDeclaration(C.kind))
6031 return CXObjCDeclQualifier_None;
6032
6033 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6034 const Decl *D = getCursorDecl(C);
6035 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6036 QT = MD->getObjCDeclQualifier();
6037 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6038 QT = PD->getObjCDeclQualifier();
6039 if (QT == Decl::OBJC_TQ_None)
6040 return CXObjCDeclQualifier_None;
6041
6042 unsigned Result = CXObjCDeclQualifier_None;
6043 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6044 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6045 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6046 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6047 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6048 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6049
6050 return Result;
6051}
6052
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006053unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6054 if (!clang_isDeclaration(C.kind))
6055 return 0;
6056
6057 const Decl *D = getCursorDecl(C);
6058 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6059 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6060 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6061 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6062
6063 return 0;
6064}
6065
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006066unsigned clang_Cursor_isVariadic(CXCursor C) {
6067 if (!clang_isDeclaration(C.kind))
6068 return 0;
6069
6070 const Decl *D = getCursorDecl(C);
6071 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6072 return FD->isVariadic();
6073 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6074 return MD->isVariadic();
6075
6076 return 0;
6077}
6078
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006079CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6080 if (!clang_isDeclaration(C.kind))
6081 return clang_getNullRange();
6082
6083 const Decl *D = getCursorDecl(C);
6084 ASTContext &Context = getCursorContext(C);
6085 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6086 if (!RC)
6087 return clang_getNullRange();
6088
6089 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6090}
6091
6092CXString clang_Cursor_getRawCommentText(CXCursor C) {
6093 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006094 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006095
6096 const Decl *D = getCursorDecl(C);
6097 ASTContext &Context = getCursorContext(C);
6098 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6099 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6100 StringRef();
6101
6102 // Don't duplicate the string because RawText points directly into source
6103 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006104 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006105}
6106
6107CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6108 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006109 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006110
6111 const Decl *D = getCursorDecl(C);
6112 const ASTContext &Context = getCursorContext(C);
6113 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6114
6115 if (RC) {
6116 StringRef BriefText = RC->getBriefText(Context);
6117
6118 // Don't duplicate the string because RawComment ensures that this memory
6119 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006120 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006121 }
6122
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006123 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006124}
6125
6126CXComment clang_Cursor_getParsedComment(CXCursor C) {
6127 if (!clang_isDeclaration(C.kind))
6128 return cxcomment::createCXComment(NULL, NULL);
6129
6130 const Decl *D = getCursorDecl(C);
6131 const ASTContext &Context = getCursorContext(C);
6132 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6133
6134 return cxcomment::createCXComment(FC, getCursorTU(C));
6135}
6136
6137CXModule clang_Cursor_getModule(CXCursor C) {
6138 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006139 if (const ImportDecl *ImportD =
6140 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006141 return ImportD->getImportedModule();
6142 }
6143
6144 return 0;
6145}
6146
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006147CXFile clang_Module_getASTFile(CXModule CXMod) {
6148 if (!CXMod)
6149 return 0;
6150 Module *Mod = static_cast<Module*>(CXMod);
6151 return const_cast<FileEntry *>(Mod->getASTFile());
6152}
6153
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006154CXModule clang_Module_getParent(CXModule CXMod) {
6155 if (!CXMod)
6156 return 0;
6157 Module *Mod = static_cast<Module*>(CXMod);
6158 return Mod->Parent;
6159}
6160
6161CXString clang_Module_getName(CXModule CXMod) {
6162 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006163 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006164 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006165 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006166}
6167
6168CXString clang_Module_getFullName(CXModule CXMod) {
6169 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006170 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006171 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006172 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006173}
6174
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006175unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6176 CXModule CXMod) {
6177 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006178 return 0;
6179 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006180 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6181 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6182 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006183}
6184
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006185CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6186 CXModule CXMod, unsigned Index) {
6187 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006188 return 0;
6189 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006190 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006191
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006192 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6193 if (Index < TopHeaders.size())
6194 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006195
6196 return 0;
6197}
6198
6199} // end: extern "C"
6200
6201//===----------------------------------------------------------------------===//
6202// C++ AST instrospection.
6203//===----------------------------------------------------------------------===//
6204
6205extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006206unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6207 if (!clang_isDeclaration(C.kind))
6208 return 0;
6209
6210 const CXXMethodDecl *Method = 0;
6211 const Decl *D = cxcursor::getCursorDecl(C);
6212 if (const FunctionTemplateDecl *FunTmpl =
6213 dyn_cast_or_null<FunctionTemplateDecl>(D))
6214 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6215 else
6216 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6217 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6218}
6219
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006220unsigned clang_CXXMethod_isStatic(CXCursor C) {
6221 if (!clang_isDeclaration(C.kind))
6222 return 0;
6223
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006224 const CXXMethodDecl *Method = 0;
6225 const Decl *D = cxcursor::getCursorDecl(C);
6226 if (const FunctionTemplateDecl *FunTmpl =
6227 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006228 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6229 else
6230 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6231 return (Method && Method->isStatic()) ? 1 : 0;
6232}
6233
6234unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6235 if (!clang_isDeclaration(C.kind))
6236 return 0;
6237
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006238 const CXXMethodDecl *Method = 0;
6239 const Decl *D = cxcursor::getCursorDecl(C);
6240 if (const FunctionTemplateDecl *FunTmpl =
6241 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006242 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6243 else
6244 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6245 return (Method && Method->isVirtual()) ? 1 : 0;
6246}
6247} // end: extern "C"
6248
6249//===----------------------------------------------------------------------===//
6250// Attribute introspection.
6251//===----------------------------------------------------------------------===//
6252
6253extern "C" {
6254CXType clang_getIBOutletCollectionType(CXCursor C) {
6255 if (C.kind != CXCursor_IBOutletCollectionAttr)
6256 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6257
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006258 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006259 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6260
6261 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6262}
6263} // end: extern "C"
6264
6265//===----------------------------------------------------------------------===//
6266// Inspecting memory usage.
6267//===----------------------------------------------------------------------===//
6268
6269typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6270
6271static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6272 enum CXTUResourceUsageKind k,
6273 unsigned long amount) {
6274 CXTUResourceUsageEntry entry = { k, amount };
6275 entries.push_back(entry);
6276}
6277
6278extern "C" {
6279
6280const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6281 const char *str = "";
6282 switch (kind) {
6283 case CXTUResourceUsage_AST:
6284 str = "ASTContext: expressions, declarations, and types";
6285 break;
6286 case CXTUResourceUsage_Identifiers:
6287 str = "ASTContext: identifiers";
6288 break;
6289 case CXTUResourceUsage_Selectors:
6290 str = "ASTContext: selectors";
6291 break;
6292 case CXTUResourceUsage_GlobalCompletionResults:
6293 str = "Code completion: cached global results";
6294 break;
6295 case CXTUResourceUsage_SourceManagerContentCache:
6296 str = "SourceManager: content cache allocator";
6297 break;
6298 case CXTUResourceUsage_AST_SideTables:
6299 str = "ASTContext: side tables";
6300 break;
6301 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6302 str = "SourceManager: malloc'ed memory buffers";
6303 break;
6304 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6305 str = "SourceManager: mmap'ed memory buffers";
6306 break;
6307 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6308 str = "ExternalASTSource: malloc'ed memory buffers";
6309 break;
6310 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6311 str = "ExternalASTSource: mmap'ed memory buffers";
6312 break;
6313 case CXTUResourceUsage_Preprocessor:
6314 str = "Preprocessor: malloc'ed memory";
6315 break;
6316 case CXTUResourceUsage_PreprocessingRecord:
6317 str = "Preprocessor: PreprocessingRecord";
6318 break;
6319 case CXTUResourceUsage_SourceManager_DataStructures:
6320 str = "SourceManager: data structures and tables";
6321 break;
6322 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6323 str = "Preprocessor: header search tables";
6324 break;
6325 }
6326 return str;
6327}
6328
6329CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6330 if (!TU) {
6331 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6332 return usage;
6333 }
6334
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006335 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006336 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6337 ASTContext &astContext = astUnit->getASTContext();
6338
6339 // How much memory is used by AST nodes and types?
6340 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6341 (unsigned long) astContext.getASTAllocatedMemory());
6342
6343 // How much memory is used by identifiers?
6344 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6345 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6346
6347 // How much memory is used for selectors?
6348 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6349 (unsigned long) astContext.Selectors.getTotalMemory());
6350
6351 // How much memory is used by ASTContext's side tables?
6352 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6353 (unsigned long) astContext.getSideTableAllocatedMemory());
6354
6355 // How much memory is used for caching global code completion results?
6356 unsigned long completionBytes = 0;
6357 if (GlobalCodeCompletionAllocator *completionAllocator =
6358 astUnit->getCachedCompletionAllocator().getPtr()) {
6359 completionBytes = completionAllocator->getTotalMemory();
6360 }
6361 createCXTUResourceUsageEntry(*entries,
6362 CXTUResourceUsage_GlobalCompletionResults,
6363 completionBytes);
6364
6365 // How much memory is being used by SourceManager's content cache?
6366 createCXTUResourceUsageEntry(*entries,
6367 CXTUResourceUsage_SourceManagerContentCache,
6368 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6369
6370 // How much memory is being used by the MemoryBuffer's in SourceManager?
6371 const SourceManager::MemoryBufferSizes &srcBufs =
6372 astUnit->getSourceManager().getMemoryBufferSizes();
6373
6374 createCXTUResourceUsageEntry(*entries,
6375 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6376 (unsigned long) srcBufs.malloc_bytes);
6377 createCXTUResourceUsageEntry(*entries,
6378 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6379 (unsigned long) srcBufs.mmap_bytes);
6380 createCXTUResourceUsageEntry(*entries,
6381 CXTUResourceUsage_SourceManager_DataStructures,
6382 (unsigned long) astContext.getSourceManager()
6383 .getDataStructureSizes());
6384
6385 // How much memory is being used by the ExternalASTSource?
6386 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6387 const ExternalASTSource::MemoryBufferSizes &sizes =
6388 esrc->getMemoryBufferSizes();
6389
6390 createCXTUResourceUsageEntry(*entries,
6391 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6392 (unsigned long) sizes.malloc_bytes);
6393 createCXTUResourceUsageEntry(*entries,
6394 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6395 (unsigned long) sizes.mmap_bytes);
6396 }
6397
6398 // How much memory is being used by the Preprocessor?
6399 Preprocessor &pp = astUnit->getPreprocessor();
6400 createCXTUResourceUsageEntry(*entries,
6401 CXTUResourceUsage_Preprocessor,
6402 pp.getTotalMemory());
6403
6404 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6405 createCXTUResourceUsageEntry(*entries,
6406 CXTUResourceUsage_PreprocessingRecord,
6407 pRec->getTotalMemory());
6408 }
6409
6410 createCXTUResourceUsageEntry(*entries,
6411 CXTUResourceUsage_Preprocessor_HeaderSearch,
6412 pp.getHeaderSearchInfo().getTotalMemory());
6413
6414 CXTUResourceUsage usage = { (void*) entries.get(),
6415 (unsigned) entries->size(),
6416 entries->size() ? &(*entries)[0] : 0 };
6417 entries.take();
6418 return usage;
6419}
6420
6421void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6422 if (usage.data)
6423 delete (MemUsageEntries*) usage.data;
6424}
6425
6426} // end extern "C"
6427
6428void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6429 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6430 for (unsigned I = 0; I != Usage.numEntries; ++I)
6431 fprintf(stderr, " %s: %lu\n",
6432 clang_getTUResourceUsageName(Usage.entries[I].kind),
6433 Usage.entries[I].amount);
6434
6435 clang_disposeCXTUResourceUsage(Usage);
6436}
6437
6438//===----------------------------------------------------------------------===//
6439// Misc. utility functions.
6440//===----------------------------------------------------------------------===//
6441
6442/// Default to using an 8 MB stack size on "safety" threads.
6443static unsigned SafetyStackThreadSize = 8 << 20;
6444
6445namespace clang {
6446
6447bool RunSafely(llvm::CrashRecoveryContext &CRC,
6448 void (*Fn)(void*), void *UserData,
6449 unsigned Size) {
6450 if (!Size)
6451 Size = GetSafetyThreadStackSize();
6452 if (Size)
6453 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6454 return CRC.RunSafely(Fn, UserData);
6455}
6456
6457unsigned GetSafetyThreadStackSize() {
6458 return SafetyStackThreadSize;
6459}
6460
6461void SetSafetyThreadStackSize(unsigned Value) {
6462 SafetyStackThreadSize = Value;
6463}
6464
6465}
6466
6467void clang::setThreadBackgroundPriority() {
6468 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6469 return;
6470
6471 // FIXME: Move to llvm/Support and make it cross-platform.
6472#ifdef __APPLE__
6473 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6474#endif
6475}
6476
6477void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6478 if (!Unit)
6479 return;
6480
6481 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6482 DEnd = Unit->stored_diag_end();
6483 D != DEnd; ++D) {
6484 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6485 CXString Msg = clang_formatDiagnostic(&Diag,
6486 clang_defaultDiagnosticDisplayOptions());
6487 fprintf(stderr, "%s\n", clang_getCString(Msg));
6488 clang_disposeString(Msg);
6489 }
6490#ifdef LLVM_ON_WIN32
6491 // On Windows, force a flush, since there may be multiple copies of
6492 // stderr and stdout in the file system, all with different buffers
6493 // but writing to the same device.
6494 fflush(stderr);
6495#endif
6496}
6497
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006498MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6499 SourceLocation MacroDefLoc,
6500 CXTranslationUnit TU){
6501 if (MacroDefLoc.isInvalid() || !TU)
6502 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006503 if (!II.hadMacroDefinition())
6504 return 0;
6505
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006506 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006507 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006508 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006509 if (MD) {
6510 for (MacroDirective::DefInfo
6511 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6512 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6513 return Def.getMacroInfo();
6514 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006515 }
6516
6517 return 0;
6518}
6519
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006520const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6521 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006522 if (!MacroDef || !TU)
6523 return 0;
6524 const IdentifierInfo *II = MacroDef->getName();
6525 if (!II)
6526 return 0;
6527
6528 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6529}
6530
6531MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6532 const Token &Tok,
6533 CXTranslationUnit TU) {
6534 if (!MI || !TU)
6535 return 0;
6536 if (Tok.isNot(tok::raw_identifier))
6537 return 0;
6538
6539 if (MI->getNumTokens() == 0)
6540 return 0;
6541 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6542 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006543 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006544
6545 // Check that the token is inside the definition and not its argument list.
6546 SourceManager &SM = Unit->getSourceManager();
6547 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6548 return 0;
6549 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6550 return 0;
6551
6552 Preprocessor &PP = Unit->getPreprocessor();
6553 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6554 if (!PPRec)
6555 return 0;
6556
6557 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6558 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6559 if (!II.hadMacroDefinition())
6560 return 0;
6561
6562 // Check that the identifier is not one of the macro arguments.
6563 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6564 return 0;
6565
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006566 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6567 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006568 return 0;
6569
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006570 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006571}
6572
6573MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6574 SourceLocation Loc,
6575 CXTranslationUnit TU) {
6576 if (Loc.isInvalid() || !MI || !TU)
6577 return 0;
6578
6579 if (MI->getNumTokens() == 0)
6580 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006581 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006582 Preprocessor &PP = Unit->getPreprocessor();
6583 if (!PP.getPreprocessingRecord())
6584 return 0;
6585 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6586 Token Tok;
6587 if (PP.getRawToken(Loc, Tok))
6588 return 0;
6589
6590 return checkForMacroInMacroDefinition(MI, Tok, TU);
6591}
6592
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006593extern "C" {
6594
6595CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006596 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006597}
6598
6599} // end: extern "C"
6600
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006601Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6602 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006603 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006604 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006605 if (Unit->isMainFileAST())
6606 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006607 return *this;
6608 }
6609 }
6610
6611 LogOS << "<NULL TU>";
6612 return *this;
6613}
6614
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006615Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6616 *this << FE->getName();
6617 return *this;
6618}
6619
6620Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6621 CXString cursorName = clang_getCursorDisplayName(cursor);
6622 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6623 clang_disposeString(cursorName);
6624 return *this;
6625}
6626
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006627Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6628 CXFile File;
6629 unsigned Line, Column;
6630 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6631 CXString FileName = clang_getFileName(File);
6632 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6633 clang_disposeString(FileName);
6634 return *this;
6635}
6636
6637Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6638 CXSourceLocation BLoc = clang_getRangeStart(range);
6639 CXSourceLocation ELoc = clang_getRangeEnd(range);
6640
6641 CXFile BFile;
6642 unsigned BLine, BColumn;
6643 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6644
6645 CXFile EFile;
6646 unsigned ELine, EColumn;
6647 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6648
6649 CXString BFileName = clang_getFileName(BFile);
6650 if (BFile == EFile) {
6651 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6652 BLine, BColumn, ELine, EColumn);
6653 } else {
6654 CXString EFileName = clang_getFileName(EFile);
6655 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6656 BLine, BColumn)
6657 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6658 ELine, EColumn);
6659 clang_disposeString(EFileName);
6660 }
6661 clang_disposeString(BFileName);
6662 return *this;
6663}
6664
6665Logger &cxindex::Logger::operator<<(CXString Str) {
6666 *this << clang_getCString(Str);
6667 return *this;
6668}
6669
6670Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6671 LogOS << Fmt;
6672 return *this;
6673}
6674
6675cxindex::Logger::~Logger() {
6676 LogOS.flush();
6677
6678 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6679
6680 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6681
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006682 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006683 OS << "[libclang:" << Name << ':';
6684
6685 // FIXME: Portability.
6686#if HAVE_PTHREAD_H && __APPLE__
6687 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6688 OS << tid << ':';
6689#endif
6690
6691 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6692 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6693 OS << Msg.str() << '\n';
6694
6695 if (Trace) {
6696 llvm::sys::PrintStackTrace(stderr);
6697 OS << "--------------------------------------------------\n";
6698 }
6699}