blob: c30f937e1a89ad79fd87b3c212694fd16145eac2 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
Fariborz Jahanian9b7ab872012-12-18 23:02:59 +000025#include "SimpleFormatContext.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000026#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000027#include "clang/AST/StmtVisitor.h"
28#include "clang/Basic/Diagnostic.h"
29#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
33#include "clang/Lex/HeaderSearch.h"
34#include "clang/Lex/Lexer.h"
35#include "clang/Lex/PreprocessingRecord.h"
36#include "clang/Lex/Preprocessor.h"
37#include "llvm/ADT/Optional.h"
38#include "llvm/ADT/STLExtras.h"
39#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000040#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/Support/Compiler.h"
42#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/MemoryBuffer.h"
45#include "llvm/Support/Mutex.h"
46#include "llvm/Support/PrettyStackTrace.h"
47#include "llvm/Support/Program.h"
48#include "llvm/Support/SaveAndRestore.h"
49#include "llvm/Support/Signals.h"
50#include "llvm/Support/Threading.h"
51#include "llvm/Support/Timer.h"
52#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000053
54#if HAVE_PTHREAD_H
55#include <pthread.h>
56#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000057
58using namespace clang;
59using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000060using namespace clang::cxtu;
61using namespace clang::cxindex;
62
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000063CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
64 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000065 return 0;
66 CXTranslationUnit D = new CXTranslationUnitImpl();
67 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000068 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000069 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000070 D->Diagnostics = 0;
71 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Fariborz Jahanian9b7ab872012-12-18 23:02:59 +000072 D->FormatContext = 0;
73 D->FormatInMemoryUniqueId = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000074 return D;
75}
76
77cxtu::CXTUOwner::~CXTUOwner() {
78 if (TU)
79 clang_disposeTranslationUnit(TU);
80}
81
82/// \brief Compare two source ranges to determine their relative position in
83/// the translation unit.
84static RangeComparisonResult RangeCompare(SourceManager &SM,
85 SourceRange R1,
86 SourceRange R2) {
87 assert(R1.isValid() && "First range is invalid?");
88 assert(R2.isValid() && "Second range is invalid?");
89 if (R1.getEnd() != R2.getBegin() &&
90 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
91 return RangeBefore;
92 if (R2.getEnd() != R1.getBegin() &&
93 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
94 return RangeAfter;
95 return RangeOverlap;
96}
97
98/// \brief Determine if a source location falls within, before, or after a
99/// a given source range.
100static RangeComparisonResult LocationCompare(SourceManager &SM,
101 SourceLocation L, SourceRange R) {
102 assert(R.isValid() && "First range is invalid?");
103 assert(L.isValid() && "Second range is invalid?");
104 if (L == R.getBegin() || L == R.getEnd())
105 return RangeOverlap;
106 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
107 return RangeBefore;
108 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
109 return RangeAfter;
110 return RangeOverlap;
111}
112
113/// \brief Translate a Clang source range into a CIndex source range.
114///
115/// Clang internally represents ranges where the end location points to the
116/// start of the token at the end. However, for external clients it is more
117/// useful to have a CXSourceRange be a proper half-open interval. This routine
118/// does the appropriate translation.
119CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
120 const LangOptions &LangOpts,
121 const CharSourceRange &R) {
122 // We want the last character in this location, so we will adjust the
123 // location accordingly.
124 SourceLocation EndLoc = R.getEnd();
125 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
126 EndLoc = SM.getExpansionRange(EndLoc).second;
127 if (R.isTokenRange() && !EndLoc.isInvalid()) {
128 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
129 SM, LangOpts);
130 EndLoc = EndLoc.getLocWithOffset(Length);
131 }
132
Bill Wendlingeade3622013-01-23 08:25:41 +0000133 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000134 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000135 R.getBegin().getRawEncoding(),
136 EndLoc.getRawEncoding()
137 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000138 return Result;
139}
140
141//===----------------------------------------------------------------------===//
142// Cursor visitor.
143//===----------------------------------------------------------------------===//
144
145static SourceRange getRawCursorExtent(CXCursor C);
146static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
147
148
149RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
150 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
151}
152
153/// \brief Visit the given cursor and, if requested by the visitor,
154/// its children.
155///
156/// \param Cursor the cursor to visit.
157///
158/// \param CheckedRegionOfInterest if true, then the caller already checked
159/// that this cursor is within the region of interest.
160///
161/// \returns true if the visitation should be aborted, false if it
162/// should continue.
163bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
164 if (clang_isInvalid(Cursor.kind))
165 return false;
166
167 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000168 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000169 if (!D) {
170 assert(0 && "Invalid declaration cursor");
171 return true; // abort.
172 }
173
174 // Ignore implicit declarations, unless it's an objc method because
175 // currently we should report implicit methods for properties when indexing.
176 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
177 return false;
178 }
179
180 // If we have a range of interest, and this cursor doesn't intersect with it,
181 // we're done.
182 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
183 SourceRange Range = getRawCursorExtent(Cursor);
184 if (Range.isInvalid() || CompareRegionOfInterest(Range))
185 return false;
186 }
187
188 switch (Visitor(Cursor, Parent, ClientData)) {
189 case CXChildVisit_Break:
190 return true;
191
192 case CXChildVisit_Continue:
193 return false;
194
195 case CXChildVisit_Recurse: {
196 bool ret = VisitChildren(Cursor);
197 if (PostChildrenVisitor)
198 if (PostChildrenVisitor(Cursor, ClientData))
199 return true;
200 return ret;
201 }
202 }
203
204 llvm_unreachable("Invalid CXChildVisitResult!");
205}
206
207static bool visitPreprocessedEntitiesInRange(SourceRange R,
208 PreprocessingRecord &PPRec,
209 CursorVisitor &Visitor) {
210 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
211 FileID FID;
212
213 if (!Visitor.shouldVisitIncludedEntities()) {
214 // If the begin/end of the range lie in the same FileID, do the optimization
215 // where we skip preprocessed entities that do not come from the same FileID.
216 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
217 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
218 FID = FileID();
219 }
220
221 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
222 Entities = PPRec.getPreprocessedEntitiesInRange(R);
223 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
224 PPRec, FID);
225}
226
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000227bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000228 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000229 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000230
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000231 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000232 SourceManager &SM = Unit->getSourceManager();
233
234 std::pair<FileID, unsigned>
235 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
236 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
237
238 if (End.first != Begin.first) {
239 // If the end does not reside in the same file, try to recover by
240 // picking the end of the file of begin location.
241 End.first = Begin.first;
242 End.second = SM.getFileIDSize(Begin.first);
243 }
244
245 assert(Begin.first == End.first);
246 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
249 FileID File = Begin.first;
250 unsigned Offset = Begin.second;
251 unsigned Length = End.second - Begin.second;
252
253 if (!VisitDeclsOnly && !VisitPreprocessorLast)
254 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000255 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000256
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000257 if (visitDeclsFromFileRegion(File, Offset, Length))
258 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000259
260 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return visitPreprocessedEntitiesInRegion();
262
263 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000264}
265
266static bool isInLexicalContext(Decl *D, DeclContext *DC) {
267 if (!DC)
268 return false;
269
270 for (DeclContext *DeclDC = D->getLexicalDeclContext();
271 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
272 if (DeclDC == DC)
273 return true;
274 }
275 return false;
276}
277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000279 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000280 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000281 SourceManager &SM = Unit->getSourceManager();
282 SourceRange Range = RegionOfInterest;
283
284 SmallVector<Decl *, 16> Decls;
285 Unit->findFileRegionDecls(File, Offset, Length, Decls);
286
287 // If we didn't find any file level decls for the file, try looking at the
288 // file that it was included from.
289 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
290 bool Invalid = false;
291 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
292 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000293 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000294
295 SourceLocation Outer;
296 if (SLEntry.isFile())
297 Outer = SLEntry.getFile().getIncludeLoc();
298 else
299 Outer = SLEntry.getExpansion().getExpansionLocStart();
300 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000301 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000302
303 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
304 Length = 0;
305 Unit->findFileRegionDecls(File, Offset, Length, Decls);
306 }
307
308 assert(!Decls.empty());
309
310 bool VisitedAtLeastOnce = false;
311 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000312 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
313 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000314 Decl *D = *DIt;
315 if (D->getSourceRange().isInvalid())
316 continue;
317
318 if (isInLexicalContext(D, CurDC))
319 continue;
320
321 CurDC = dyn_cast<DeclContext>(D);
322
323 if (TagDecl *TD = dyn_cast<TagDecl>(D))
324 if (!TD->isFreeStanding())
325 continue;
326
327 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
328 if (CompRes == RangeBefore)
329 continue;
330 if (CompRes == RangeAfter)
331 break;
332
333 assert(CompRes == RangeOverlap);
334 VisitedAtLeastOnce = true;
335
336 if (isa<ObjCContainerDecl>(D)) {
337 FileDI_current = &DIt;
338 FileDE_current = DE;
339 } else {
340 FileDI_current = 0;
341 }
342
343 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000344 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000345 }
346
347 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000348 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000349
350 // No Decls overlapped with the range. Move up the lexical context until there
351 // is a context that contains the range or we reach the translation unit
352 // level.
353 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
354 : (*(DIt-1))->getLexicalDeclContext();
355
356 while (DC && !DC->isTranslationUnit()) {
357 Decl *D = cast<Decl>(DC);
358 SourceRange CurDeclRange = D->getSourceRange();
359 if (CurDeclRange.isInvalid())
360 break;
361
362 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000363 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
364 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000365 }
366
367 DC = D->getLexicalDeclContext();
368 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369
370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371}
372
373bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
374 if (!AU->getPreprocessor().getPreprocessingRecord())
375 return false;
376
377 PreprocessingRecord &PPRec
378 = *AU->getPreprocessor().getPreprocessingRecord();
379 SourceManager &SM = AU->getSourceManager();
380
381 if (RegionOfInterest.isValid()) {
382 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
383 SourceLocation B = MappedRange.getBegin();
384 SourceLocation E = MappedRange.getEnd();
385
386 if (AU->isInPreambleFileID(B)) {
387 if (SM.isLoadedSourceLocation(E))
388 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
389 PPRec, *this);
390
391 // Beginning of range lies in the preamble but it also extends beyond
392 // it into the main file. Split the range into 2 parts, one covering
393 // the preamble and another covering the main file. This allows subsequent
394 // calls to visitPreprocessedEntitiesInRange to accept a source range that
395 // lies in the same FileID, allowing it to skip preprocessed entities that
396 // do not come from the same FileID.
397 bool breaked =
398 visitPreprocessedEntitiesInRange(
399 SourceRange(B, AU->getEndOfPreambleFileID()),
400 PPRec, *this);
401 if (breaked) return true;
402 return visitPreprocessedEntitiesInRange(
403 SourceRange(AU->getStartOfMainFileID(), E),
404 PPRec, *this);
405 }
406
407 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
408 }
409
410 bool OnlyLocalDecls
411 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
412
413 if (OnlyLocalDecls)
414 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
415 PPRec);
416
417 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
418}
419
420template<typename InputIterator>
421bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
422 InputIterator Last,
423 PreprocessingRecord &PPRec,
424 FileID FID) {
425 for (; First != Last; ++First) {
426 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
427 continue;
428
429 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000430 if (!PPE)
431 continue;
432
Guy Benyei11169dd2012-12-18 14:30:41 +0000433 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
434 if (Visit(MakeMacroExpansionCursor(ME, TU)))
435 return true;
436
437 continue;
438 }
439
440 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
441 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
442 return true;
443
444 continue;
445 }
446
447 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
448 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
449 return true;
450
451 continue;
452 }
453 }
454
455 return false;
456}
457
458/// \brief Visit the children of the given cursor.
459///
460/// \returns true if the visitation should be aborted, false if it
461/// should continue.
462bool CursorVisitor::VisitChildren(CXCursor Cursor) {
463 if (clang_isReference(Cursor.kind) &&
464 Cursor.kind != CXCursor_CXXBaseSpecifier) {
465 // By definition, references have no children.
466 return false;
467 }
468
469 // Set the Parent field to Cursor, then back to its old value once we're
470 // done.
471 SetParentRAII SetParent(Parent, StmtParent, Cursor);
472
473 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000474 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000475 if (!D)
476 return false;
477
478 return VisitAttributes(D) || Visit(D);
479 }
480
481 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000482 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000483 return Visit(S);
484
485 return false;
486 }
487
488 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000489 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000490 return Visit(E);
491
492 return false;
493 }
494
495 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000496 CXTranslationUnit TU = getCursorTU(Cursor);
497 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000498
499 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
500 for (unsigned I = 0; I != 2; ++I) {
501 if (VisitOrder[I]) {
502 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
503 RegionOfInterest.isInvalid()) {
504 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
505 TLEnd = CXXUnit->top_level_end();
506 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000507 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return true;
509 }
510 } else if (VisitDeclContext(
511 CXXUnit->getASTContext().getTranslationUnitDecl()))
512 return true;
513 continue;
514 }
515
516 // Walk the preprocessing record.
517 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
518 visitPreprocessedEntitiesInRegion();
519 }
520
521 return false;
522 }
523
524 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000525 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
527 return Visit(BaseTSInfo->getTypeLoc());
528 }
529 }
530 }
531
532 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000533 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000534 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000535 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000536 return Visit(cxcursor::MakeCursorObjCClassRef(
537 ObjT->getInterface(),
538 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000539 }
540
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000541 // If pointing inside a macro definition, check if the token is an identifier
542 // that was ever defined as a macro. In such a case, create a "pseudo" macro
543 // expansion cursor for that token.
544 SourceLocation BeginLoc = RegionOfInterest.getBegin();
545 if (Cursor.kind == CXCursor_MacroDefinition &&
546 BeginLoc == RegionOfInterest.getEnd()) {
547 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000548 const MacroInfo *MI =
549 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000550 if (MacroDefinition *MacroDef =
551 checkForMacroInMacroDefinition(MI, Loc, TU))
552 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
553 }
554
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 // Nothing to visit at the moment.
556 return false;
557}
558
559bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
560 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
561 if (Visit(TSInfo->getTypeLoc()))
562 return true;
563
564 if (Stmt *Body = B->getBody())
565 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
566
567 return false;
568}
569
Ted Kremenek03325582013-02-21 01:29:01 +0000570Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000571 if (RegionOfInterest.isValid()) {
572 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
573 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000574 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000575
576 switch (CompareRegionOfInterest(Range)) {
577 case RangeBefore:
578 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000579 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000580
581 case RangeAfter:
582 // This declaration comes after the region of interest; we're done.
583 return false;
584
585 case RangeOverlap:
586 // This declaration overlaps the region of interest; visit it.
587 break;
588 }
589 }
590 return true;
591}
592
593bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
594 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
595
596 // FIXME: Eventually remove. This part of a hack to support proper
597 // iteration over all Decls contained lexically within an ObjC container.
598 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
599 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
600
601 for ( ; I != E; ++I) {
602 Decl *D = *I;
603 if (D->getLexicalDeclContext() != DC)
604 continue;
605 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
606
607 // Ignore synthesized ivars here, otherwise if we have something like:
608 // @synthesize prop = _prop;
609 // and '_prop' is not declared, we will encounter a '_prop' ivar before
610 // encountering the 'prop' synthesize declaration and we will think that
611 // we passed the region-of-interest.
612 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
613 if (ivarD->getSynthesize())
614 continue;
615 }
616
617 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
618 // declarations is a mismatch with the compiler semantics.
619 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
620 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
621 if (!ID->isThisDeclarationADefinition())
622 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
623
624 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
625 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
626 if (!PD->isThisDeclarationADefinition())
627 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
628 }
629
Ted Kremenek03325582013-02-21 01:29:01 +0000630 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000631 if (!V.hasValue())
632 continue;
633 if (!V.getValue())
634 return false;
635 if (Visit(Cursor, true))
636 return true;
637 }
638 return false;
639}
640
641bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
642 llvm_unreachable("Translation units are visited directly by Visit()");
643}
644
645bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
646 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
647 return Visit(TSInfo->getTypeLoc());
648
649 return false;
650}
651
652bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
653 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
654 return Visit(TSInfo->getTypeLoc());
655
656 return false;
657}
658
659bool CursorVisitor::VisitTagDecl(TagDecl *D) {
660 return VisitDeclContext(D);
661}
662
663bool CursorVisitor::VisitClassTemplateSpecializationDecl(
664 ClassTemplateSpecializationDecl *D) {
665 bool ShouldVisitBody = false;
666 switch (D->getSpecializationKind()) {
667 case TSK_Undeclared:
668 case TSK_ImplicitInstantiation:
669 // Nothing to visit
670 return false;
671
672 case TSK_ExplicitInstantiationDeclaration:
673 case TSK_ExplicitInstantiationDefinition:
674 break;
675
676 case TSK_ExplicitSpecialization:
677 ShouldVisitBody = true;
678 break;
679 }
680
681 // Visit the template arguments used in the specialization.
682 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
683 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000684 if (TemplateSpecializationTypeLoc TSTLoc =
685 TL.getAs<TemplateSpecializationTypeLoc>()) {
686 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
687 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000688 return true;
689 }
690 }
691
692 if (ShouldVisitBody && VisitCXXRecordDecl(D))
693 return true;
694
695 return false;
696}
697
698bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
699 ClassTemplatePartialSpecializationDecl *D) {
700 // FIXME: Visit the "outer" template parameter lists on the TagDecl
701 // before visiting these template parameters.
702 if (VisitTemplateParameters(D->getTemplateParameters()))
703 return true;
704
705 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000706 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
707 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
708 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
710 return true;
711
712 return VisitCXXRecordDecl(D);
713}
714
715bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
716 // Visit the default argument.
717 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
718 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
719 if (Visit(DefArg->getTypeLoc()))
720 return true;
721
722 return false;
723}
724
725bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
726 if (Expr *Init = D->getInitExpr())
727 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
728 return false;
729}
730
731bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000732 unsigned NumParamList = DD->getNumTemplateParameterLists();
733 for (unsigned i = 0; i < NumParamList; i++) {
734 TemplateParameterList* Params = DD->getTemplateParameterList(i);
735 if (VisitTemplateParameters(Params))
736 return true;
737 }
738
Guy Benyei11169dd2012-12-18 14:30:41 +0000739 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
740 if (Visit(TSInfo->getTypeLoc()))
741 return true;
742
743 // Visit the nested-name-specifier, if present.
744 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
745 if (VisitNestedNameSpecifierLoc(QualifierLoc))
746 return true;
747
748 return false;
749}
750
751/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000752static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
753 CXXCtorInitializer *const *Y) {
754 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000755}
756
757bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000758 unsigned NumParamList = ND->getNumTemplateParameterLists();
759 for (unsigned i = 0; i < NumParamList; i++) {
760 TemplateParameterList* Params = ND->getTemplateParameterList(i);
761 if (VisitTemplateParameters(Params))
762 return true;
763 }
764
Guy Benyei11169dd2012-12-18 14:30:41 +0000765 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
766 // Visit the function declaration's syntactic components in the order
767 // written. This requires a bit of work.
768 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000769 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000770
771 // If we have a function declared directly (without the use of a typedef),
772 // visit just the return type. Otherwise, just visit the function's type
773 // now.
David Blaikie6adc78e2013-02-18 22:06:02 +0000774 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000775 (!FTL && Visit(TL)))
776 return true;
777
778 // Visit the nested-name-specifier, if present.
779 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
780 if (VisitNestedNameSpecifierLoc(QualifierLoc))
781 return true;
782
783 // Visit the declaration name.
784 if (VisitDeclarationNameInfo(ND->getNameInfo()))
785 return true;
786
787 // FIXME: Visit explicitly-specified template arguments!
788
789 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000791 return true;
792
Bill Wendling44426052012-12-20 19:22:21 +0000793 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 }
795
796 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
797 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
798 // Find the initializers that were written in the source.
799 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
800 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
801 IEnd = Constructor->init_end();
802 I != IEnd; ++I) {
803 if (!(*I)->isWritten())
804 continue;
805
806 WrittenInits.push_back(*I);
807 }
808
809 // Sort the initializers in source order
810 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
811 &CompareCXXCtorInitializers);
812
813 // Visit the initializers in source order
814 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
815 CXXCtorInitializer *Init = WrittenInits[I];
816 if (Init->isAnyMemberInitializer()) {
817 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
818 Init->getMemberLocation(), TU)))
819 return true;
820 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
821 if (Visit(TInfo->getTypeLoc()))
822 return true;
823 }
824
825 // Visit the initializer value.
826 if (Expr *Initializer = Init->getInit())
827 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
828 return true;
829 }
830 }
831
832 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
833 return true;
834 }
835
836 return false;
837}
838
839bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
840 if (VisitDeclaratorDecl(D))
841 return true;
842
843 if (Expr *BitWidth = D->getBitWidth())
844 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
845
846 return false;
847}
848
849bool CursorVisitor::VisitVarDecl(VarDecl *D) {
850 if (VisitDeclaratorDecl(D))
851 return true;
852
853 if (Expr *Init = D->getInit())
854 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
855
856 return false;
857}
858
859bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
864 if (Expr *DefArg = D->getDefaultArgument())
865 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
871 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
872 // before visiting these template parameters.
873 if (VisitTemplateParameters(D->getTemplateParameters()))
874 return true;
875
876 return VisitFunctionDecl(D->getTemplatedDecl());
877}
878
879bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
880 // FIXME: Visit the "outer" template parameter lists on the TagDecl
881 // before visiting these template parameters.
882 if (VisitTemplateParameters(D->getTemplateParameters()))
883 return true;
884
885 return VisitCXXRecordDecl(D->getTemplatedDecl());
886}
887
888bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
889 if (VisitTemplateParameters(D->getTemplateParameters()))
890 return true;
891
892 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
893 VisitTemplateArgumentLoc(D->getDefaultArgument()))
894 return true;
895
896 return false;
897}
898
899bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
900 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
901 if (Visit(TSInfo->getTypeLoc()))
902 return true;
903
904 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
905 PEnd = ND->param_end();
906 P != PEnd; ++P) {
907 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
908 return true;
909 }
910
911 if (ND->isThisDeclarationADefinition() &&
912 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
913 return true;
914
915 return false;
916}
917
918template <typename DeclIt>
919static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
920 SourceManager &SM, SourceLocation EndLoc,
921 SmallVectorImpl<Decl *> &Decls) {
922 DeclIt next = *DI_current;
923 while (++next != DE_current) {
924 Decl *D_next = *next;
925 if (!D_next)
926 break;
927 SourceLocation L = D_next->getLocStart();
928 if (!L.isValid())
929 break;
930 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
931 *DI_current = next;
932 Decls.push_back(D_next);
933 continue;
934 }
935 break;
936 }
937}
938
939namespace {
940 struct ContainerDeclsSort {
941 SourceManager &SM;
942 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
943 bool operator()(Decl *A, Decl *B) {
944 SourceLocation L_A = A->getLocStart();
945 SourceLocation L_B = B->getLocStart();
946 assert(L_A.isValid() && L_B.isValid());
947 return SM.isBeforeInTranslationUnit(L_A, L_B);
948 }
949 };
950}
951
952bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
953 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
954 // an @implementation can lexically contain Decls that are not properly
955 // nested in the AST. When we identify such cases, we need to retrofit
956 // this nesting here.
957 if (!DI_current && !FileDI_current)
958 return VisitDeclContext(D);
959
960 // Scan the Decls that immediately come after the container
961 // in the current DeclContext. If any fall within the
962 // container's lexical region, stash them into a vector
963 // for later processing.
964 SmallVector<Decl *, 24> DeclsInContainer;
965 SourceLocation EndLoc = D->getSourceRange().getEnd();
966 SourceManager &SM = AU->getSourceManager();
967 if (EndLoc.isValid()) {
968 if (DI_current) {
969 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
970 DeclsInContainer);
971 } else {
972 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
973 DeclsInContainer);
974 }
975 }
976
977 // The common case.
978 if (DeclsInContainer.empty())
979 return VisitDeclContext(D);
980
981 // Get all the Decls in the DeclContext, and sort them with the
982 // additional ones we've collected. Then visit them.
983 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
984 I!=E; ++I) {
985 Decl *subDecl = *I;
986 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
987 subDecl->getLocStart().isInvalid())
988 continue;
989 DeclsInContainer.push_back(subDecl);
990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
994 ContainerDeclsSort(SM));
995
996 // Now visit the decls.
997 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
998 E = DeclsInContainer.end(); I != E; ++I) {
999 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001000 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!V.hasValue())
1002 continue;
1003 if (!V.getValue())
1004 return false;
1005 if (Visit(Cursor, true))
1006 return true;
1007 }
1008 return false;
1009}
1010
1011bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1012 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1013 TU)))
1014 return true;
1015
1016 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1017 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1018 E = ND->protocol_end(); I != E; ++I, ++PL)
1019 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1020 return true;
1021
1022 return VisitObjCContainerDecl(ND);
1023}
1024
1025bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1026 if (!PID->isThisDeclarationADefinition())
1027 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1028
1029 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1030 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1031 E = PID->protocol_end(); I != E; ++I, ++PL)
1032 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1033 return true;
1034
1035 return VisitObjCContainerDecl(PID);
1036}
1037
1038bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1039 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1040 return true;
1041
1042 // FIXME: This implements a workaround with @property declarations also being
1043 // installed in the DeclContext for the @interface. Eventually this code
1044 // should be removed.
1045 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1046 if (!CDecl || !CDecl->IsClassExtension())
1047 return false;
1048
1049 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1050 if (!ID)
1051 return false;
1052
1053 IdentifierInfo *PropertyId = PD->getIdentifier();
1054 ObjCPropertyDecl *prevDecl =
1055 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1056
1057 if (!prevDecl)
1058 return false;
1059
1060 // Visit synthesized methods since they will be skipped when visiting
1061 // the @interface.
1062 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1063 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1064 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1065 return true;
1066
1067 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1076 if (!D->isThisDeclarationADefinition()) {
1077 // Forward declaration is treated like a reference.
1078 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1079 }
1080
1081 // Issue callbacks for super class.
1082 if (D->getSuperClass() &&
1083 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1084 D->getSuperClassLoc(),
1085 TU)))
1086 return true;
1087
1088 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1089 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1090 E = D->protocol_end(); I != E; ++I, ++PL)
1091 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1092 return true;
1093
1094 return VisitObjCContainerDecl(D);
1095}
1096
1097bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1098 return VisitObjCContainerDecl(D);
1099}
1100
1101bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1102 // 'ID' could be null when dealing with invalid code.
1103 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1104 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1105 return true;
1106
1107 return VisitObjCImplDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1111#if 0
1112 // Issue callbacks for super class.
1113 // FIXME: No source location information!
1114 if (D->getSuperClass() &&
1115 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1116 D->getSuperClassLoc(),
1117 TU)))
1118 return true;
1119#endif
1120
1121 return VisitObjCImplDecl(D);
1122}
1123
1124bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1125 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1126 if (PD->isIvarNameSpecified())
1127 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1128
1129 return false;
1130}
1131
1132bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1133 return VisitDeclContext(D);
1134}
1135
1136bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1137 // Visit nested-name-specifier.
1138 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1139 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1140 return true;
1141
1142 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1143 D->getTargetNameLoc(), TU));
1144}
1145
1146bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1147 // Visit nested-name-specifier.
1148 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1149 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1150 return true;
1151 }
1152
1153 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1154 return true;
1155
1156 return VisitDeclarationNameInfo(D->getNameInfo());
1157}
1158
1159bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1160 // Visit nested-name-specifier.
1161 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1162 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1163 return true;
1164
1165 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1166 D->getIdentLocation(), TU));
1167}
1168
1169bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174 }
1175
1176 return VisitDeclarationNameInfo(D->getNameInfo());
1177}
1178
1179bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1180 UnresolvedUsingTypenameDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return false;
1187}
1188
1189bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1190 switch (Name.getName().getNameKind()) {
1191 case clang::DeclarationName::Identifier:
1192 case clang::DeclarationName::CXXLiteralOperatorName:
1193 case clang::DeclarationName::CXXOperatorName:
1194 case clang::DeclarationName::CXXUsingDirective:
1195 return false;
1196
1197 case clang::DeclarationName::CXXConstructorName:
1198 case clang::DeclarationName::CXXDestructorName:
1199 case clang::DeclarationName::CXXConversionFunctionName:
1200 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1201 return Visit(TSInfo->getTypeLoc());
1202 return false;
1203
1204 case clang::DeclarationName::ObjCZeroArgSelector:
1205 case clang::DeclarationName::ObjCOneArgSelector:
1206 case clang::DeclarationName::ObjCMultiArgSelector:
1207 // FIXME: Per-identifier location info?
1208 return false;
1209 }
1210
1211 llvm_unreachable("Invalid DeclarationName::Kind!");
1212}
1213
1214bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1215 SourceRange Range) {
1216 // FIXME: This whole routine is a hack to work around the lack of proper
1217 // source information in nested-name-specifiers (PR5791). Since we do have
1218 // a beginning source location, we can visit the first component of the
1219 // nested-name-specifier, if it's a single-token component.
1220 if (!NNS)
1221 return false;
1222
1223 // Get the first component in the nested-name-specifier.
1224 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1225 NNS = Prefix;
1226
1227 switch (NNS->getKind()) {
1228 case NestedNameSpecifier::Namespace:
1229 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1230 TU));
1231
1232 case NestedNameSpecifier::NamespaceAlias:
1233 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1234 Range.getBegin(), TU));
1235
1236 case NestedNameSpecifier::TypeSpec: {
1237 // If the type has a form where we know that the beginning of the source
1238 // range matches up with a reference cursor. Visit the appropriate reference
1239 // cursor.
1240 const Type *T = NNS->getAsType();
1241 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1242 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1243 if (const TagType *Tag = dyn_cast<TagType>(T))
1244 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1245 if (const TemplateSpecializationType *TST
1246 = dyn_cast<TemplateSpecializationType>(T))
1247 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1248 break;
1249 }
1250
1251 case NestedNameSpecifier::TypeSpecWithTemplate:
1252 case NestedNameSpecifier::Global:
1253 case NestedNameSpecifier::Identifier:
1254 break;
1255 }
1256
1257 return false;
1258}
1259
1260bool
1261CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1262 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1263 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1264 Qualifiers.push_back(Qualifier);
1265
1266 while (!Qualifiers.empty()) {
1267 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1268 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1269 switch (NNS->getKind()) {
1270 case NestedNameSpecifier::Namespace:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1272 Q.getLocalBeginLoc(),
1273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Q.getLocalBeginLoc(),
1281 TU)))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::TypeSpec:
1287 case NestedNameSpecifier::TypeSpecWithTemplate:
1288 if (Visit(Q.getTypeLoc()))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::Global:
1294 case NestedNameSpecifier::Identifier:
1295 break;
1296 }
1297 }
1298
1299 return false;
1300}
1301
1302bool CursorVisitor::VisitTemplateParameters(
1303 const TemplateParameterList *Params) {
1304 if (!Params)
1305 return false;
1306
1307 for (TemplateParameterList::const_iterator P = Params->begin(),
1308 PEnd = Params->end();
1309 P != PEnd; ++P) {
1310 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1311 return true;
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1318 switch (Name.getKind()) {
1319 case TemplateName::Template:
1320 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1321
1322 case TemplateName::OverloadedTemplate:
1323 // Visit the overloaded template set.
1324 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1325 return true;
1326
1327 return false;
1328
1329 case TemplateName::DependentTemplate:
1330 // FIXME: Visit nested-name-specifier.
1331 return false;
1332
1333 case TemplateName::QualifiedTemplate:
1334 // FIXME: Visit nested-name-specifier.
1335 return Visit(MakeCursorTemplateRef(
1336 Name.getAsQualifiedTemplateName()->getDecl(),
1337 Loc, TU));
1338
1339 case TemplateName::SubstTemplateTemplateParm:
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParmPack:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1347 Loc, TU));
1348 }
1349
1350 llvm_unreachable("Invalid TemplateName::Kind!");
1351}
1352
1353bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1354 switch (TAL.getArgument().getKind()) {
1355 case TemplateArgument::Null:
1356 case TemplateArgument::Integral:
1357 case TemplateArgument::Pack:
1358 return false;
1359
1360 case TemplateArgument::Type:
1361 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1362 return Visit(TSInfo->getTypeLoc());
1363 return false;
1364
1365 case TemplateArgument::Declaration:
1366 if (Expr *E = TAL.getSourceDeclExpression())
1367 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1368 return false;
1369
1370 case TemplateArgument::NullPtr:
1371 if (Expr *E = TAL.getSourceNullPtrExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::Expression:
1376 if (Expr *E = TAL.getSourceExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Template:
1381 case TemplateArgument::TemplateExpansion:
1382 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1383 return true;
1384
1385 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1386 TAL.getTemplateNameLoc());
1387 }
1388
1389 llvm_unreachable("Invalid TemplateArgument::Kind!");
1390}
1391
1392bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1393 return VisitDeclContext(D);
1394}
1395
1396bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1397 return Visit(TL.getUnqualifiedLoc());
1398}
1399
1400bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1401 ASTContext &Context = AU->getASTContext();
1402
1403 // Some builtin types (such as Objective-C's "id", "sel", and
1404 // "Class") have associated declarations. Create cursors for those.
1405 QualType VisitType;
1406 switch (TL.getTypePtr()->getKind()) {
1407
1408 case BuiltinType::Void:
1409 case BuiltinType::NullPtr:
1410 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001411 case BuiltinType::OCLImage1d:
1412 case BuiltinType::OCLImage1dArray:
1413 case BuiltinType::OCLImage1dBuffer:
1414 case BuiltinType::OCLImage2d:
1415 case BuiltinType::OCLImage2dArray:
1416 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001417 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001418 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001419#define BUILTIN_TYPE(Id, SingletonId)
1420#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#include "clang/AST/BuiltinTypes.def"
1425 break;
1426
1427 case BuiltinType::ObjCId:
1428 VisitType = Context.getObjCIdType();
1429 break;
1430
1431 case BuiltinType::ObjCClass:
1432 VisitType = Context.getObjCClassType();
1433 break;
1434
1435 case BuiltinType::ObjCSel:
1436 VisitType = Context.getObjCSelType();
1437 break;
1438 }
1439
1440 if (!VisitType.isNull()) {
1441 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1442 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1443 TU));
1444 }
1445
1446 return false;
1447}
1448
1449bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1450 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1458 if (TL.isDefinition())
1459 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1460
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1469 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1470 return true;
1471
1472 return false;
1473}
1474
1475bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1476 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1477 return true;
1478
1479 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1480 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1481 TU)))
1482 return true;
1483 }
1484
1485 return false;
1486}
1487
1488bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1493 return Visit(TL.getInnerLoc());
1494}
1495
1496bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1501 return Visit(TL.getPointeeLoc());
1502}
1503
1504bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1505 return Visit(TL.getPointeeLoc());
1506}
1507
1508bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1509 return Visit(TL.getPointeeLoc());
1510}
1511
1512bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1513 return Visit(TL.getPointeeLoc());
1514}
1515
1516bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1517 return Visit(TL.getModifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1521 bool SkipResultType) {
1522 if (!SkipResultType && Visit(TL.getResultLoc()))
1523 return true;
1524
1525 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1526 if (Decl *D = TL.getArg(I))
1527 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1528 return true;
1529
1530 return false;
1531}
1532
1533bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1534 if (Visit(TL.getElementLoc()))
1535 return true;
1536
1537 if (Expr *Size = TL.getSizeExpr())
1538 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1539
1540 return false;
1541}
1542
Reid Kleckner8a365022013-06-24 17:51:48 +00001543bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1544 return Visit(TL.getOriginalLoc());
1545}
1546
Guy Benyei11169dd2012-12-18 14:30:41 +00001547bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1548 TemplateSpecializationTypeLoc TL) {
1549 // Visit the template name.
1550 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1551 TL.getTemplateNameLoc()))
1552 return true;
1553
1554 // Visit the template arguments.
1555 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1556 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1557 return true;
1558
1559 return false;
1560}
1561
1562bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1563 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1564}
1565
1566bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1567 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1568 return Visit(TSInfo->getTypeLoc());
1569
1570 return false;
1571}
1572
1573bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1574 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1575 return Visit(TSInfo->getTypeLoc());
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1581 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1582 return true;
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1588 DependentTemplateSpecializationTypeLoc TL) {
1589 // Visit the nested-name-specifier, if there is one.
1590 if (TL.getQualifierLoc() &&
1591 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1592 return true;
1593
1594 // Visit the template arguments.
1595 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1596 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1597 return true;
1598
1599 return false;
1600}
1601
1602bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1603 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1604 return true;
1605
1606 return Visit(TL.getNamedTypeLoc());
1607}
1608
1609bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1610 return Visit(TL.getPatternLoc());
1611}
1612
1613bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1614 if (Expr *E = TL.getUnderlyingExpr())
1615 return Visit(MakeCXCursor(E, StmtParent, TU));
1616
1617 return false;
1618}
1619
1620bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1621 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1622}
1623
1624bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1625 return Visit(TL.getValueLoc());
1626}
1627
1628#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1629bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1630 return Visit##PARENT##Loc(TL); \
1631}
1632
1633DEFAULT_TYPELOC_IMPL(Complex, Type)
1634DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1635DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1636DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1638DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1639DEFAULT_TYPELOC_IMPL(Vector, Type)
1640DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1641DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1642DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1643DEFAULT_TYPELOC_IMPL(Record, TagType)
1644DEFAULT_TYPELOC_IMPL(Enum, TagType)
1645DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1646DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1647DEFAULT_TYPELOC_IMPL(Auto, Type)
1648
1649bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1650 // Visit the nested-name-specifier, if present.
1651 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1652 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1653 return true;
1654
1655 if (D->isCompleteDefinition()) {
1656 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1657 E = D->bases_end(); I != E; ++I) {
1658 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1659 return true;
1660 }
1661 }
1662
1663 return VisitTagDecl(D);
1664}
1665
1666bool CursorVisitor::VisitAttributes(Decl *D) {
1667 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1668 i != e; ++i)
1669 if (Visit(MakeCXCursor(*i, D, TU)))
1670 return true;
1671
1672 return false;
1673}
1674
1675//===----------------------------------------------------------------------===//
1676// Data-recursive visitor methods.
1677//===----------------------------------------------------------------------===//
1678
1679namespace {
1680#define DEF_JOB(NAME, DATA, KIND)\
1681class NAME : public VisitorJob {\
1682public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001683 NAME(const DATA *d, CXCursor parent) : \
1684 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001685 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001687};
1688
1689DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1690DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1691DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1692DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1693DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1694 ExplicitTemplateArgsVisitKind)
1695DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1696DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1697DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1698#undef DEF_JOB
1699
1700class DeclVisit : public VisitorJob {
1701public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001702 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001703 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001704 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 static bool classof(const VisitorJob *VJ) {
1706 return VJ->getKind() == DeclVisitKind;
1707 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001708 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001709 bool isFirst() const { return data[1] ? true : false; }
1710};
1711class TypeLocVisit : public VisitorJob {
1712public:
1713 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1714 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1715 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1716
1717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == TypeLocVisitKind;
1719 }
1720
1721 TypeLoc get() const {
1722 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001723 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 }
1725};
1726
1727class LabelRefVisit : public VisitorJob {
1728public:
1729 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1730 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1731 labelLoc.getPtrEncoding()) {}
1732
1733 static bool classof(const VisitorJob *VJ) {
1734 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1735 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001736 const LabelDecl *get() const {
1737 return static_cast<const LabelDecl *>(data[0]);
1738 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001739 SourceLocation getLoc() const {
1740 return SourceLocation::getFromPtrEncoding(data[1]); }
1741};
1742
1743class NestedNameSpecifierLocVisit : public VisitorJob {
1744public:
1745 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1746 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1747 Qualifier.getNestedNameSpecifier(),
1748 Qualifier.getOpaqueData()) { }
1749
1750 static bool classof(const VisitorJob *VJ) {
1751 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1752 }
1753
1754 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001755 return NestedNameSpecifierLoc(
1756 const_cast<NestedNameSpecifier *>(
1757 static_cast<const NestedNameSpecifier *>(data[0])),
1758 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001759 }
1760};
1761
1762class DeclarationNameInfoVisit : public VisitorJob {
1763public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001764 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001765 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 static bool classof(const VisitorJob *VJ) {
1767 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1768 }
1769 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001770 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 switch (S->getStmtClass()) {
1772 default:
1773 llvm_unreachable("Unhandled Stmt");
1774 case clang::Stmt::MSDependentExistsStmtClass:
1775 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1776 case Stmt::CXXDependentScopeMemberExprClass:
1777 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1778 case Stmt::DependentScopeDeclRefExprClass:
1779 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1780 }
1781 }
1782};
1783class MemberRefVisit : public VisitorJob {
1784public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001785 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001786 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1787 L.getPtrEncoding()) {}
1788 static bool classof(const VisitorJob *VJ) {
1789 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1790 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001791 const FieldDecl *get() const {
1792 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 }
1794 SourceLocation getLoc() const {
1795 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1796 }
1797};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001799 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 VisitorWorkList &WL;
1801 CXCursor Parent;
1802public:
1803 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1804 : WL(wl), Parent(parent) {}
1805
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001806 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1807 void VisitBlockExpr(const BlockExpr *B);
1808 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1809 void VisitCompoundStmt(const CompoundStmt *S);
1810 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1811 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1812 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1813 void VisitCXXNewExpr(const CXXNewExpr *E);
1814 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1815 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1816 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1817 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1818 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1819 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1820 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1821 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1822 void VisitDeclRefExpr(const DeclRefExpr *D);
1823 void VisitDeclStmt(const DeclStmt *S);
1824 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1825 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1826 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1827 void VisitForStmt(const ForStmt *FS);
1828 void VisitGotoStmt(const GotoStmt *GS);
1829 void VisitIfStmt(const IfStmt *If);
1830 void VisitInitListExpr(const InitListExpr *IE);
1831 void VisitMemberExpr(const MemberExpr *M);
1832 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1833 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1834 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1835 void VisitOverloadExpr(const OverloadExpr *E);
1836 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1837 void VisitStmt(const Stmt *S);
1838 void VisitSwitchStmt(const SwitchStmt *S);
1839 void VisitWhileStmt(const WhileStmt *W);
1840 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1841 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853
Guy Benyei11169dd2012-12-18 14:30:41 +00001854private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001856 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1857 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1859 void AddStmt(const Stmt *S);
1860 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001863 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001864};
1865} // end anonyous namespace
1866
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001868 // 'S' should always be non-null, since it comes from the
1869 // statement we are visiting.
1870 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1871}
1872
1873void
1874EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1875 if (Qualifier)
1876 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1877}
1878
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 if (S)
1881 WL.push_back(StmtVisit(S, Parent));
1882}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 if (D)
1885 WL.push_back(DeclVisit(D, Parent, isFirst));
1886}
1887void EnqueueVisitor::
1888 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1889 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001891}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001893 if (D)
1894 WL.push_back(MemberRefVisit(D, L, Parent));
1895}
1896void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1897 if (TI)
1898 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1899 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 AddStmt(*Child);
1904 }
1905 if (size == WL.size())
1906 return;
1907 // Now reverse the entries we just added. This will match the DFS
1908 // ordering performed by the worklist.
1909 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1910 std::reverse(I, E);
1911}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001912namespace {
1913class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1914 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001915 /// \brief Process clauses with list of variables.
1916 template <typename T>
1917 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918public:
1919 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1920#define OPENMP_CLAUSE(Name, Class) \
1921 void Visit##Class(const Class *C);
1922#include "clang/Basic/OpenMPKinds.def"
1923};
1924
1925void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001926
1927template<typename T>
1928void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1929 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1930 E = Node->varlist_end();
1931 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001933}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001934
1935void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001936 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001937}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001938void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1939 const OMPFirstprivateClause *C) {
1940 VisitOMPClauseList(C);
1941}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001942void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001943 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001944}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945}
Alexey Bataev756c1962013-09-24 03:17:45 +00001946
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1948 unsigned size = WL.size();
1949 OMPClauseEnqueue Visitor(this);
1950 Visitor.Visit(S);
1951 if (size == WL.size())
1952 return;
1953 // Now reverse the entries we just added. This will match the DFS
1954 // ordering performed by the worklist.
1955 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1956 std::reverse(I, E);
1957}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1960}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 AddDecl(B->getBlockDecl());
1963}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 EnqueueChildren(E);
1966 AddTypeLoc(E->getTypeSourceInfo());
1967}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1969 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 E = S->body_rend(); I != E; ++I) {
1971 AddStmt(*I);
1972 }
1973}
1974void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 AddStmt(S->getSubStmt());
1977 AddDeclarationNameInfo(S);
1978 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1979 AddNestedNameSpecifierLoc(QualifierLoc);
1980}
1981
1982void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1985 AddDeclarationNameInfo(E);
1986 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1987 AddNestedNameSpecifierLoc(QualifierLoc);
1988 if (!E->isImplicitAccess())
1989 AddStmt(E->getBase());
1990}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 // Enqueue the initializer , if any.
1993 AddStmt(E->getInitializer());
1994 // Enqueue the array size, if any.
1995 AddStmt(E->getArraySize());
1996 // Enqueue the allocated type.
1997 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1998 // Enqueue the placement arguments.
1999 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2000 AddStmt(E->getPlacementArg(I-1));
2001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2004 AddStmt(CE->getArg(I-1));
2005 AddStmt(CE->getCallee());
2006 AddStmt(CE->getArg(0));
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2009 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 // Visit the name of the type being destroyed.
2011 AddTypeLoc(E->getDestroyedTypeInfo());
2012 // Visit the scope type that looks disturbingly like the nested-name-specifier
2013 // but isn't.
2014 AddTypeLoc(E->getScopeTypeInfo());
2015 // Visit the nested-name-specifier.
2016 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2017 AddNestedNameSpecifierLoc(QualifierLoc);
2018 // Visit base expression.
2019 AddStmt(E->getBase());
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2022 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 AddTypeLoc(E->getTypeSourceInfo());
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2026 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 EnqueueChildren(E);
2028 AddTypeLoc(E->getTypeSourceInfo());
2029}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 EnqueueChildren(E);
2032 if (E->isTypeOperand())
2033 AddTypeLoc(E->getTypeOperandSourceInfo());
2034}
2035
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2037 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002038 EnqueueChildren(E);
2039 AddTypeLoc(E->getTypeSourceInfo());
2040}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 EnqueueChildren(E);
2043 if (E->isTypeOperand())
2044 AddTypeLoc(E->getTypeOperandSourceInfo());
2045}
2046
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(S);
2049 AddDecl(S->getExceptionDecl());
2050}
2051
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 if (DR->hasExplicitTemplateArgs()) {
2054 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2055 }
2056 WL.push_back(DeclRefExprParts(DR, Parent));
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2059 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2061 AddDeclarationNameInfo(E);
2062 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 unsigned size = WL.size();
2066 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 D != DEnd; ++D) {
2069 AddDecl(*D, isFirst);
2070 isFirst = false;
2071 }
2072 if (size == WL.size())
2073 return;
2074 // Now reverse the entries we just added. This will match the DFS
2075 // ordering performed by the worklist.
2076 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2077 std::reverse(I, E);
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 D = E->designators_rbegin(), DEnd = E->designators_rend();
2083 D != DEnd; ++D) {
2084 if (D->isFieldDesignator()) {
2085 if (FieldDecl *Field = D->getField())
2086 AddMemberRef(Field, D->getFieldLoc());
2087 continue;
2088 }
2089 if (D->isArrayDesignator()) {
2090 AddStmt(E->getArrayIndex(*D));
2091 continue;
2092 }
2093 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2094 AddStmt(E->getArrayRangeEnd(*D));
2095 AddStmt(E->getArrayRangeStart(*D));
2096 }
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 EnqueueChildren(E);
2100 AddTypeLoc(E->getTypeInfoAsWritten());
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 AddStmt(FS->getBody());
2104 AddStmt(FS->getInc());
2105 AddStmt(FS->getCond());
2106 AddDecl(FS->getConditionVariable());
2107 AddStmt(FS->getInit());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 AddStmt(If->getElse());
2114 AddStmt(If->getThen());
2115 AddStmt(If->getCond());
2116 AddDecl(If->getConditionVariable());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 // We care about the syntactic form of the initializer list, only.
2120 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2121 IE = Syntactic;
2122 EnqueueChildren(IE);
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 WL.push_back(MemberExprParts(M, Parent));
2126
2127 // If the base of the member access expression is an implicit 'this', don't
2128 // visit it.
2129 // FIXME: If we ever want to show these implicit accesses, this will be
2130 // unfortunate. However, clang_getCursor() relies on this behavior.
2131 if (!M->isImplicitAccess())
2132 AddStmt(M->getBase());
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 AddTypeLoc(E->getEncodedTypeSourceInfo());
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 EnqueueChildren(M);
2139 AddTypeLoc(M->getClassReceiverTypeInfo());
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 // Visit the components of the offsetof expression.
2143 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2144 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2145 const OffsetOfNode &Node = E->getComponent(I-1);
2146 switch (Node.getKind()) {
2147 case OffsetOfNode::Array:
2148 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2149 break;
2150 case OffsetOfNode::Field:
2151 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2152 break;
2153 case OffsetOfNode::Identifier:
2154 case OffsetOfNode::Base:
2155 continue;
2156 }
2157 }
2158 // Visit the type into which we're computing the offset.
2159 AddTypeLoc(E->getTypeSourceInfo());
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2163 WL.push_back(OverloadExprParts(E, Parent));
2164}
2165void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 EnqueueChildren(E);
2168 if (E->isArgumentType())
2169 AddTypeLoc(E->getArgumentTypeInfo());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(S);
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddStmt(S->getBody());
2176 AddStmt(S->getCond());
2177 AddDecl(S->getConditionVariable());
2178}
2179
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddStmt(W->getBody());
2182 AddStmt(W->getCond());
2183 AddDecl(W->getConditionVariable());
2184}
2185
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 AddTypeLoc(E->getQueriedTypeSourceInfo());
2188}
2189
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddTypeLoc(E->getRhsTypeSourceInfo());
2192 AddTypeLoc(E->getLhsTypeSourceInfo());
2193}
2194
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 for (unsigned I = E->getNumArgs(); I > 0; --I)
2197 AddTypeLoc(E->getArg(I-1));
2198}
2199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 AddTypeLoc(E->getQueriedTypeSourceInfo());
2202}
2203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 EnqueueChildren(E);
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 VisitOverloadExpr(U);
2210 if (!U->isImplicitAccess())
2211 AddStmt(U->getBase());
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 AddStmt(E->getSubExpr());
2215 AddTypeLoc(E->getWrittenTypeInfo());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 WL.push_back(SizeOfPackExprParts(E, Parent));
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 // If the opaque value has a source expression, just transparently
2222 // visit that. This is useful for (e.g.) pseudo-object expressions.
2223 if (Expr *SourceExpr = E->getSourceExpr())
2224 return Visit(SourceExpr);
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 AddStmt(E->getBody());
2228 WL.push_back(LambdaExprParts(E, Parent));
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 // Treat the expression like its syntactic form.
2232 Visit(E->getSyntacticForm());
2233}
2234
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002235void EnqueueVisitor::VisitOMPExecutableDirective(
2236 const OMPExecutableDirective *D) {
2237 EnqueueChildren(D);
2238 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2239 E = D->clauses().end();
2240 I != E; ++I)
2241 EnqueueChildren(*I);
2242}
2243
2244void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2245 VisitOMPExecutableDirective(D);
2246}
2247
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2250}
2251
2252bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2253 if (RegionOfInterest.isValid()) {
2254 SourceRange Range = getRawCursorExtent(C);
2255 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2256 return false;
2257 }
2258 return true;
2259}
2260
2261bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2262 while (!WL.empty()) {
2263 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002264 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002265
2266 // Set the Parent field, then back to its old value once we're done.
2267 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2268
2269 switch (LI.getKind()) {
2270 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 if (!D)
2273 continue;
2274
2275 // For now, perform default visitation for Decls.
2276 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2277 cast<DeclVisit>(&LI)->isFirst())))
2278 return true;
2279
2280 continue;
2281 }
2282 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2283 const ASTTemplateArgumentListInfo *ArgList =
2284 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2285 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2286 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2287 Arg != ArgEnd; ++Arg) {
2288 if (VisitTemplateArgumentLoc(*Arg))
2289 return true;
2290 }
2291 continue;
2292 }
2293 case VisitorJob::TypeLocVisitKind: {
2294 // Perform default visitation for TypeLocs.
2295 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2296 return true;
2297 continue;
2298 }
2299 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 if (LabelStmt *stmt = LS->getStmt()) {
2302 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2303 TU))) {
2304 return true;
2305 }
2306 }
2307 continue;
2308 }
2309
2310 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2311 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2312 if (VisitNestedNameSpecifierLoc(V->get()))
2313 return true;
2314 continue;
2315 }
2316
2317 case VisitorJob::DeclarationNameInfoVisitKind: {
2318 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2319 ->get()))
2320 return true;
2321 continue;
2322 }
2323 case VisitorJob::MemberRefVisitKind: {
2324 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2325 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2326 return true;
2327 continue;
2328 }
2329 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 if (!S)
2332 continue;
2333
2334 // Update the current cursor.
2335 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2336 if (!IsInRegionOfInterest(Cursor))
2337 continue;
2338 switch (Visitor(Cursor, Parent, ClientData)) {
2339 case CXChildVisit_Break: return true;
2340 case CXChildVisit_Continue: break;
2341 case CXChildVisit_Recurse:
2342 if (PostChildrenVisitor)
2343 WL.push_back(PostChildrenVisit(0, Cursor));
2344 EnqueueWorkList(WL, S);
2345 break;
2346 }
2347 continue;
2348 }
2349 case VisitorJob::MemberExprPartsKind: {
2350 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002352
2353 // Visit the nested-name-specifier
2354 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2355 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2356 return true;
2357
2358 // Visit the declaration name.
2359 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2360 return true;
2361
2362 // Visit the explicitly-specified template arguments, if any.
2363 if (M->hasExplicitTemplateArgs()) {
2364 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2365 *ArgEnd = Arg + M->getNumTemplateArgs();
2366 Arg != ArgEnd; ++Arg) {
2367 if (VisitTemplateArgumentLoc(*Arg))
2368 return true;
2369 }
2370 }
2371 continue;
2372 }
2373 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002374 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002375 // Visit nested-name-specifier, if present.
2376 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2377 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2378 return true;
2379 // Visit declaration name.
2380 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2381 return true;
2382 continue;
2383 }
2384 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 // Visit the nested-name-specifier.
2387 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2388 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2389 return true;
2390 // Visit the declaration name.
2391 if (VisitDeclarationNameInfo(O->getNameInfo()))
2392 return true;
2393 // Visit the overloaded declaration reference.
2394 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2395 return true;
2396 continue;
2397 }
2398 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002399 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002400 NamedDecl *Pack = E->getPack();
2401 if (isa<TemplateTypeParmDecl>(Pack)) {
2402 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2403 E->getPackLoc(), TU)))
2404 return true;
2405
2406 continue;
2407 }
2408
2409 if (isa<TemplateTemplateParmDecl>(Pack)) {
2410 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2411 E->getPackLoc(), TU)))
2412 return true;
2413
2414 continue;
2415 }
2416
2417 // Non-type template parameter packs and function parameter packs are
2418 // treated like DeclRefExpr cursors.
2419 continue;
2420 }
2421
2422 case VisitorJob::LambdaExprPartsKind: {
2423 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002424 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002425 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2426 CEnd = E->explicit_capture_end();
2427 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002428 // FIXME: Lambda init-captures.
2429 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002431
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2433 C->getLocation(),
2434 TU)))
2435 return true;
2436 }
2437
2438 // Visit parameters and return type, if present.
2439 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2440 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2441 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2442 // Visit the whole type.
2443 if (Visit(TL))
2444 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002445 } else if (FunctionProtoTypeLoc Proto =
2446 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 if (E->hasExplicitParameters()) {
2448 // Visit parameters.
2449 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2450 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2451 return true;
2452 } else {
2453 // Visit result type.
2454 if (Visit(Proto.getResultLoc()))
2455 return true;
2456 }
2457 }
2458 }
2459 break;
2460 }
2461
2462 case VisitorJob::PostChildrenVisitKind:
2463 if (PostChildrenVisitor(Parent, ClientData))
2464 return true;
2465 break;
2466 }
2467 }
2468 return false;
2469}
2470
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 VisitorWorkList *WL = 0;
2473 if (!WorkListFreeList.empty()) {
2474 WL = WorkListFreeList.back();
2475 WL->clear();
2476 WorkListFreeList.pop_back();
2477 }
2478 else {
2479 WL = new VisitorWorkList();
2480 WorkListCache.push_back(WL);
2481 }
2482 EnqueueWorkList(*WL, S);
2483 bool result = RunVisitorWorkList(*WL);
2484 WorkListFreeList.push_back(WL);
2485 return result;
2486}
2487
2488namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002489typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002490RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2491 const DeclarationNameInfo &NI,
2492 const SourceRange &QLoc,
2493 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2494 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2495 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2496 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2497
2498 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2499
2500 RefNamePieces Pieces;
2501
2502 if (WantQualifier && QLoc.isValid())
2503 Pieces.push_back(QLoc);
2504
2505 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2506 Pieces.push_back(NI.getLoc());
2507
2508 if (WantTemplateArgs && TemplateArgs)
2509 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2510 TemplateArgs->RAngleLoc));
2511
2512 if (Kind == DeclarationName::CXXOperatorName) {
2513 Pieces.push_back(SourceLocation::getFromRawEncoding(
2514 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2515 Pieces.push_back(SourceLocation::getFromRawEncoding(
2516 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2517 }
2518
2519 if (WantSinglePiece) {
2520 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2521 Pieces.clear();
2522 Pieces.push_back(R);
2523 }
2524
2525 return Pieces;
2526}
2527}
2528
2529//===----------------------------------------------------------------------===//
2530// Misc. API hooks.
2531//===----------------------------------------------------------------------===//
2532
2533static llvm::sys::Mutex EnableMultithreadingMutex;
2534static bool EnabledMultithreading;
2535
Chad Rosier05c71aa2013-03-27 18:28:23 +00002536static void fatal_error_handler(void *user_data, const std::string& reason,
2537 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 // Write the result out to stderr avoiding errs() because raw_ostreams can
2539 // call report_fatal_error.
2540 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2541 ::abort();
2542}
2543
2544extern "C" {
2545CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2546 int displayDiagnostics) {
2547 // Disable pretty stack trace functionality, which will otherwise be a very
2548 // poor citizen of the world and set up all sorts of signal handlers.
2549 llvm::DisablePrettyStackTrace = true;
2550
2551 // We use crash recovery to make some of our APIs more reliable, implicitly
2552 // enable it.
2553 llvm::CrashRecoveryContext::Enable();
2554
2555 // Enable support for multithreading in LLVM.
2556 {
2557 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2558 if (!EnabledMultithreading) {
2559 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2560 llvm::llvm_start_multithreaded();
2561 EnabledMultithreading = true;
2562 }
2563 }
2564
2565 CIndexer *CIdxr = new CIndexer();
2566 if (excludeDeclarationsFromPCH)
2567 CIdxr->setOnlyLocalDecls();
2568 if (displayDiagnostics)
2569 CIdxr->setDisplayDiagnostics();
2570
2571 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2572 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2573 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2574 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2575 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2576 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2577
2578 return CIdxr;
2579}
2580
2581void clang_disposeIndex(CXIndex CIdx) {
2582 if (CIdx)
2583 delete static_cast<CIndexer *>(CIdx);
2584}
2585
2586void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2587 if (CIdx)
2588 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2589}
2590
2591unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2592 if (CIdx)
2593 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2594 return 0;
2595}
2596
2597void clang_toggleCrashRecovery(unsigned isEnabled) {
2598 if (isEnabled)
2599 llvm::CrashRecoveryContext::Enable();
2600 else
2601 llvm::CrashRecoveryContext::Disable();
2602}
2603
2604CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2605 const char *ast_filename) {
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002606 if (!CIdx || !ast_filename)
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 return 0;
2608
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002609 LOG_FUNC_SECTION {
2610 *Log << ast_filename;
2611 }
2612
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2614 FileSystemOptions FileSystemOpts;
2615
2616 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2617 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2618 CXXIdx->getOnlyLocalDecls(),
2619 0, 0,
2620 /*CaptureDiagnostics=*/true,
2621 /*AllowPCHWithCompilerErrors=*/true,
2622 /*UserFilesAreVolatile=*/true);
2623 return MakeCXTranslationUnit(CXXIdx, TU);
2624}
2625
2626unsigned clang_defaultEditingTranslationUnitOptions() {
2627 return CXTranslationUnit_PrecompiledPreamble |
2628 CXTranslationUnit_CacheCompletionResults;
2629}
2630
2631CXTranslationUnit
2632clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2633 const char *source_filename,
2634 int num_command_line_args,
2635 const char * const *command_line_args,
2636 unsigned num_unsaved_files,
2637 struct CXUnsavedFile *unsaved_files) {
2638 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2639 return clang_parseTranslationUnit(CIdx, source_filename,
2640 command_line_args, num_command_line_args,
2641 unsaved_files, num_unsaved_files,
2642 Options);
2643}
2644
2645struct ParseTranslationUnitInfo {
2646 CXIndex CIdx;
2647 const char *source_filename;
2648 const char *const *command_line_args;
2649 int num_command_line_args;
2650 struct CXUnsavedFile *unsaved_files;
2651 unsigned num_unsaved_files;
2652 unsigned options;
2653 CXTranslationUnit result;
2654};
2655static void clang_parseTranslationUnit_Impl(void *UserData) {
2656 ParseTranslationUnitInfo *PTUI =
2657 static_cast<ParseTranslationUnitInfo*>(UserData);
2658 CXIndex CIdx = PTUI->CIdx;
2659 const char *source_filename = PTUI->source_filename;
2660 const char * const *command_line_args = PTUI->command_line_args;
2661 int num_command_line_args = PTUI->num_command_line_args;
2662 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2663 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2664 unsigned options = PTUI->options;
2665 PTUI->result = 0;
2666
2667 if (!CIdx)
2668 return;
2669
2670 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2671
2672 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2673 setThreadBackgroundPriority();
2674
2675 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2676 // FIXME: Add a flag for modules.
2677 TranslationUnitKind TUKind
2678 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2679 bool CacheCodeCompetionResults
2680 = options & CXTranslationUnit_CacheCompletionResults;
2681 bool IncludeBriefCommentsInCodeCompletion
2682 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2683 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2684 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2685
2686 // Configure the diagnostics.
2687 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002688 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002689
2690 // Recover resources if we crash before exiting this function.
2691 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2692 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2693 DiagCleanup(Diags.getPtr());
2694
2695 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2696 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2697
2698 // Recover resources if we crash before exiting this function.
2699 llvm::CrashRecoveryContextCleanupRegistrar<
2700 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2701
2702 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2703 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2704 const llvm::MemoryBuffer *Buffer
2705 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2706 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2707 Buffer));
2708 }
2709
2710 OwningPtr<std::vector<const char *> >
2711 Args(new std::vector<const char*>());
2712
2713 // Recover resources if we crash before exiting this method.
2714 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2715 ArgsCleanup(Args.get());
2716
2717 // Since the Clang C library is primarily used by batch tools dealing with
2718 // (often very broken) source code, where spell-checking can have a
2719 // significant negative impact on performance (particularly when
2720 // precompiled headers are involved), we disable it by default.
2721 // Only do this if we haven't found a spell-checking-related argument.
2722 bool FoundSpellCheckingArgument = false;
2723 for (int I = 0; I != num_command_line_args; ++I) {
2724 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2725 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2726 FoundSpellCheckingArgument = true;
2727 break;
2728 }
2729 }
2730 if (!FoundSpellCheckingArgument)
2731 Args->push_back("-fno-spell-checking");
2732
2733 Args->insert(Args->end(), command_line_args,
2734 command_line_args + num_command_line_args);
2735
2736 // The 'source_filename' argument is optional. If the caller does not
2737 // specify it then it is assumed that the source file is specified
2738 // in the actual argument list.
2739 // Put the source file after command_line_args otherwise if '-x' flag is
2740 // present it will be unused.
2741 if (source_filename)
2742 Args->push_back(source_filename);
2743
2744 // Do we need the detailed preprocessing record?
2745 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2746 Args->push_back("-Xclang");
2747 Args->push_back("-detailed-preprocessing-record");
2748 }
2749
2750 unsigned NumErrors = Diags->getClient()->getNumErrors();
2751 OwningPtr<ASTUnit> ErrUnit;
2752 OwningPtr<ASTUnit> Unit(
2753 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2754 /* vector::data() not portable */,
2755 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2756 Diags,
2757 CXXIdx->getClangResourcesPath(),
2758 CXXIdx->getOnlyLocalDecls(),
2759 /*CaptureDiagnostics=*/true,
2760 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2761 RemappedFiles->size(),
2762 /*RemappedFilesKeepOriginalName=*/true,
2763 PrecompilePreamble,
2764 TUKind,
2765 CacheCodeCompetionResults,
2766 IncludeBriefCommentsInCodeCompletion,
2767 /*AllowPCHWithCompilerErrors=*/true,
2768 SkipFunctionBodies,
2769 /*UserFilesAreVolatile=*/true,
2770 ForSerialization,
2771 &ErrUnit));
2772
2773 if (NumErrors != Diags->getClient()->getNumErrors()) {
2774 // Make sure to check that 'Unit' is non-NULL.
2775 if (CXXIdx->getDisplayDiagnostics())
2776 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2777 }
2778
2779 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2780}
2781CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2782 const char *source_filename,
2783 const char * const *command_line_args,
2784 int num_command_line_args,
2785 struct CXUnsavedFile *unsaved_files,
2786 unsigned num_unsaved_files,
2787 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002788 LOG_FUNC_SECTION {
2789 *Log << source_filename << ": ";
2790 for (int i = 0; i != num_command_line_args; ++i)
2791 *Log << command_line_args[i] << " ";
2792 }
2793
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2795 num_command_line_args, unsaved_files,
2796 num_unsaved_files, options, 0 };
2797 llvm::CrashRecoveryContext CRC;
2798
2799 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2800 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2801 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2802 fprintf(stderr, " 'command_line_args' : [");
2803 for (int i = 0; i != num_command_line_args; ++i) {
2804 if (i)
2805 fprintf(stderr, ", ");
2806 fprintf(stderr, "'%s'", command_line_args[i]);
2807 }
2808 fprintf(stderr, "],\n");
2809 fprintf(stderr, " 'unsaved_files' : [");
2810 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2811 if (i)
2812 fprintf(stderr, ", ");
2813 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2814 unsaved_files[i].Length);
2815 }
2816 fprintf(stderr, "],\n");
2817 fprintf(stderr, " 'options' : %d,\n", options);
2818 fprintf(stderr, "}\n");
2819
2820 return 0;
2821 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2822 PrintLibclangResourceUsage(PTUI.result);
2823 }
2824
2825 return PTUI.result;
2826}
2827
2828unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2829 return CXSaveTranslationUnit_None;
2830}
2831
2832namespace {
2833
2834struct SaveTranslationUnitInfo {
2835 CXTranslationUnit TU;
2836 const char *FileName;
2837 unsigned options;
2838 CXSaveError result;
2839};
2840
2841}
2842
2843static void clang_saveTranslationUnit_Impl(void *UserData) {
2844 SaveTranslationUnitInfo *STUI =
2845 static_cast<SaveTranslationUnitInfo*>(UserData);
2846
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002847 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2849 setThreadBackgroundPriority();
2850
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002851 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2853}
2854
2855int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2856 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002857 LOG_FUNC_SECTION {
2858 *Log << TU << ' ' << FileName;
2859 }
2860
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 if (!TU)
2862 return CXSaveError_InvalidTU;
2863
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002864 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2866 if (!CXXUnit->hasSema())
2867 return CXSaveError_InvalidTU;
2868
2869 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2870
2871 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2872 getenv("LIBCLANG_NOTHREADS")) {
2873 clang_saveTranslationUnit_Impl(&STUI);
2874
2875 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2876 PrintLibclangResourceUsage(TU);
2877
2878 return STUI.result;
2879 }
2880
2881 // We have an AST that has invalid nodes due to compiler errors.
2882 // Use a crash recovery thread for protection.
2883
2884 llvm::CrashRecoveryContext CRC;
2885
2886 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2887 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2888 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2889 fprintf(stderr, " 'options' : %d,\n", options);
2890 fprintf(stderr, "}\n");
2891
2892 return CXSaveError_Unknown;
2893
2894 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2895 PrintLibclangResourceUsage(TU);
2896 }
2897
2898 return STUI.result;
2899}
2900
2901void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2902 if (CTUnit) {
2903 // If the translation unit has been marked as unsafe to free, just discard
2904 // it.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002905 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002906 return;
2907
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002908 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002909 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2911 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenkoba82fea2013-01-26 21:39:50 +00002912 delete CTUnit->FormatContext;
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 delete CTUnit;
2914 }
2915}
2916
2917unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2918 return CXReparse_None;
2919}
2920
2921struct ReparseTranslationUnitInfo {
2922 CXTranslationUnit TU;
2923 unsigned num_unsaved_files;
2924 struct CXUnsavedFile *unsaved_files;
2925 unsigned options;
2926 int result;
2927};
2928
2929static void clang_reparseTranslationUnit_Impl(void *UserData) {
2930 ReparseTranslationUnitInfo *RTUI =
2931 static_cast<ReparseTranslationUnitInfo*>(UserData);
2932 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002933 if (!TU)
2934 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00002935
2936 // Reset the associated diagnostics.
2937 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2938 TU->Diagnostics = 0;
2939
2940 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2941 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2942 unsigned options = RTUI->options;
2943 (void) options;
2944 RTUI->result = 1;
2945
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002946 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2948 setThreadBackgroundPriority();
2949
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002950 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2952
2953 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2954 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2955
2956 // Recover resources if we crash before exiting this function.
2957 llvm::CrashRecoveryContextCleanupRegistrar<
2958 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2959
2960 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2961 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2962 const llvm::MemoryBuffer *Buffer
2963 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2964 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2965 Buffer));
2966 }
2967
2968 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2969 RemappedFiles->size()))
2970 RTUI->result = 0;
2971}
2972
2973int clang_reparseTranslationUnit(CXTranslationUnit TU,
2974 unsigned num_unsaved_files,
2975 struct CXUnsavedFile *unsaved_files,
2976 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002977 LOG_FUNC_SECTION {
2978 *Log << TU;
2979 }
2980
Guy Benyei11169dd2012-12-18 14:30:41 +00002981 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2982 options, 0 };
2983
2984 if (getenv("LIBCLANG_NOTHREADS")) {
2985 clang_reparseTranslationUnit_Impl(&RTUI);
2986 return RTUI.result;
2987 }
2988
2989 llvm::CrashRecoveryContext CRC;
2990
2991 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2992 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002993 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002994 return 1;
2995 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2996 PrintLibclangResourceUsage(TU);
2997
2998 return RTUI.result;
2999}
3000
3001
3002CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3003 if (!CTUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003004 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003005
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003006 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003007 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003008}
3009
3010CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003011 if (!TU)
3012 return clang_getNullCursor();
3013
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3016}
3017
3018} // end: extern "C"
3019
3020//===----------------------------------------------------------------------===//
3021// CXFile Operations.
3022//===----------------------------------------------------------------------===//
3023
3024extern "C" {
3025CXString clang_getFileName(CXFile SFile) {
3026 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003027 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003028
3029 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003030 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003031}
3032
3033time_t clang_getFileTime(CXFile SFile) {
3034 if (!SFile)
3035 return 0;
3036
3037 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3038 return FEnt->getModificationTime();
3039}
3040
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003041CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3042 if (!TU)
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 return 0;
3044
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003045 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003046
3047 FileManager &FMgr = CXXUnit->getFileManager();
3048 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3049}
3050
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003051unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3052 if (!TU || !file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 return 0;
3054
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003055 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 FileEntry *FEnt = static_cast<FileEntry *>(file);
3057 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3058 .isFileMultipleIncludeGuarded(FEnt);
3059}
3060
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003061int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3062 if (!file || !outID)
3063 return 1;
3064
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003065 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003066 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3067 outID->data[0] = ID.getDevice();
3068 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003069 outID->data[2] = FEnt->getModificationTime();
3070 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003071}
3072
Guy Benyei11169dd2012-12-18 14:30:41 +00003073} // end: extern "C"
3074
3075//===----------------------------------------------------------------------===//
3076// CXCursor Operations.
3077//===----------------------------------------------------------------------===//
3078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003079static const Decl *getDeclFromExpr(const Stmt *E) {
3080 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 return getDeclFromExpr(CE->getSubExpr());
3082
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003083 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003085 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003087 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003088 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003089 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 if (PRE->isExplicitProperty())
3091 return PRE->getExplicitProperty();
3092 // It could be messaging both getter and setter as in:
3093 // ++myobj.myprop;
3094 // in which case prefer to associate the setter since it is less obvious
3095 // from inspecting the source that the setter is going to get called.
3096 if (PRE->isMessagingSetter())
3097 return PRE->getImplicitPropertySetter();
3098 return PRE->getImplicitPropertyGetter();
3099 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003100 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003102 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 if (Expr *Src = OVE->getSourceExpr())
3104 return getDeclFromExpr(Src);
3105
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003106 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003108 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 if (!CE->isElidable())
3110 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003111 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 return OME->getMethodDecl();
3113
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003114 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003116 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3118 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003119 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3121 isa<ParmVarDecl>(SizeOfPack->getPack()))
3122 return SizeOfPack->getPack();
3123
3124 return 0;
3125}
3126
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003127static SourceLocation getLocationFromExpr(const Expr *E) {
3128 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 return getLocationFromExpr(CE->getSubExpr());
3130
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003131 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003133 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003135 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003137 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003139 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003141 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 return PropRef->getLocation();
3143
3144 return E->getLocStart();
3145}
3146
3147extern "C" {
3148
3149unsigned clang_visitChildren(CXCursor parent,
3150 CXCursorVisitor visitor,
3151 CXClientData client_data) {
3152 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3153 /*VisitPreprocessorLast=*/false);
3154 return CursorVis.VisitChildren(parent);
3155}
3156
3157#ifndef __has_feature
3158#define __has_feature(x) 0
3159#endif
3160#if __has_feature(blocks)
3161typedef enum CXChildVisitResult
3162 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3163
3164static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3165 CXClientData client_data) {
3166 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3167 return block(cursor, parent);
3168}
3169#else
3170// If we are compiled with a compiler that doesn't have native blocks support,
3171// define and call the block manually, so the
3172typedef struct _CXChildVisitResult
3173{
3174 void *isa;
3175 int flags;
3176 int reserved;
3177 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3178 CXCursor);
3179} *CXCursorVisitorBlock;
3180
3181static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3182 CXClientData client_data) {
3183 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3184 return block->invoke(block, cursor, parent);
3185}
3186#endif
3187
3188
3189unsigned clang_visitChildrenWithBlock(CXCursor parent,
3190 CXCursorVisitorBlock block) {
3191 return clang_visitChildren(parent, visitWithBlock, block);
3192}
3193
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003196 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003197
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003198 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ObjCPropertyImplDecl *PropImpl =
3201 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003203 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003204
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003207 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003209 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 }
3211
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003212 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003213 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003214
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003215 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3217 // and returns different names. NamedDecl returns the class name and
3218 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003219 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003220
3221 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003222 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003223
3224 SmallString<1024> S;
3225 llvm::raw_svector_ostream os(S);
3226 ND->printName(os);
3227
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003228 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003229}
3230
3231CXString clang_getCursorSpelling(CXCursor C) {
3232 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003233 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003234
3235 if (clang_isReference(C.kind)) {
3236 switch (C.kind) {
3237 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003238 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003239 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 }
3241 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003242 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003243 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 }
3245 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003246 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003248 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 }
3250 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003251 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003252 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 }
3254 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003255 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 assert(Type && "Missing type decl");
3257
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003258 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 getAsString());
3260 }
3261 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003262 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 assert(Template && "Missing template decl");
3264
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003265 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 }
3267
3268 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003269 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 assert(NS && "Missing namespace decl");
3271
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003272 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 }
3274
3275 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003276 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 assert(Field && "Missing member decl");
3278
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003279 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 }
3281
3282 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003283 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 assert(Label && "Missing label");
3285
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003286 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 }
3288
3289 case CXCursor_OverloadedDeclRef: {
3290 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003291 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3292 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003293 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003294 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003297 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 OverloadedTemplateStorage *Ovl
3299 = Storage.get<OverloadedTemplateStorage*>();
3300 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003301 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003302 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303 }
3304
3305 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003306 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 assert(Var && "Missing variable decl");
3308
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003309 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 }
3311
3312 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003313 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 }
3315 }
3316
3317 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 if (D)
3320 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003321 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 }
3323
3324 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003325 const Stmt *S = getCursorStmt(C);
3326 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003327 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003329 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 }
3331
3332 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003333 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 ->getNameStart());
3335
3336 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003337 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 ->getNameStart());
3339
3340 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
3343 if (clang_isDeclaration(C.kind))
3344 return getDeclSpelling(getCursorDecl(C));
3345
3346 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003347 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003348 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350
3351 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003352 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003353 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003356 if (C.kind == CXCursor_PackedAttr) {
3357 return cxstring::createRef("packed");
3358 }
3359
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003360 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003361}
3362
3363CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3364 unsigned pieceIndex,
3365 unsigned options) {
3366 if (clang_Cursor_isNull(C))
3367 return clang_getNullRange();
3368
3369 ASTContext &Ctx = getCursorContext(C);
3370
3371 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003372 const Stmt *S = getCursorStmt(C);
3373 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 if (pieceIndex > 0)
3375 return clang_getNullRange();
3376 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3377 }
3378
3379 return clang_getNullRange();
3380 }
3381
3382 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003383 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3385 if (pieceIndex >= ME->getNumSelectorLocs())
3386 return clang_getNullRange();
3387 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3388 }
3389 }
3390
3391 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3392 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3395 if (pieceIndex >= MD->getNumSelectorLocs())
3396 return clang_getNullRange();
3397 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3398 }
3399 }
3400
3401 if (C.kind == CXCursor_ObjCCategoryDecl ||
3402 C.kind == CXCursor_ObjCCategoryImplDecl) {
3403 if (pieceIndex > 0)
3404 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003405 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3407 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003408 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3410 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3411 }
3412
3413 if (C.kind == CXCursor_ModuleImportDecl) {
3414 if (pieceIndex > 0)
3415 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003416 if (const ImportDecl *ImportD =
3417 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3419 if (!Locs.empty())
3420 return cxloc::translateSourceRange(Ctx,
3421 SourceRange(Locs.front(), Locs.back()));
3422 }
3423 return clang_getNullRange();
3424 }
3425
3426 // FIXME: A CXCursor_InclusionDirective should give the location of the
3427 // filename, but we don't keep track of this.
3428
3429 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3430 // but we don't keep track of this.
3431
3432 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3433 // but we don't keep track of this.
3434
3435 // Default handling, give the location of the cursor.
3436
3437 if (pieceIndex > 0)
3438 return clang_getNullRange();
3439
3440 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3441 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3442 return cxloc::translateSourceRange(Ctx, Loc);
3443}
3444
3445CXString clang_getCursorDisplayName(CXCursor C) {
3446 if (!clang_isDeclaration(C.kind))
3447 return clang_getCursorSpelling(C);
3448
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003449 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003452
3453 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003454 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 D = FunTmpl->getTemplatedDecl();
3456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003457 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 SmallString<64> Str;
3459 llvm::raw_svector_ostream OS(Str);
3460 OS << *Function;
3461 if (Function->getPrimaryTemplate())
3462 OS << "<>";
3463 OS << "(";
3464 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3465 if (I)
3466 OS << ", ";
3467 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3468 }
3469
3470 if (Function->isVariadic()) {
3471 if (Function->getNumParams())
3472 OS << ", ";
3473 OS << "...";
3474 }
3475 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003476 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 }
3478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 SmallString<64> Str;
3481 llvm::raw_svector_ostream OS(Str);
3482 OS << *ClassTemplate;
3483 OS << "<";
3484 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3485 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3486 if (I)
3487 OS << ", ";
3488
3489 NamedDecl *Param = Params->getParam(I);
3490 if (Param->getIdentifier()) {
3491 OS << Param->getIdentifier()->getName();
3492 continue;
3493 }
3494
3495 // There is no parameter name, which makes this tricky. Try to come up
3496 // with something useful that isn't too long.
3497 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3498 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3499 else if (NonTypeTemplateParmDecl *NTTP
3500 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3501 OS << NTTP->getType().getAsString(Policy);
3502 else
3503 OS << "template<...> class";
3504 }
3505
3506 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003507 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 }
3509
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3512 // If the type was explicitly written, use that.
3513 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003514 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003515
Benjamin Kramer9170e912013-02-22 15:46:01 +00003516 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 llvm::raw_svector_ostream OS(Str);
3518 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003519 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 ClassSpec->getTemplateArgs().data(),
3521 ClassSpec->getTemplateArgs().size(),
3522 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003523 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 }
3525
3526 return clang_getCursorSpelling(C);
3527}
3528
3529CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3530 switch (Kind) {
3531 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003536 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003540 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003546 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003554 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003564 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003568 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003572 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003576 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003580 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003586 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003588 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003592 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003596 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003598 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003600 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003604 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003606 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003608 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003659 case CXCursor_ObjCSelfExpr:
3660 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003777 case CXCursor_PackedAttr:
3778 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003827 case CXCursor_OMPParallelDirective:
3828 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 }
3830
3831 llvm_unreachable("Unhandled CXCursorKind");
3832}
3833
3834struct GetCursorData {
3835 SourceLocation TokenBeginLoc;
3836 bool PointsAtMacroArgExpansion;
3837 bool VisitedObjCPropertyImplDecl;
3838 SourceLocation VisitedDeclaratorDeclStartLoc;
3839 CXCursor &BestCursor;
3840
3841 GetCursorData(SourceManager &SM,
3842 SourceLocation tokenBegin, CXCursor &outputCursor)
3843 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3844 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3845 VisitedObjCPropertyImplDecl = false;
3846 }
3847};
3848
3849static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3850 CXCursor parent,
3851 CXClientData client_data) {
3852 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3853 CXCursor *BestCursor = &Data->BestCursor;
3854
3855 // If we point inside a macro argument we should provide info of what the
3856 // token is so use the actual cursor, don't replace it with a macro expansion
3857 // cursor.
3858 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3859 return CXChildVisit_Recurse;
3860
3861 if (clang_isDeclaration(cursor.kind)) {
3862 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003863 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3865 if (MD->isImplicit())
3866 return CXChildVisit_Break;
3867
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003868 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3870 // Check that when we have multiple @class references in the same line,
3871 // that later ones do not override the previous ones.
3872 // If we have:
3873 // @class Foo, Bar;
3874 // source ranges for both start at '@', so 'Bar' will end up overriding
3875 // 'Foo' even though the cursor location was at 'Foo'.
3876 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3877 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003878 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3880 if (PrevID != ID &&
3881 !PrevID->isThisDeclarationADefinition() &&
3882 !ID->isThisDeclarationADefinition())
3883 return CXChildVisit_Break;
3884 }
3885
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003886 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3888 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3889 // Check that when we have multiple declarators in the same line,
3890 // that later ones do not override the previous ones.
3891 // If we have:
3892 // int Foo, Bar;
3893 // source ranges for both start at 'int', so 'Bar' will end up overriding
3894 // 'Foo' even though the cursor location was at 'Foo'.
3895 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3896 return CXChildVisit_Break;
3897 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3898
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003899 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3901 (void)PropImp;
3902 // Check that when we have multiple @synthesize in the same line,
3903 // that later ones do not override the previous ones.
3904 // If we have:
3905 // @synthesize Foo, Bar;
3906 // source ranges for both start at '@', so 'Bar' will end up overriding
3907 // 'Foo' even though the cursor location was at 'Foo'.
3908 if (Data->VisitedObjCPropertyImplDecl)
3909 return CXChildVisit_Break;
3910 Data->VisitedObjCPropertyImplDecl = true;
3911 }
3912 }
3913
3914 if (clang_isExpression(cursor.kind) &&
3915 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003916 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 // Avoid having the cursor of an expression replace the declaration cursor
3918 // when the expression source range overlaps the declaration range.
3919 // This can happen for C++ constructor expressions whose range generally
3920 // include the variable declaration, e.g.:
3921 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3922 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3923 D->getLocation() == Data->TokenBeginLoc)
3924 return CXChildVisit_Break;
3925 }
3926 }
3927
3928 // If our current best cursor is the construction of a temporary object,
3929 // don't replace that cursor with a type reference, because we want
3930 // clang_getCursor() to point at the constructor.
3931 if (clang_isExpression(BestCursor->kind) &&
3932 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3933 cursor.kind == CXCursor_TypeRef) {
3934 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3935 // as having the actual point on the type reference.
3936 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3937 return CXChildVisit_Recurse;
3938 }
3939
3940 *BestCursor = cursor;
3941 return CXChildVisit_Recurse;
3942}
3943
3944CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3945 if (!TU)
3946 return clang_getNullCursor();
3947
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003948 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3950
3951 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3952 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3953
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003954 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 CXFile SearchFile;
3956 unsigned SearchLine, SearchColumn;
3957 CXFile ResultFile;
3958 unsigned ResultLine, ResultColumn;
3959 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3960 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3961 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3962
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003963 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3964 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 &ResultColumn, 0);
3966 SearchFileName = clang_getFileName(SearchFile);
3967 ResultFileName = clang_getFileName(ResultFile);
3968 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3969 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003970 *Log << llvm::format("(%s:%d:%d) = %s",
3971 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3972 clang_getCString(KindSpelling))
3973 << llvm::format("(%s:%d:%d):%s%s",
3974 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3975 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 clang_disposeString(SearchFileName);
3977 clang_disposeString(ResultFileName);
3978 clang_disposeString(KindSpelling);
3979 clang_disposeString(USR);
3980
3981 CXCursor Definition = clang_getCursorDefinition(Result);
3982 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3983 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3984 CXString DefinitionKindSpelling
3985 = clang_getCursorKindSpelling(Definition.kind);
3986 CXFile DefinitionFile;
3987 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003988 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 &DefinitionLine, &DefinitionColumn, 0);
3990 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003991 *Log << llvm::format(" -> %s(%s:%d:%d)",
3992 clang_getCString(DefinitionKindSpelling),
3993 clang_getCString(DefinitionFileName),
3994 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 clang_disposeString(DefinitionFileName);
3996 clang_disposeString(DefinitionKindSpelling);
3997 }
3998 }
3999
4000 return Result;
4001}
4002
4003CXCursor clang_getNullCursor(void) {
4004 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4005}
4006
4007unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004008 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4009 // can't set consistently. For example, when visiting a DeclStmt we will set
4010 // it but we don't set it on the result of clang_getCursorDefinition for
4011 // a reference of the same declaration.
4012 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4013 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4014 // to provide that kind of info.
4015 if (clang_isDeclaration(X.kind))
4016 X.data[1] = 0;
4017 if (clang_isDeclaration(Y.kind))
4018 Y.data[1] = 0;
4019
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 return X == Y;
4021}
4022
4023unsigned clang_hashCursor(CXCursor C) {
4024 unsigned Index = 0;
4025 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4026 Index = 1;
4027
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004028 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 std::make_pair(C.kind, C.data[Index]));
4030}
4031
4032unsigned clang_isInvalid(enum CXCursorKind K) {
4033 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4034}
4035
4036unsigned clang_isDeclaration(enum CXCursorKind K) {
4037 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4038 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4039}
4040
4041unsigned clang_isReference(enum CXCursorKind K) {
4042 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4043}
4044
4045unsigned clang_isExpression(enum CXCursorKind K) {
4046 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4047}
4048
4049unsigned clang_isStatement(enum CXCursorKind K) {
4050 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4051}
4052
4053unsigned clang_isAttribute(enum CXCursorKind K) {
4054 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4055}
4056
4057unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4058 return K == CXCursor_TranslationUnit;
4059}
4060
4061unsigned clang_isPreprocessing(enum CXCursorKind K) {
4062 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4063}
4064
4065unsigned clang_isUnexposed(enum CXCursorKind K) {
4066 switch (K) {
4067 case CXCursor_UnexposedDecl:
4068 case CXCursor_UnexposedExpr:
4069 case CXCursor_UnexposedStmt:
4070 case CXCursor_UnexposedAttr:
4071 return true;
4072 default:
4073 return false;
4074 }
4075}
4076
4077CXCursorKind clang_getCursorKind(CXCursor C) {
4078 return C.kind;
4079}
4080
4081CXSourceLocation clang_getCursorLocation(CXCursor C) {
4082 if (clang_isReference(C.kind)) {
4083 switch (C.kind) {
4084 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004085 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 = getCursorObjCSuperClassRef(C);
4087 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4088 }
4089
4090 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004091 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 = getCursorObjCProtocolRef(C);
4093 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4094 }
4095
4096 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004097 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 = getCursorObjCClassRef(C);
4099 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4100 }
4101
4102 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004103 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4105 }
4106
4107 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004108 std::pair<const TemplateDecl *, SourceLocation> P =
4109 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4111 }
4112
4113 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004114 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4116 }
4117
4118 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004119 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4121 }
4122
4123 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004124 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4126 }
4127
4128 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004129 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 if (!BaseSpec)
4131 return clang_getNullLocation();
4132
4133 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4134 return cxloc::translateSourceLocation(getCursorContext(C),
4135 TSInfo->getTypeLoc().getBeginLoc());
4136
4137 return cxloc::translateSourceLocation(getCursorContext(C),
4138 BaseSpec->getLocStart());
4139 }
4140
4141 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004142 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4144 }
4145
4146 case CXCursor_OverloadedDeclRef:
4147 return cxloc::translateSourceLocation(getCursorContext(C),
4148 getCursorOverloadedDeclRef(C).second);
4149
4150 default:
4151 // FIXME: Need a way to enumerate all non-reference cases.
4152 llvm_unreachable("Missed a reference kind");
4153 }
4154 }
4155
4156 if (clang_isExpression(C.kind))
4157 return cxloc::translateSourceLocation(getCursorContext(C),
4158 getLocationFromExpr(getCursorExpr(C)));
4159
4160 if (clang_isStatement(C.kind))
4161 return cxloc::translateSourceLocation(getCursorContext(C),
4162 getCursorStmt(C)->getLocStart());
4163
4164 if (C.kind == CXCursor_PreprocessingDirective) {
4165 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4166 return cxloc::translateSourceLocation(getCursorContext(C), L);
4167 }
4168
4169 if (C.kind == CXCursor_MacroExpansion) {
4170 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004171 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 return cxloc::translateSourceLocation(getCursorContext(C), L);
4173 }
4174
4175 if (C.kind == CXCursor_MacroDefinition) {
4176 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4177 return cxloc::translateSourceLocation(getCursorContext(C), L);
4178 }
4179
4180 if (C.kind == CXCursor_InclusionDirective) {
4181 SourceLocation L
4182 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4183 return cxloc::translateSourceLocation(getCursorContext(C), L);
4184 }
4185
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004186 if (clang_isAttribute(C.kind)) {
4187 SourceLocation L
4188 = cxcursor::getCursorAttr(C)->getLocation();
4189 return cxloc::translateSourceLocation(getCursorContext(C), L);
4190 }
4191
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 if (!clang_isDeclaration(C.kind))
4193 return clang_getNullLocation();
4194
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004195 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 if (!D)
4197 return clang_getNullLocation();
4198
4199 SourceLocation Loc = D->getLocation();
4200 // FIXME: Multiple variables declared in a single declaration
4201 // currently lack the information needed to correctly determine their
4202 // ranges when accounting for the type-specifier. We use context
4203 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4204 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004205 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 if (!cxcursor::isFirstInDeclGroup(C))
4207 Loc = VD->getLocation();
4208 }
4209
4210 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004211 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 Loc = MD->getSelectorStartLoc();
4213
4214 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4215}
4216
4217} // end extern "C"
4218
4219CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4220 assert(TU);
4221
4222 // Guard against an invalid SourceLocation, or we may assert in one
4223 // of the following calls.
4224 if (SLoc.isInvalid())
4225 return clang_getNullCursor();
4226
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004227 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228
4229 // Translate the given source location to make it point at the beginning of
4230 // the token under the cursor.
4231 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4232 CXXUnit->getASTContext().getLangOpts());
4233
4234 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4235 if (SLoc.isValid()) {
4236 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4237 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4238 /*VisitPreprocessorLast=*/true,
4239 /*VisitIncludedEntities=*/false,
4240 SourceLocation(SLoc));
4241 CursorVis.visitFileRegion();
4242 }
4243
4244 return Result;
4245}
4246
4247static SourceRange getRawCursorExtent(CXCursor C) {
4248 if (clang_isReference(C.kind)) {
4249 switch (C.kind) {
4250 case CXCursor_ObjCSuperClassRef:
4251 return getCursorObjCSuperClassRef(C).second;
4252
4253 case CXCursor_ObjCProtocolRef:
4254 return getCursorObjCProtocolRef(C).second;
4255
4256 case CXCursor_ObjCClassRef:
4257 return getCursorObjCClassRef(C).second;
4258
4259 case CXCursor_TypeRef:
4260 return getCursorTypeRef(C).second;
4261
4262 case CXCursor_TemplateRef:
4263 return getCursorTemplateRef(C).second;
4264
4265 case CXCursor_NamespaceRef:
4266 return getCursorNamespaceRef(C).second;
4267
4268 case CXCursor_MemberRef:
4269 return getCursorMemberRef(C).second;
4270
4271 case CXCursor_CXXBaseSpecifier:
4272 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4273
4274 case CXCursor_LabelRef:
4275 return getCursorLabelRef(C).second;
4276
4277 case CXCursor_OverloadedDeclRef:
4278 return getCursorOverloadedDeclRef(C).second;
4279
4280 case CXCursor_VariableRef:
4281 return getCursorVariableRef(C).second;
4282
4283 default:
4284 // FIXME: Need a way to enumerate all non-reference cases.
4285 llvm_unreachable("Missed a reference kind");
4286 }
4287 }
4288
4289 if (clang_isExpression(C.kind))
4290 return getCursorExpr(C)->getSourceRange();
4291
4292 if (clang_isStatement(C.kind))
4293 return getCursorStmt(C)->getSourceRange();
4294
4295 if (clang_isAttribute(C.kind))
4296 return getCursorAttr(C)->getRange();
4297
4298 if (C.kind == CXCursor_PreprocessingDirective)
4299 return cxcursor::getCursorPreprocessingDirective(C);
4300
4301 if (C.kind == CXCursor_MacroExpansion) {
4302 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004303 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 return TU->mapRangeFromPreamble(Range);
4305 }
4306
4307 if (C.kind == CXCursor_MacroDefinition) {
4308 ASTUnit *TU = getCursorASTUnit(C);
4309 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4310 return TU->mapRangeFromPreamble(Range);
4311 }
4312
4313 if (C.kind == CXCursor_InclusionDirective) {
4314 ASTUnit *TU = getCursorASTUnit(C);
4315 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4316 return TU->mapRangeFromPreamble(Range);
4317 }
4318
4319 if (C.kind == CXCursor_TranslationUnit) {
4320 ASTUnit *TU = getCursorASTUnit(C);
4321 FileID MainID = TU->getSourceManager().getMainFileID();
4322 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4323 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4324 return SourceRange(Start, End);
4325 }
4326
4327 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004328 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 if (!D)
4330 return SourceRange();
4331
4332 SourceRange R = D->getSourceRange();
4333 // FIXME: Multiple variables declared in a single declaration
4334 // currently lack the information needed to correctly determine their
4335 // ranges when accounting for the type-specifier. We use context
4336 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4337 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004338 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 if (!cxcursor::isFirstInDeclGroup(C))
4340 R.setBegin(VD->getLocation());
4341 }
4342 return R;
4343 }
4344 return SourceRange();
4345}
4346
4347/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4348/// the decl-specifier-seq for declarations.
4349static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4350 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004351 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 if (!D)
4353 return SourceRange();
4354
4355 SourceRange R = D->getSourceRange();
4356
4357 // Adjust the start of the location for declarations preceded by
4358 // declaration specifiers.
4359 SourceLocation StartLoc;
4360 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4361 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4362 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004363 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4365 StartLoc = TI->getTypeLoc().getLocStart();
4366 }
4367
4368 if (StartLoc.isValid() && R.getBegin().isValid() &&
4369 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4370 R.setBegin(StartLoc);
4371
4372 // FIXME: Multiple variables declared in a single declaration
4373 // currently lack the information needed to correctly determine their
4374 // ranges when accounting for the type-specifier. We use context
4375 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4376 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004377 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 if (!cxcursor::isFirstInDeclGroup(C))
4379 R.setBegin(VD->getLocation());
4380 }
4381
4382 return R;
4383 }
4384
4385 return getRawCursorExtent(C);
4386}
4387
4388extern "C" {
4389
4390CXSourceRange clang_getCursorExtent(CXCursor C) {
4391 SourceRange R = getRawCursorExtent(C);
4392 if (R.isInvalid())
4393 return clang_getNullRange();
4394
4395 return cxloc::translateSourceRange(getCursorContext(C), R);
4396}
4397
4398CXCursor clang_getCursorReferenced(CXCursor C) {
4399 if (clang_isInvalid(C.kind))
4400 return clang_getNullCursor();
4401
4402 CXTranslationUnit tu = getCursorTU(C);
4403 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004404 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 if (!D)
4406 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004409 if (const ObjCPropertyImplDecl *PropImpl =
4410 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4412 return MakeCXCursor(Property, tu);
4413
4414 return C;
4415 }
4416
4417 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004418 const Expr *E = getCursorExpr(C);
4419 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 if (D) {
4421 CXCursor declCursor = MakeCXCursor(D, tu);
4422 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4423 declCursor);
4424 return declCursor;
4425 }
4426
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004427 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 return MakeCursorOverloadedDeclRef(Ovl, tu);
4429
4430 return clang_getNullCursor();
4431 }
4432
4433 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004434 const Stmt *S = getCursorStmt(C);
4435 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 if (LabelDecl *label = Goto->getLabel())
4437 if (LabelStmt *labelS = label->getStmt())
4438 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4439
4440 return clang_getNullCursor();
4441 }
4442
4443 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004444 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 return MakeMacroDefinitionCursor(Def, tu);
4446 }
4447
4448 if (!clang_isReference(C.kind))
4449 return clang_getNullCursor();
4450
4451 switch (C.kind) {
4452 case CXCursor_ObjCSuperClassRef:
4453 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4454
4455 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004456 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4457 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 return MakeCXCursor(Def, tu);
4459
4460 return MakeCXCursor(Prot, tu);
4461 }
4462
4463 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004464 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4465 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 return MakeCXCursor(Def, tu);
4467
4468 return MakeCXCursor(Class, tu);
4469 }
4470
4471 case CXCursor_TypeRef:
4472 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4473
4474 case CXCursor_TemplateRef:
4475 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4476
4477 case CXCursor_NamespaceRef:
4478 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4479
4480 case CXCursor_MemberRef:
4481 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4482
4483 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004484 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4486 tu ));
4487 }
4488
4489 case CXCursor_LabelRef:
4490 // FIXME: We end up faking the "parent" declaration here because we
4491 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004492 return MakeCXCursor(getCursorLabelRef(C).first,
4493 cxtu::getASTUnit(tu)->getASTContext()
4494 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 tu);
4496
4497 case CXCursor_OverloadedDeclRef:
4498 return C;
4499
4500 case CXCursor_VariableRef:
4501 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4502
4503 default:
4504 // We would prefer to enumerate all non-reference cursor kinds here.
4505 llvm_unreachable("Unhandled reference cursor kind");
4506 }
4507}
4508
4509CXCursor clang_getCursorDefinition(CXCursor C) {
4510 if (clang_isInvalid(C.kind))
4511 return clang_getNullCursor();
4512
4513 CXTranslationUnit TU = getCursorTU(C);
4514
4515 bool WasReference = false;
4516 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4517 C = clang_getCursorReferenced(C);
4518 WasReference = true;
4519 }
4520
4521 if (C.kind == CXCursor_MacroExpansion)
4522 return clang_getCursorReferenced(C);
4523
4524 if (!clang_isDeclaration(C.kind))
4525 return clang_getNullCursor();
4526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004527 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 if (!D)
4529 return clang_getNullCursor();
4530
4531 switch (D->getKind()) {
4532 // Declaration kinds that don't really separate the notions of
4533 // declaration and definition.
4534 case Decl::Namespace:
4535 case Decl::Typedef:
4536 case Decl::TypeAlias:
4537 case Decl::TypeAliasTemplate:
4538 case Decl::TemplateTypeParm:
4539 case Decl::EnumConstant:
4540 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004541 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 case Decl::IndirectField:
4543 case Decl::ObjCIvar:
4544 case Decl::ObjCAtDefsField:
4545 case Decl::ImplicitParam:
4546 case Decl::ParmVar:
4547 case Decl::NonTypeTemplateParm:
4548 case Decl::TemplateTemplateParm:
4549 case Decl::ObjCCategoryImpl:
4550 case Decl::ObjCImplementation:
4551 case Decl::AccessSpec:
4552 case Decl::LinkageSpec:
4553 case Decl::ObjCPropertyImpl:
4554 case Decl::FileScopeAsm:
4555 case Decl::StaticAssert:
4556 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004557 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 case Decl::Label: // FIXME: Is this right??
4559 case Decl::ClassScopeFunctionSpecialization:
4560 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004561 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 return C;
4563
4564 // Declaration kinds that don't make any sense here, but are
4565 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004566 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case Decl::TranslationUnit:
4568 break;
4569
4570 // Declaration kinds for which the definition is not resolvable.
4571 case Decl::UnresolvedUsingTypename:
4572 case Decl::UnresolvedUsingValue:
4573 break;
4574
4575 case Decl::UsingDirective:
4576 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4577 TU);
4578
4579 case Decl::NamespaceAlias:
4580 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4581
4582 case Decl::Enum:
4583 case Decl::Record:
4584 case Decl::CXXRecord:
4585 case Decl::ClassTemplateSpecialization:
4586 case Decl::ClassTemplatePartialSpecialization:
4587 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4588 return MakeCXCursor(Def, TU);
4589 return clang_getNullCursor();
4590
4591 case Decl::Function:
4592 case Decl::CXXMethod:
4593 case Decl::CXXConstructor:
4594 case Decl::CXXDestructor:
4595 case Decl::CXXConversion: {
4596 const FunctionDecl *Def = 0;
4597 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004598 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 return clang_getNullCursor();
4600 }
4601
Larisse Voufo39a1e502013-08-06 01:03:05 +00004602 case Decl::Var:
4603 case Decl::VarTemplateSpecialization:
4604 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004606 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 return MakeCXCursor(Def, TU);
4608 return clang_getNullCursor();
4609 }
4610
4611 case Decl::FunctionTemplate: {
4612 const FunctionDecl *Def = 0;
4613 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4614 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4615 return clang_getNullCursor();
4616 }
4617
4618 case Decl::ClassTemplate: {
4619 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4620 ->getDefinition())
4621 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4622 TU);
4623 return clang_getNullCursor();
4624 }
4625
Larisse Voufo39a1e502013-08-06 01:03:05 +00004626 case Decl::VarTemplate: {
4627 if (VarDecl *Def =
4628 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4629 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4630 return clang_getNullCursor();
4631 }
4632
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case Decl::Using:
4634 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4635 D->getLocation(), TU);
4636
4637 case Decl::UsingShadow:
4638 return clang_getCursorDefinition(
4639 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4640 TU));
4641
4642 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004643 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 if (Method->isThisDeclarationADefinition())
4645 return C;
4646
4647 // Dig out the method definition in the associated
4648 // @implementation, if we have it.
4649 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004650 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4652 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4653 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4654 Method->isInstanceMethod()))
4655 if (Def->isThisDeclarationADefinition())
4656 return MakeCXCursor(Def, TU);
4657
4658 return clang_getNullCursor();
4659 }
4660
4661 case Decl::ObjCCategory:
4662 if (ObjCCategoryImplDecl *Impl
4663 = cast<ObjCCategoryDecl>(D)->getImplementation())
4664 return MakeCXCursor(Impl, TU);
4665 return clang_getNullCursor();
4666
4667 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004668 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 return MakeCXCursor(Def, TU);
4670 return clang_getNullCursor();
4671
4672 case Decl::ObjCInterface: {
4673 // There are two notions of a "definition" for an Objective-C
4674 // class: the interface and its implementation. When we resolved a
4675 // reference to an Objective-C class, produce the @interface as
4676 // the definition; when we were provided with the interface,
4677 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004678 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004680 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 return MakeCXCursor(Def, TU);
4682 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4683 return MakeCXCursor(Impl, TU);
4684 return clang_getNullCursor();
4685 }
4686
4687 case Decl::ObjCProperty:
4688 // FIXME: We don't really know where to find the
4689 // ObjCPropertyImplDecls that implement this property.
4690 return clang_getNullCursor();
4691
4692 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004693 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004695 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 return MakeCXCursor(Def, TU);
4697
4698 return clang_getNullCursor();
4699
4700 case Decl::Friend:
4701 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4702 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4703 return clang_getNullCursor();
4704
4705 case Decl::FriendTemplate:
4706 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4707 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4708 return clang_getNullCursor();
4709 }
4710
4711 return clang_getNullCursor();
4712}
4713
4714unsigned clang_isCursorDefinition(CXCursor C) {
4715 if (!clang_isDeclaration(C.kind))
4716 return 0;
4717
4718 return clang_getCursorDefinition(C) == C;
4719}
4720
4721CXCursor clang_getCanonicalCursor(CXCursor C) {
4722 if (!clang_isDeclaration(C.kind))
4723 return C;
4724
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004725 if (const Decl *D = getCursorDecl(C)) {
4726 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4728 return MakeCXCursor(CatD, getCursorTU(C));
4729
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004730 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4731 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 return MakeCXCursor(IFD, getCursorTU(C));
4733
4734 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4735 }
4736
4737 return C;
4738}
4739
4740int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4741 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4742}
4743
4744unsigned clang_getNumOverloadedDecls(CXCursor C) {
4745 if (C.kind != CXCursor_OverloadedDeclRef)
4746 return 0;
4747
4748 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004749 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 return E->getNumDecls();
4751
4752 if (OverloadedTemplateStorage *S
4753 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4754 return S->size();
4755
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004756 const Decl *D = Storage.get<const Decl *>();
4757 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 return Using->shadow_size();
4759
4760 return 0;
4761}
4762
4763CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4764 if (cursor.kind != CXCursor_OverloadedDeclRef)
4765 return clang_getNullCursor();
4766
4767 if (index >= clang_getNumOverloadedDecls(cursor))
4768 return clang_getNullCursor();
4769
4770 CXTranslationUnit TU = getCursorTU(cursor);
4771 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004772 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 return MakeCXCursor(E->decls_begin()[index], TU);
4774
4775 if (OverloadedTemplateStorage *S
4776 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4777 return MakeCXCursor(S->begin()[index], TU);
4778
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004779 const Decl *D = Storage.get<const Decl *>();
4780 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 // FIXME: This is, unfortunately, linear time.
4782 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4783 std::advance(Pos, index);
4784 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4785 }
4786
4787 return clang_getNullCursor();
4788}
4789
4790void clang_getDefinitionSpellingAndExtent(CXCursor C,
4791 const char **startBuf,
4792 const char **endBuf,
4793 unsigned *startLine,
4794 unsigned *startColumn,
4795 unsigned *endLine,
4796 unsigned *endColumn) {
4797 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004798 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4800
4801 SourceManager &SM = FD->getASTContext().getSourceManager();
4802 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4803 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4804 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4805 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4806 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4807 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4808}
4809
4810
4811CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4812 unsigned PieceIndex) {
4813 RefNamePieces Pieces;
4814
4815 switch (C.kind) {
4816 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004817 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4819 E->getQualifierLoc().getSourceRange());
4820 break;
4821
4822 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004823 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4825 E->getQualifierLoc().getSourceRange(),
4826 E->getOptionalExplicitTemplateArgs());
4827 break;
4828
4829 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004830 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004832 const Expr *Callee = OCE->getCallee();
4833 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 Callee = ICE->getSubExpr();
4835
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004836 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4838 DRE->getQualifierLoc().getSourceRange());
4839 }
4840 break;
4841
4842 default:
4843 break;
4844 }
4845
4846 if (Pieces.empty()) {
4847 if (PieceIndex == 0)
4848 return clang_getCursorExtent(C);
4849 } else if (PieceIndex < Pieces.size()) {
4850 SourceRange R = Pieces[PieceIndex];
4851 if (R.isValid())
4852 return cxloc::translateSourceRange(getCursorContext(C), R);
4853 }
4854
4855 return clang_getNullRange();
4856}
4857
4858void clang_enableStackTraces(void) {
4859 llvm::sys::PrintStackTraceOnErrorSignal();
4860}
4861
4862void clang_executeOnThread(void (*fn)(void*), void *user_data,
4863 unsigned stack_size) {
4864 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4865}
4866
4867} // end: extern "C"
4868
4869//===----------------------------------------------------------------------===//
4870// Token-based Operations.
4871//===----------------------------------------------------------------------===//
4872
4873/* CXToken layout:
4874 * int_data[0]: a CXTokenKind
4875 * int_data[1]: starting token location
4876 * int_data[2]: token length
4877 * int_data[3]: reserved
4878 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4879 * otherwise unused.
4880 */
4881extern "C" {
4882
4883CXTokenKind clang_getTokenKind(CXToken CXTok) {
4884 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4885}
4886
4887CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4888 switch (clang_getTokenKind(CXTok)) {
4889 case CXToken_Identifier:
4890 case CXToken_Keyword:
4891 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004892 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 ->getNameStart());
4894
4895 case CXToken_Literal: {
4896 // We have stashed the starting pointer in the ptr_data field. Use it.
4897 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004898 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 }
4900
4901 case CXToken_Punctuation:
4902 case CXToken_Comment:
4903 break;
4904 }
4905
4906 // We have to find the starting buffer pointer the hard way, by
4907 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004908 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004909 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004910 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004911
4912 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4913 std::pair<FileID, unsigned> LocInfo
4914 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4915 bool Invalid = false;
4916 StringRef Buffer
4917 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4918 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004919 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004920
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004921 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004922}
4923
4924CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004925 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 if (!CXXUnit)
4927 return clang_getNullLocation();
4928
4929 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4930 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4931}
4932
4933CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004934 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 if (!CXXUnit)
4936 return clang_getNullRange();
4937
4938 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4939 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4940}
4941
4942static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4943 SmallVectorImpl<CXToken> &CXTokens) {
4944 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4945 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004946 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00004948 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00004949
4950 // Cannot tokenize across files.
4951 if (BeginLocInfo.first != EndLocInfo.first)
4952 return;
4953
4954 // Create a lexer
4955 bool Invalid = false;
4956 StringRef Buffer
4957 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4958 if (Invalid)
4959 return;
4960
4961 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4962 CXXUnit->getASTContext().getLangOpts(),
4963 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4964 Lex.SetCommentRetentionState(true);
4965
4966 // Lex tokens until we hit the end of the range.
4967 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4968 Token Tok;
4969 bool previousWasAt = false;
4970 do {
4971 // Lex the next token
4972 Lex.LexFromRawLexer(Tok);
4973 if (Tok.is(tok::eof))
4974 break;
4975
4976 // Initialize the CXToken.
4977 CXToken CXTok;
4978
4979 // - Common fields
4980 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4981 CXTok.int_data[2] = Tok.getLength();
4982 CXTok.int_data[3] = 0;
4983
4984 // - Kind-specific fields
4985 if (Tok.isLiteral()) {
4986 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00004987 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 } else if (Tok.is(tok::raw_identifier)) {
4989 // Lookup the identifier to determine whether we have a keyword.
4990 IdentifierInfo *II
4991 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4992
4993 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4994 CXTok.int_data[0] = CXToken_Keyword;
4995 }
4996 else {
4997 CXTok.int_data[0] = Tok.is(tok::identifier)
4998 ? CXToken_Identifier
4999 : CXToken_Keyword;
5000 }
5001 CXTok.ptr_data = II;
5002 } else if (Tok.is(tok::comment)) {
5003 CXTok.int_data[0] = CXToken_Comment;
5004 CXTok.ptr_data = 0;
5005 } else {
5006 CXTok.int_data[0] = CXToken_Punctuation;
5007 CXTok.ptr_data = 0;
5008 }
5009 CXTokens.push_back(CXTok);
5010 previousWasAt = Tok.is(tok::at);
5011 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5012}
5013
5014void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5015 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005016 LOG_FUNC_SECTION {
5017 *Log << TU << ' ' << Range;
5018 }
5019
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (Tokens)
5021 *Tokens = 0;
5022 if (NumTokens)
5023 *NumTokens = 0;
5024
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005025 if (!TU)
5026 return;
5027
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005028 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 if (!CXXUnit || !Tokens || !NumTokens)
5030 return;
5031
5032 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5033
5034 SourceRange R = cxloc::translateCXSourceRange(Range);
5035 if (R.isInvalid())
5036 return;
5037
5038 SmallVector<CXToken, 32> CXTokens;
5039 getTokens(CXXUnit, R, CXTokens);
5040
5041 if (CXTokens.empty())
5042 return;
5043
5044 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5045 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5046 *NumTokens = CXTokens.size();
5047}
5048
5049void clang_disposeTokens(CXTranslationUnit TU,
5050 CXToken *Tokens, unsigned NumTokens) {
5051 free(Tokens);
5052}
5053
5054} // end: extern "C"
5055
5056//===----------------------------------------------------------------------===//
5057// Token annotation APIs.
5058//===----------------------------------------------------------------------===//
5059
Guy Benyei11169dd2012-12-18 14:30:41 +00005060static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5061 CXCursor parent,
5062 CXClientData client_data);
5063static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5064 CXClientData client_data);
5065
5066namespace {
5067class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 CXToken *Tokens;
5069 CXCursor *Cursors;
5070 unsigned NumTokens;
5071 unsigned TokIdx;
5072 unsigned PreprocessingTokIdx;
5073 CursorVisitor AnnotateVis;
5074 SourceManager &SrcMgr;
5075 bool HasContextSensitiveKeywords;
5076
5077 struct PostChildrenInfo {
5078 CXCursor Cursor;
5079 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005080 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 unsigned BeforeChildrenTokenIdx;
5082 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005083 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei11169dd2012-12-18 14:30:41 +00005084
5085 bool MoreTokens() const { return TokIdx < NumTokens; }
5086 unsigned NextToken() const { return TokIdx; }
5087 void AdvanceToken() { ++TokIdx; }
5088 SourceLocation GetTokenLoc(unsigned tokI) {
5089 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5090 }
5091 bool isFunctionMacroToken(unsigned tokI) const {
5092 return Tokens[tokI].int_data[3] != 0;
5093 }
5094 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5095 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5096 }
5097
5098 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005099 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 SourceRange);
5101
5102public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005103 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005104 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005105 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005107 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 AnnotateTokensVisitor, this,
5109 /*VisitPreprocessorLast=*/true,
5110 /*VisitIncludedEntities=*/false,
5111 RegionOfInterest,
5112 /*VisitDeclsOnly=*/false,
5113 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005114 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 HasContextSensitiveKeywords(false) { }
5116
5117 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5118 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5119 bool postVisitChildren(CXCursor cursor);
5120 void AnnotateTokens();
5121
5122 /// \brief Determine whether the annotator saw any cursors that have
5123 /// context-sensitive keywords.
5124 bool hasContextSensitiveKeywords() const {
5125 return HasContextSensitiveKeywords;
5126 }
5127
5128 ~AnnotateTokensWorker() {
5129 assert(PostChildrenInfos.empty());
5130 }
5131};
5132}
5133
5134void AnnotateTokensWorker::AnnotateTokens() {
5135 // Walk the AST within the region of interest, annotating tokens
5136 // along the way.
5137 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005138}
Guy Benyei11169dd2012-12-18 14:30:41 +00005139
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005140static inline void updateCursorAnnotation(CXCursor &Cursor,
5141 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005142 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005144 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005145}
5146
5147/// \brief It annotates and advances tokens with a cursor until the comparison
5148//// between the cursor location and the source range is the same as
5149/// \arg compResult.
5150///
5151/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5152/// Pass RangeOverlap to annotate tokens inside a range.
5153void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5154 RangeComparisonResult compResult,
5155 SourceRange range) {
5156 while (MoreTokens()) {
5157 const unsigned I = NextToken();
5158 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005159 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5160 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005161
5162 SourceLocation TokLoc = GetTokenLoc(I);
5163 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005164 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 AdvanceToken();
5166 continue;
5167 }
5168 break;
5169 }
5170}
5171
5172/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005173/// \returns true if it advanced beyond all macro tokens, false otherwise.
5174bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 CXCursor updateC,
5176 RangeComparisonResult compResult,
5177 SourceRange range) {
5178 assert(MoreTokens());
5179 assert(isFunctionMacroToken(NextToken()) &&
5180 "Should be called only for macro arg tokens");
5181
5182 // This works differently than annotateAndAdvanceTokens; because expanded
5183 // macro arguments can have arbitrary translation-unit source order, we do not
5184 // advance the token index one by one until a token fails the range test.
5185 // We only advance once past all of the macro arg tokens if all of them
5186 // pass the range test. If one of them fails we keep the token index pointing
5187 // at the start of the macro arg tokens so that the failing token will be
5188 // annotated by a subsequent annotation try.
5189
5190 bool atLeastOneCompFail = false;
5191
5192 unsigned I = NextToken();
5193 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5194 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5195 if (TokLoc.isFileID())
5196 continue; // not macro arg token, it's parens or comma.
5197 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5198 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5199 Cursors[I] = updateC;
5200 } else
5201 atLeastOneCompFail = true;
5202 }
5203
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005204 if (atLeastOneCompFail)
5205 return false;
5206
5207 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5208 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005209}
5210
5211enum CXChildVisitResult
5212AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 SourceRange cursorRange = getRawCursorExtent(cursor);
5214 if (cursorRange.isInvalid())
5215 return CXChildVisit_Recurse;
5216
5217 if (!HasContextSensitiveKeywords) {
5218 // Objective-C properties can have context-sensitive keywords.
5219 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005220 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5222 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5223 }
5224 // Objective-C methods can have context-sensitive keywords.
5225 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5226 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005227 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5229 if (Method->getObjCDeclQualifier())
5230 HasContextSensitiveKeywords = true;
5231 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005232 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5233 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 P != PEnd; ++P) {
5235 if ((*P)->getObjCDeclQualifier()) {
5236 HasContextSensitiveKeywords = true;
5237 break;
5238 }
5239 }
5240 }
5241 }
5242 }
5243 // C++ methods can have context-sensitive keywords.
5244 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005245 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5247 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5248 HasContextSensitiveKeywords = true;
5249 }
5250 }
5251 // C++ classes can have context-sensitive keywords.
5252 else if (cursor.kind == CXCursor_StructDecl ||
5253 cursor.kind == CXCursor_ClassDecl ||
5254 cursor.kind == CXCursor_ClassTemplate ||
5255 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005256 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 if (D->hasAttr<FinalAttr>())
5258 HasContextSensitiveKeywords = true;
5259 }
5260 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005261
5262 // Don't override a property annotation with its getter/setter method.
5263 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5264 parent.kind == CXCursor_ObjCPropertyDecl)
5265 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005266
5267 if (clang_isPreprocessing(cursor.kind)) {
5268 // Items in the preprocessing record are kept separate from items in
5269 // declarations, so we keep a separate token index.
5270 unsigned SavedTokIdx = TokIdx;
5271 TokIdx = PreprocessingTokIdx;
5272
5273 // Skip tokens up until we catch up to the beginning of the preprocessing
5274 // entry.
5275 while (MoreTokens()) {
5276 const unsigned I = NextToken();
5277 SourceLocation TokLoc = GetTokenLoc(I);
5278 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5279 case RangeBefore:
5280 AdvanceToken();
5281 continue;
5282 case RangeAfter:
5283 case RangeOverlap:
5284 break;
5285 }
5286 break;
5287 }
5288
5289 // Look at all of the tokens within this range.
5290 while (MoreTokens()) {
5291 const unsigned I = NextToken();
5292 SourceLocation TokLoc = GetTokenLoc(I);
5293 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5294 case RangeBefore:
5295 llvm_unreachable("Infeasible");
5296 case RangeAfter:
5297 break;
5298 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005299 // For macro expansions, just note where the beginning of the macro
5300 // expansion occurs.
5301 if (cursor.kind == CXCursor_MacroExpansion) {
5302 if (TokLoc == cursorRange.getBegin())
5303 Cursors[I] = cursor;
5304 AdvanceToken();
5305 break;
5306 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005307 // We may have already annotated macro names inside macro definitions.
5308 if (Cursors[I].kind != CXCursor_MacroExpansion)
5309 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 continue;
5312 }
5313 break;
5314 }
5315
5316 // Save the preprocessing token index; restore the non-preprocessing
5317 // token index.
5318 PreprocessingTokIdx = TokIdx;
5319 TokIdx = SavedTokIdx;
5320 return CXChildVisit_Recurse;
5321 }
5322
5323 if (cursorRange.isInvalid())
5324 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005325
5326 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 const enum CXCursorKind K = clang_getCursorKind(parent);
5329 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005330 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5331 // Attributes are annotated out-of-order, skip tokens until we reach it.
5332 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 ? clang_getNullCursor() : parent;
5334
5335 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5336
5337 // Avoid having the cursor of an expression "overwrite" the annotation of the
5338 // variable declaration that it belongs to.
5339 // This can happen for C++ constructor expressions whose range generally
5340 // include the variable declaration, e.g.:
5341 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5342 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005343 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005344 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 const unsigned I = NextToken();
5346 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5347 E->getLocStart() == D->getLocation() &&
5348 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005349 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 AdvanceToken();
5351 }
5352 }
5353 }
5354
5355 // Before recursing into the children keep some state that we are going
5356 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5357 // extra work after the child nodes are visited.
5358 // Note that we don't call VisitChildren here to avoid traversing statements
5359 // code-recursively which can blow the stack.
5360
5361 PostChildrenInfo Info;
5362 Info.Cursor = cursor;
5363 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005364 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 Info.BeforeChildrenTokenIdx = NextToken();
5366 PostChildrenInfos.push_back(Info);
5367
5368 return CXChildVisit_Recurse;
5369}
5370
5371bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5372 if (PostChildrenInfos.empty())
5373 return false;
5374 const PostChildrenInfo &Info = PostChildrenInfos.back();
5375 if (!clang_equalCursors(Info.Cursor, cursor))
5376 return false;
5377
5378 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5379 const unsigned AfterChildren = NextToken();
5380 SourceRange cursorRange = Info.CursorRange;
5381
5382 // Scan the tokens that are at the end of the cursor, but are not captured
5383 // but the child cursors.
5384 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5385
5386 // Scan the tokens that are at the beginning of the cursor, but are not
5387 // capture by the child cursors.
5388 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5389 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5390 break;
5391
5392 Cursors[I] = cursor;
5393 }
5394
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005395 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5396 // encountered the attribute cursor.
5397 if (clang_isAttribute(cursor.kind))
5398 TokIdx = Info.BeforeReachingCursorIdx;
5399
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 PostChildrenInfos.pop_back();
5401 return false;
5402}
5403
5404static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5405 CXCursor parent,
5406 CXClientData client_data) {
5407 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5408}
5409
5410static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5411 CXClientData client_data) {
5412 return static_cast<AnnotateTokensWorker*>(client_data)->
5413 postVisitChildren(cursor);
5414}
5415
5416namespace {
5417
5418/// \brief Uses the macro expansions in the preprocessing record to find
5419/// and mark tokens that are macro arguments. This info is used by the
5420/// AnnotateTokensWorker.
5421class MarkMacroArgTokensVisitor {
5422 SourceManager &SM;
5423 CXToken *Tokens;
5424 unsigned NumTokens;
5425 unsigned CurIdx;
5426
5427public:
5428 MarkMacroArgTokensVisitor(SourceManager &SM,
5429 CXToken *tokens, unsigned numTokens)
5430 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5431
5432 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5433 if (cursor.kind != CXCursor_MacroExpansion)
5434 return CXChildVisit_Continue;
5435
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005436 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 if (macroRange.getBegin() == macroRange.getEnd())
5438 return CXChildVisit_Continue; // it's not a function macro.
5439
5440 for (; CurIdx < NumTokens; ++CurIdx) {
5441 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5442 macroRange.getBegin()))
5443 break;
5444 }
5445
5446 if (CurIdx == NumTokens)
5447 return CXChildVisit_Break;
5448
5449 for (; CurIdx < NumTokens; ++CurIdx) {
5450 SourceLocation tokLoc = getTokenLoc(CurIdx);
5451 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5452 break;
5453
5454 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5455 }
5456
5457 if (CurIdx == NumTokens)
5458 return CXChildVisit_Break;
5459
5460 return CXChildVisit_Continue;
5461 }
5462
5463private:
5464 SourceLocation getTokenLoc(unsigned tokI) {
5465 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5466 }
5467
5468 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5469 // The third field is reserved and currently not used. Use it here
5470 // to mark macro arg expanded tokens with their expanded locations.
5471 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5472 }
5473};
5474
5475} // end anonymous namespace
5476
5477static CXChildVisitResult
5478MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5479 CXClientData client_data) {
5480 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5481 parent);
5482}
5483
5484namespace {
5485 struct clang_annotateTokens_Data {
5486 CXTranslationUnit TU;
5487 ASTUnit *CXXUnit;
5488 CXToken *Tokens;
5489 unsigned NumTokens;
5490 CXCursor *Cursors;
5491 };
5492}
5493
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005494/// \brief Used by \c annotatePreprocessorTokens.
5495/// \returns true if lexing was finished, false otherwise.
5496static bool lexNext(Lexer &Lex, Token &Tok,
5497 unsigned &NextIdx, unsigned NumTokens) {
5498 if (NextIdx >= NumTokens)
5499 return true;
5500
5501 ++NextIdx;
5502 Lex.LexFromRawLexer(Tok);
5503 if (Tok.is(tok::eof))
5504 return true;
5505
5506 return false;
5507}
5508
Guy Benyei11169dd2012-12-18 14:30:41 +00005509static void annotatePreprocessorTokens(CXTranslationUnit TU,
5510 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005511 CXCursor *Cursors,
5512 CXToken *Tokens,
5513 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005514 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005515
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005516 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5518 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005519 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005521 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005522
5523 if (BeginLocInfo.first != EndLocInfo.first)
5524 return;
5525
5526 StringRef Buffer;
5527 bool Invalid = false;
5528 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5529 if (Buffer.empty() || Invalid)
5530 return;
5531
5532 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5533 CXXUnit->getASTContext().getLangOpts(),
5534 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5535 Buffer.end());
5536 Lex.SetCommentRetentionState(true);
5537
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005538 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005539 // Lex tokens in raw mode until we hit the end of the range, to avoid
5540 // entering #includes or expanding macros.
5541 while (true) {
5542 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005543 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5544 break;
5545 unsigned TokIdx = NextIdx-1;
5546 assert(Tok.getLocation() ==
5547 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005548
5549 reprocess:
5550 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005551 // We have found a preprocessing directive. Annotate the tokens
5552 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 //
5554 // FIXME: Some simple tests here could identify macro definitions and
5555 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005556
5557 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005558 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5559 break;
5560
5561 MacroInfo *MI = 0;
5562 if (Tok.is(tok::raw_identifier) &&
5563 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5564 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5565 break;
5566
5567 if (Tok.is(tok::raw_identifier)) {
5568 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5569 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5570 SourceLocation MappedTokLoc =
5571 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5572 MI = getMacroInfo(II, MappedTokLoc, TU);
5573 }
5574 }
5575
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005576 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005578 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5579 finished = true;
5580 break;
5581 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005582 // If we are in a macro definition, check if the token was ever a
5583 // macro name and annotate it if that's the case.
5584 if (MI) {
5585 SourceLocation SaveLoc = Tok.getLocation();
5586 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5587 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5588 Tok.setLocation(SaveLoc);
5589 if (MacroDef)
5590 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5591 Tok.getLocation(), TU);
5592 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005593 } while (!Tok.isAtStartOfLine());
5594
5595 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5596 assert(TokIdx <= LastIdx);
5597 SourceLocation EndLoc =
5598 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5599 CXCursor Cursor =
5600 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5601
5602 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005603 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005604
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005605 if (finished)
5606 break;
5607 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 }
5610}
5611
5612// This gets run a separate thread to avoid stack blowout.
5613static void clang_annotateTokensImpl(void *UserData) {
5614 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5615 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5616 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5617 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5618 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5619
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005620 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5622 setThreadBackgroundPriority();
5623
5624 // Determine the region of interest, which contains all of the tokens.
5625 SourceRange RegionOfInterest;
5626 RegionOfInterest.setBegin(
5627 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5628 RegionOfInterest.setEnd(
5629 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5630 Tokens[NumTokens-1])));
5631
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 // Relex the tokens within the source range to look for preprocessing
5633 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005634 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005635
5636 // If begin location points inside a macro argument, set it to the expansion
5637 // location so we can have the full context when annotating semantically.
5638 {
5639 SourceManager &SM = CXXUnit->getSourceManager();
5640 SourceLocation Loc =
5641 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5642 if (Loc.isMacroID())
5643 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5644 }
5645
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5647 // Search and mark tokens that are macro argument expansions.
5648 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5649 Tokens, NumTokens);
5650 CursorVisitor MacroArgMarker(TU,
5651 MarkMacroArgTokensVisitorDelegate, &Visitor,
5652 /*VisitPreprocessorLast=*/true,
5653 /*VisitIncludedEntities=*/false,
5654 RegionOfInterest);
5655 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5656 }
5657
5658 // Annotate all of the source locations in the region of interest that map to
5659 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005660 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005661
5662 // FIXME: We use a ridiculous stack size here because the data-recursion
5663 // algorithm uses a large stack frame than the non-data recursive version,
5664 // and AnnotationTokensWorker currently transforms the data-recursion
5665 // algorithm back into a traditional recursion by explicitly calling
5666 // VisitChildren(). We will need to remove this explicit recursive call.
5667 W.AnnotateTokens();
5668
5669 // If we ran into any entities that involve context-sensitive keywords,
5670 // take another pass through the tokens to mark them as such.
5671 if (W.hasContextSensitiveKeywords()) {
5672 for (unsigned I = 0; I != NumTokens; ++I) {
5673 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5674 continue;
5675
5676 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5677 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005678 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5680 if (Property->getPropertyAttributesAsWritten() != 0 &&
5681 llvm::StringSwitch<bool>(II->getName())
5682 .Case("readonly", true)
5683 .Case("assign", true)
5684 .Case("unsafe_unretained", true)
5685 .Case("readwrite", true)
5686 .Case("retain", true)
5687 .Case("copy", true)
5688 .Case("nonatomic", true)
5689 .Case("atomic", true)
5690 .Case("getter", true)
5691 .Case("setter", true)
5692 .Case("strong", true)
5693 .Case("weak", true)
5694 .Default(false))
5695 Tokens[I].int_data[0] = CXToken_Keyword;
5696 }
5697 continue;
5698 }
5699
5700 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5701 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5702 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5703 if (llvm::StringSwitch<bool>(II->getName())
5704 .Case("in", true)
5705 .Case("out", true)
5706 .Case("inout", true)
5707 .Case("oneway", true)
5708 .Case("bycopy", true)
5709 .Case("byref", true)
5710 .Default(false))
5711 Tokens[I].int_data[0] = CXToken_Keyword;
5712 continue;
5713 }
5714
5715 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5716 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5717 Tokens[I].int_data[0] = CXToken_Keyword;
5718 continue;
5719 }
5720 }
5721 }
5722}
5723
5724extern "C" {
5725
5726void clang_annotateTokens(CXTranslationUnit TU,
5727 CXToken *Tokens, unsigned NumTokens,
5728 CXCursor *Cursors) {
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005729 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005730 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005732 }
5733
5734 LOG_FUNC_SECTION {
5735 *Log << TU << ' ';
5736 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5737 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5738 *Log << clang_getRange(bloc, eloc);
5739 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005740
5741 // Any token we don't specifically annotate will have a NULL cursor.
5742 CXCursor C = clang_getNullCursor();
5743 for (unsigned I = 0; I != NumTokens; ++I)
5744 Cursors[I] = C;
5745
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005746 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 if (!CXXUnit)
5748 return;
5749
5750 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5751
5752 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5753 llvm::CrashRecoveryContext CRC;
5754 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5755 GetSafetyThreadStackSize() * 2)) {
5756 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5757 }
5758}
5759
5760} // end: extern "C"
5761
5762//===----------------------------------------------------------------------===//
5763// Operations for querying linkage of a cursor.
5764//===----------------------------------------------------------------------===//
5765
5766extern "C" {
5767CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5768 if (!clang_isDeclaration(cursor.kind))
5769 return CXLinkage_Invalid;
5770
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005771 const Decl *D = cxcursor::getCursorDecl(cursor);
5772 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005773 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005774 case NoLinkage:
5775 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 case InternalLinkage: return CXLinkage_Internal;
5777 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5778 case ExternalLinkage: return CXLinkage_External;
5779 };
5780
5781 return CXLinkage_Invalid;
5782}
5783} // end: extern "C"
5784
5785//===----------------------------------------------------------------------===//
5786// Operations for querying language of a cursor.
5787//===----------------------------------------------------------------------===//
5788
5789static CXLanguageKind getDeclLanguage(const Decl *D) {
5790 if (!D)
5791 return CXLanguage_C;
5792
5793 switch (D->getKind()) {
5794 default:
5795 break;
5796 case Decl::ImplicitParam:
5797 case Decl::ObjCAtDefsField:
5798 case Decl::ObjCCategory:
5799 case Decl::ObjCCategoryImpl:
5800 case Decl::ObjCCompatibleAlias:
5801 case Decl::ObjCImplementation:
5802 case Decl::ObjCInterface:
5803 case Decl::ObjCIvar:
5804 case Decl::ObjCMethod:
5805 case Decl::ObjCProperty:
5806 case Decl::ObjCPropertyImpl:
5807 case Decl::ObjCProtocol:
5808 return CXLanguage_ObjC;
5809 case Decl::CXXConstructor:
5810 case Decl::CXXConversion:
5811 case Decl::CXXDestructor:
5812 case Decl::CXXMethod:
5813 case Decl::CXXRecord:
5814 case Decl::ClassTemplate:
5815 case Decl::ClassTemplatePartialSpecialization:
5816 case Decl::ClassTemplateSpecialization:
5817 case Decl::Friend:
5818 case Decl::FriendTemplate:
5819 case Decl::FunctionTemplate:
5820 case Decl::LinkageSpec:
5821 case Decl::Namespace:
5822 case Decl::NamespaceAlias:
5823 case Decl::NonTypeTemplateParm:
5824 case Decl::StaticAssert:
5825 case Decl::TemplateTemplateParm:
5826 case Decl::TemplateTypeParm:
5827 case Decl::UnresolvedUsingTypename:
5828 case Decl::UnresolvedUsingValue:
5829 case Decl::Using:
5830 case Decl::UsingDirective:
5831 case Decl::UsingShadow:
5832 return CXLanguage_CPlusPlus;
5833 }
5834
5835 return CXLanguage_C;
5836}
5837
5838extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005839
5840static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5841 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5842 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005843
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005844 switch (D->getAvailability()) {
5845 case AR_Available:
5846 case AR_NotYetIntroduced:
5847 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005848 return getCursorAvailabilityForDecl(
5849 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005850 return CXAvailability_Available;
5851
5852 case AR_Deprecated:
5853 return CXAvailability_Deprecated;
5854
5855 case AR_Unavailable:
5856 return CXAvailability_NotAvailable;
5857 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005858
5859 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005860}
5861
Guy Benyei11169dd2012-12-18 14:30:41 +00005862enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5863 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005864 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5865 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005866
5867 return CXAvailability_Available;
5868}
5869
5870static CXVersion convertVersion(VersionTuple In) {
5871 CXVersion Out = { -1, -1, -1 };
5872 if (In.empty())
5873 return Out;
5874
5875 Out.Major = In.getMajor();
5876
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005877 Optional<unsigned> Minor = In.getMinor();
5878 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 Out.Minor = *Minor;
5880 else
5881 return Out;
5882
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005883 Optional<unsigned> Subminor = In.getSubminor();
5884 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 Out.Subminor = *Subminor;
5886
5887 return Out;
5888}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005889
5890static int getCursorPlatformAvailabilityForDecl(const Decl *D,
5891 int *always_deprecated,
5892 CXString *deprecated_message,
5893 int *always_unavailable,
5894 CXString *unavailable_message,
5895 CXPlatformAvailability *availability,
5896 int availability_size) {
5897 bool HadAvailAttr = false;
5898 int N = 0;
5899 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5900 ++A) {
5901 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5902 HadAvailAttr = true;
5903 if (always_deprecated)
5904 *always_deprecated = 1;
5905 if (deprecated_message)
5906 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
5907 continue;
5908 }
5909
5910 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5911 HadAvailAttr = true;
5912 if (always_unavailable)
5913 *always_unavailable = 1;
5914 if (unavailable_message) {
5915 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
5916 }
5917 continue;
5918 }
5919
5920 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5921 HadAvailAttr = true;
5922 if (N < availability_size) {
5923 availability[N].Platform
5924 = cxstring::createDup(Avail->getPlatform()->getName());
5925 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5926 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5927 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5928 availability[N].Unavailable = Avail->getUnavailable();
5929 availability[N].Message = cxstring::createDup(Avail->getMessage());
5930 }
5931 ++N;
5932 }
5933 }
5934
5935 if (!HadAvailAttr)
5936 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
5937 return getCursorPlatformAvailabilityForDecl(
5938 cast<Decl>(EnumConst->getDeclContext()),
5939 always_deprecated,
5940 deprecated_message,
5941 always_unavailable,
5942 unavailable_message,
5943 availability,
5944 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005945
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005946 return N;
5947}
5948
Guy Benyei11169dd2012-12-18 14:30:41 +00005949int clang_getCursorPlatformAvailability(CXCursor cursor,
5950 int *always_deprecated,
5951 CXString *deprecated_message,
5952 int *always_unavailable,
5953 CXString *unavailable_message,
5954 CXPlatformAvailability *availability,
5955 int availability_size) {
5956 if (always_deprecated)
5957 *always_deprecated = 0;
5958 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005959 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005960 if (always_unavailable)
5961 *always_unavailable = 0;
5962 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005963 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005964
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 if (!clang_isDeclaration(cursor.kind))
5966 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005967
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005968 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005969 if (!D)
5970 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005971
5972 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
5973 deprecated_message,
5974 always_unavailable,
5975 unavailable_message,
5976 availability,
5977 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00005978}
5979
5980void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5981 clang_disposeString(availability->Platform);
5982 clang_disposeString(availability->Message);
5983}
5984
5985CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5986 if (clang_isDeclaration(cursor.kind))
5987 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5988
5989 return CXLanguage_Invalid;
5990}
5991
5992 /// \brief If the given cursor is the "templated" declaration
5993 /// descibing a class or function template, return the class or
5994 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005995static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 if (!D)
5997 return 0;
5998
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005999 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6001 return FunTmpl;
6002
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006003 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6005 return ClassTmpl;
6006
6007 return D;
6008}
6009
6010CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6011 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006012 if (const Decl *D = getCursorDecl(cursor)) {
6013 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 if (!DC)
6015 return clang_getNullCursor();
6016
6017 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6018 getCursorTU(cursor));
6019 }
6020 }
6021
6022 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006023 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 return MakeCXCursor(D, getCursorTU(cursor));
6025 }
6026
6027 return clang_getNullCursor();
6028}
6029
6030CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6031 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006032 if (const Decl *D = getCursorDecl(cursor)) {
6033 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 if (!DC)
6035 return clang_getNullCursor();
6036
6037 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6038 getCursorTU(cursor));
6039 }
6040 }
6041
6042 // FIXME: Note that we can't easily compute the lexical context of a
6043 // statement or expression, so we return nothing.
6044 return clang_getNullCursor();
6045}
6046
6047CXFile clang_getIncludedFile(CXCursor cursor) {
6048 if (cursor.kind != CXCursor_InclusionDirective)
6049 return 0;
6050
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006051 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006052 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006053}
6054
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006055unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6056 if (C.kind != CXCursor_ObjCPropertyDecl)
6057 return CXObjCPropertyAttr_noattr;
6058
6059 unsigned Result = CXObjCPropertyAttr_noattr;
6060 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6061 ObjCPropertyDecl::PropertyAttributeKind Attr =
6062 PD->getPropertyAttributesAsWritten();
6063
6064#define SET_CXOBJCPROP_ATTR(A) \
6065 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6066 Result |= CXObjCPropertyAttr_##A
6067 SET_CXOBJCPROP_ATTR(readonly);
6068 SET_CXOBJCPROP_ATTR(getter);
6069 SET_CXOBJCPROP_ATTR(assign);
6070 SET_CXOBJCPROP_ATTR(readwrite);
6071 SET_CXOBJCPROP_ATTR(retain);
6072 SET_CXOBJCPROP_ATTR(copy);
6073 SET_CXOBJCPROP_ATTR(nonatomic);
6074 SET_CXOBJCPROP_ATTR(setter);
6075 SET_CXOBJCPROP_ATTR(atomic);
6076 SET_CXOBJCPROP_ATTR(weak);
6077 SET_CXOBJCPROP_ATTR(strong);
6078 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6079#undef SET_CXOBJCPROP_ATTR
6080
6081 return Result;
6082}
6083
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006084unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6085 if (!clang_isDeclaration(C.kind))
6086 return CXObjCDeclQualifier_None;
6087
6088 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6089 const Decl *D = getCursorDecl(C);
6090 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6091 QT = MD->getObjCDeclQualifier();
6092 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6093 QT = PD->getObjCDeclQualifier();
6094 if (QT == Decl::OBJC_TQ_None)
6095 return CXObjCDeclQualifier_None;
6096
6097 unsigned Result = CXObjCDeclQualifier_None;
6098 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6099 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6100 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6101 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6102 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6103 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6104
6105 return Result;
6106}
6107
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006108unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6109 if (!clang_isDeclaration(C.kind))
6110 return 0;
6111
6112 const Decl *D = getCursorDecl(C);
6113 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6114 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6115 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6116 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6117
6118 return 0;
6119}
6120
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006121unsigned clang_Cursor_isVariadic(CXCursor C) {
6122 if (!clang_isDeclaration(C.kind))
6123 return 0;
6124
6125 const Decl *D = getCursorDecl(C);
6126 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6127 return FD->isVariadic();
6128 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6129 return MD->isVariadic();
6130
6131 return 0;
6132}
6133
Guy Benyei11169dd2012-12-18 14:30:41 +00006134CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6135 if (!clang_isDeclaration(C.kind))
6136 return clang_getNullRange();
6137
6138 const Decl *D = getCursorDecl(C);
6139 ASTContext &Context = getCursorContext(C);
6140 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6141 if (!RC)
6142 return clang_getNullRange();
6143
6144 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6145}
6146
6147CXString clang_Cursor_getRawCommentText(CXCursor C) {
6148 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006149 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006150
6151 const Decl *D = getCursorDecl(C);
6152 ASTContext &Context = getCursorContext(C);
6153 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6154 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6155 StringRef();
6156
6157 // Don't duplicate the string because RawText points directly into source
6158 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006159 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006160}
6161
6162CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6163 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006164 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006165
6166 const Decl *D = getCursorDecl(C);
6167 const ASTContext &Context = getCursorContext(C);
6168 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6169
6170 if (RC) {
6171 StringRef BriefText = RC->getBriefText(Context);
6172
6173 // Don't duplicate the string because RawComment ensures that this memory
6174 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006175 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 }
6177
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006178 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006179}
6180
6181CXComment clang_Cursor_getParsedComment(CXCursor C) {
6182 if (!clang_isDeclaration(C.kind))
6183 return cxcomment::createCXComment(NULL, NULL);
6184
6185 const Decl *D = getCursorDecl(C);
6186 const ASTContext &Context = getCursorContext(C);
6187 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6188
6189 return cxcomment::createCXComment(FC, getCursorTU(C));
6190}
6191
6192CXModule clang_Cursor_getModule(CXCursor C) {
6193 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006194 if (const ImportDecl *ImportD =
6195 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 return ImportD->getImportedModule();
6197 }
6198
6199 return 0;
6200}
6201
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006202CXFile clang_Module_getASTFile(CXModule CXMod) {
6203 if (!CXMod)
6204 return 0;
6205 Module *Mod = static_cast<Module*>(CXMod);
6206 return const_cast<FileEntry *>(Mod->getASTFile());
6207}
6208
Guy Benyei11169dd2012-12-18 14:30:41 +00006209CXModule clang_Module_getParent(CXModule CXMod) {
6210 if (!CXMod)
6211 return 0;
6212 Module *Mod = static_cast<Module*>(CXMod);
6213 return Mod->Parent;
6214}
6215
6216CXString clang_Module_getName(CXModule CXMod) {
6217 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006218 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006219 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006220 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006221}
6222
6223CXString clang_Module_getFullName(CXModule CXMod) {
6224 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006225 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006226 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006227 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006228}
6229
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006230unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6231 CXModule CXMod) {
6232 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006233 return 0;
6234 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006235 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6236 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6237 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006238}
6239
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006240CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6241 CXModule CXMod, unsigned Index) {
6242 if (!TU || !CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006243 return 0;
6244 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006245 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006246
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006247 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6248 if (Index < TopHeaders.size())
6249 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006250
6251 return 0;
6252}
6253
6254} // end: extern "C"
6255
6256//===----------------------------------------------------------------------===//
6257// C++ AST instrospection.
6258//===----------------------------------------------------------------------===//
6259
6260extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006261unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6262 if (!clang_isDeclaration(C.kind))
6263 return 0;
6264
6265 const CXXMethodDecl *Method = 0;
6266 const Decl *D = cxcursor::getCursorDecl(C);
6267 if (const FunctionTemplateDecl *FunTmpl =
6268 dyn_cast_or_null<FunctionTemplateDecl>(D))
6269 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6270 else
6271 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6272 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6273}
6274
Guy Benyei11169dd2012-12-18 14:30:41 +00006275unsigned clang_CXXMethod_isStatic(CXCursor C) {
6276 if (!clang_isDeclaration(C.kind))
6277 return 0;
6278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006279 const CXXMethodDecl *Method = 0;
6280 const Decl *D = cxcursor::getCursorDecl(C);
6281 if (const FunctionTemplateDecl *FunTmpl =
6282 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6284 else
6285 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6286 return (Method && Method->isStatic()) ? 1 : 0;
6287}
6288
6289unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6290 if (!clang_isDeclaration(C.kind))
6291 return 0;
6292
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006293 const CXXMethodDecl *Method = 0;
6294 const Decl *D = cxcursor::getCursorDecl(C);
6295 if (const FunctionTemplateDecl *FunTmpl =
6296 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006297 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6298 else
6299 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6300 return (Method && Method->isVirtual()) ? 1 : 0;
6301}
6302} // end: extern "C"
6303
6304//===----------------------------------------------------------------------===//
6305// Attribute introspection.
6306//===----------------------------------------------------------------------===//
6307
6308extern "C" {
6309CXType clang_getIBOutletCollectionType(CXCursor C) {
6310 if (C.kind != CXCursor_IBOutletCollectionAttr)
6311 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6312
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006313 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006314 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6315
6316 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6317}
6318} // end: extern "C"
6319
6320//===----------------------------------------------------------------------===//
6321// Inspecting memory usage.
6322//===----------------------------------------------------------------------===//
6323
6324typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6325
6326static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6327 enum CXTUResourceUsageKind k,
6328 unsigned long amount) {
6329 CXTUResourceUsageEntry entry = { k, amount };
6330 entries.push_back(entry);
6331}
6332
6333extern "C" {
6334
6335const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6336 const char *str = "";
6337 switch (kind) {
6338 case CXTUResourceUsage_AST:
6339 str = "ASTContext: expressions, declarations, and types";
6340 break;
6341 case CXTUResourceUsage_Identifiers:
6342 str = "ASTContext: identifiers";
6343 break;
6344 case CXTUResourceUsage_Selectors:
6345 str = "ASTContext: selectors";
6346 break;
6347 case CXTUResourceUsage_GlobalCompletionResults:
6348 str = "Code completion: cached global results";
6349 break;
6350 case CXTUResourceUsage_SourceManagerContentCache:
6351 str = "SourceManager: content cache allocator";
6352 break;
6353 case CXTUResourceUsage_AST_SideTables:
6354 str = "ASTContext: side tables";
6355 break;
6356 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6357 str = "SourceManager: malloc'ed memory buffers";
6358 break;
6359 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6360 str = "SourceManager: mmap'ed memory buffers";
6361 break;
6362 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6363 str = "ExternalASTSource: malloc'ed memory buffers";
6364 break;
6365 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6366 str = "ExternalASTSource: mmap'ed memory buffers";
6367 break;
6368 case CXTUResourceUsage_Preprocessor:
6369 str = "Preprocessor: malloc'ed memory";
6370 break;
6371 case CXTUResourceUsage_PreprocessingRecord:
6372 str = "Preprocessor: PreprocessingRecord";
6373 break;
6374 case CXTUResourceUsage_SourceManager_DataStructures:
6375 str = "SourceManager: data structures and tables";
6376 break;
6377 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6378 str = "Preprocessor: header search tables";
6379 break;
6380 }
6381 return str;
6382}
6383
6384CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6385 if (!TU) {
6386 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6387 return usage;
6388 }
6389
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006390 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006391 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6392 ASTContext &astContext = astUnit->getASTContext();
6393
6394 // How much memory is used by AST nodes and types?
6395 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6396 (unsigned long) astContext.getASTAllocatedMemory());
6397
6398 // How much memory is used by identifiers?
6399 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6400 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6401
6402 // How much memory is used for selectors?
6403 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6404 (unsigned long) astContext.Selectors.getTotalMemory());
6405
6406 // How much memory is used by ASTContext's side tables?
6407 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6408 (unsigned long) astContext.getSideTableAllocatedMemory());
6409
6410 // How much memory is used for caching global code completion results?
6411 unsigned long completionBytes = 0;
6412 if (GlobalCodeCompletionAllocator *completionAllocator =
6413 astUnit->getCachedCompletionAllocator().getPtr()) {
6414 completionBytes = completionAllocator->getTotalMemory();
6415 }
6416 createCXTUResourceUsageEntry(*entries,
6417 CXTUResourceUsage_GlobalCompletionResults,
6418 completionBytes);
6419
6420 // How much memory is being used by SourceManager's content cache?
6421 createCXTUResourceUsageEntry(*entries,
6422 CXTUResourceUsage_SourceManagerContentCache,
6423 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6424
6425 // How much memory is being used by the MemoryBuffer's in SourceManager?
6426 const SourceManager::MemoryBufferSizes &srcBufs =
6427 astUnit->getSourceManager().getMemoryBufferSizes();
6428
6429 createCXTUResourceUsageEntry(*entries,
6430 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6431 (unsigned long) srcBufs.malloc_bytes);
6432 createCXTUResourceUsageEntry(*entries,
6433 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6434 (unsigned long) srcBufs.mmap_bytes);
6435 createCXTUResourceUsageEntry(*entries,
6436 CXTUResourceUsage_SourceManager_DataStructures,
6437 (unsigned long) astContext.getSourceManager()
6438 .getDataStructureSizes());
6439
6440 // How much memory is being used by the ExternalASTSource?
6441 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6442 const ExternalASTSource::MemoryBufferSizes &sizes =
6443 esrc->getMemoryBufferSizes();
6444
6445 createCXTUResourceUsageEntry(*entries,
6446 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6447 (unsigned long) sizes.malloc_bytes);
6448 createCXTUResourceUsageEntry(*entries,
6449 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6450 (unsigned long) sizes.mmap_bytes);
6451 }
6452
6453 // How much memory is being used by the Preprocessor?
6454 Preprocessor &pp = astUnit->getPreprocessor();
6455 createCXTUResourceUsageEntry(*entries,
6456 CXTUResourceUsage_Preprocessor,
6457 pp.getTotalMemory());
6458
6459 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6460 createCXTUResourceUsageEntry(*entries,
6461 CXTUResourceUsage_PreprocessingRecord,
6462 pRec->getTotalMemory());
6463 }
6464
6465 createCXTUResourceUsageEntry(*entries,
6466 CXTUResourceUsage_Preprocessor_HeaderSearch,
6467 pp.getHeaderSearchInfo().getTotalMemory());
6468
6469 CXTUResourceUsage usage = { (void*) entries.get(),
6470 (unsigned) entries->size(),
6471 entries->size() ? &(*entries)[0] : 0 };
6472 entries.take();
6473 return usage;
6474}
6475
6476void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6477 if (usage.data)
6478 delete (MemUsageEntries*) usage.data;
6479}
6480
6481} // end extern "C"
6482
6483void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6484 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6485 for (unsigned I = 0; I != Usage.numEntries; ++I)
6486 fprintf(stderr, " %s: %lu\n",
6487 clang_getTUResourceUsageName(Usage.entries[I].kind),
6488 Usage.entries[I].amount);
6489
6490 clang_disposeCXTUResourceUsage(Usage);
6491}
6492
6493//===----------------------------------------------------------------------===//
6494// Misc. utility functions.
6495//===----------------------------------------------------------------------===//
6496
6497/// Default to using an 8 MB stack size on "safety" threads.
6498static unsigned SafetyStackThreadSize = 8 << 20;
6499
6500namespace clang {
6501
6502bool RunSafely(llvm::CrashRecoveryContext &CRC,
6503 void (*Fn)(void*), void *UserData,
6504 unsigned Size) {
6505 if (!Size)
6506 Size = GetSafetyThreadStackSize();
6507 if (Size)
6508 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6509 return CRC.RunSafely(Fn, UserData);
6510}
6511
6512unsigned GetSafetyThreadStackSize() {
6513 return SafetyStackThreadSize;
6514}
6515
6516void SetSafetyThreadStackSize(unsigned Value) {
6517 SafetyStackThreadSize = Value;
6518}
6519
6520}
6521
6522void clang::setThreadBackgroundPriority() {
6523 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6524 return;
6525
6526 // FIXME: Move to llvm/Support and make it cross-platform.
6527#ifdef __APPLE__
6528 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6529#endif
6530}
6531
6532void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6533 if (!Unit)
6534 return;
6535
6536 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6537 DEnd = Unit->stored_diag_end();
6538 D != DEnd; ++D) {
6539 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6540 CXString Msg = clang_formatDiagnostic(&Diag,
6541 clang_defaultDiagnosticDisplayOptions());
6542 fprintf(stderr, "%s\n", clang_getCString(Msg));
6543 clang_disposeString(Msg);
6544 }
6545#ifdef LLVM_ON_WIN32
6546 // On Windows, force a flush, since there may be multiple copies of
6547 // stderr and stdout in the file system, all with different buffers
6548 // but writing to the same device.
6549 fflush(stderr);
6550#endif
6551}
6552
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006553MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6554 SourceLocation MacroDefLoc,
6555 CXTranslationUnit TU){
6556 if (MacroDefLoc.isInvalid() || !TU)
6557 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006558 if (!II.hadMacroDefinition())
6559 return 0;
6560
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006561 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006562 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006563 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006564 if (MD) {
6565 for (MacroDirective::DefInfo
6566 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6567 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6568 return Def.getMacroInfo();
6569 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006570 }
6571
6572 return 0;
6573}
6574
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006575const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6576 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006577 if (!MacroDef || !TU)
6578 return 0;
6579 const IdentifierInfo *II = MacroDef->getName();
6580 if (!II)
6581 return 0;
6582
6583 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6584}
6585
6586MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6587 const Token &Tok,
6588 CXTranslationUnit TU) {
6589 if (!MI || !TU)
6590 return 0;
6591 if (Tok.isNot(tok::raw_identifier))
6592 return 0;
6593
6594 if (MI->getNumTokens() == 0)
6595 return 0;
6596 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6597 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006598 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006599
6600 // Check that the token is inside the definition and not its argument list.
6601 SourceManager &SM = Unit->getSourceManager();
6602 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6603 return 0;
6604 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6605 return 0;
6606
6607 Preprocessor &PP = Unit->getPreprocessor();
6608 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6609 if (!PPRec)
6610 return 0;
6611
6612 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6613 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6614 if (!II.hadMacroDefinition())
6615 return 0;
6616
6617 // Check that the identifier is not one of the macro arguments.
6618 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6619 return 0;
6620
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006621 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6622 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006623 return 0;
6624
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006625 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006626}
6627
6628MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6629 SourceLocation Loc,
6630 CXTranslationUnit TU) {
6631 if (Loc.isInvalid() || !MI || !TU)
6632 return 0;
6633
6634 if (MI->getNumTokens() == 0)
6635 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006636 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006637 Preprocessor &PP = Unit->getPreprocessor();
6638 if (!PP.getPreprocessingRecord())
6639 return 0;
6640 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6641 Token Tok;
6642 if (PP.getRawToken(Loc, Tok))
6643 return 0;
6644
6645 return checkForMacroInMacroDefinition(MI, Tok, TU);
6646}
6647
Guy Benyei11169dd2012-12-18 14:30:41 +00006648extern "C" {
6649
6650CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006651 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006652}
6653
6654} // end: extern "C"
6655
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006656Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6657 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006658 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006659 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006660 if (Unit->isMainFileAST())
6661 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006662 return *this;
6663 }
6664 }
6665
6666 LogOS << "<NULL TU>";
6667 return *this;
6668}
6669
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006670Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6671 *this << FE->getName();
6672 return *this;
6673}
6674
6675Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6676 CXString cursorName = clang_getCursorDisplayName(cursor);
6677 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6678 clang_disposeString(cursorName);
6679 return *this;
6680}
6681
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006682Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6683 CXFile File;
6684 unsigned Line, Column;
6685 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6686 CXString FileName = clang_getFileName(File);
6687 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6688 clang_disposeString(FileName);
6689 return *this;
6690}
6691
6692Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6693 CXSourceLocation BLoc = clang_getRangeStart(range);
6694 CXSourceLocation ELoc = clang_getRangeEnd(range);
6695
6696 CXFile BFile;
6697 unsigned BLine, BColumn;
6698 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6699
6700 CXFile EFile;
6701 unsigned ELine, EColumn;
6702 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6703
6704 CXString BFileName = clang_getFileName(BFile);
6705 if (BFile == EFile) {
6706 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6707 BLine, BColumn, ELine, EColumn);
6708 } else {
6709 CXString EFileName = clang_getFileName(EFile);
6710 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6711 BLine, BColumn)
6712 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6713 ELine, EColumn);
6714 clang_disposeString(EFileName);
6715 }
6716 clang_disposeString(BFileName);
6717 return *this;
6718}
6719
6720Logger &cxindex::Logger::operator<<(CXString Str) {
6721 *this << clang_getCString(Str);
6722 return *this;
6723}
6724
6725Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6726 LogOS << Fmt;
6727 return *this;
6728}
6729
6730cxindex::Logger::~Logger() {
6731 LogOS.flush();
6732
6733 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6734
6735 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6736
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006737 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006738 OS << "[libclang:" << Name << ':';
6739
6740 // FIXME: Portability.
6741#if HAVE_PTHREAD_H && __APPLE__
6742 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6743 OS << tid << ':';
6744#endif
6745
6746 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6747 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6748 OS << Msg.str() << '\n';
6749
6750 if (Trace) {
6751 llvm::sys::PrintStackTrace(stderr);
6752 OS << "--------------------------------------------------\n";
6753 }
6754}