blob: 036b46dcf791c0a46f325cebdcbf556b3bb36f10 [file] [log] [blame]
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
Fariborz Jahanian88b95212012-12-18 23:02:59 +000025#include "SimpleFormatContext.h"
David Blaikie0b5ca512013-09-13 18:32:52 +000026#include "clang/AST/Attr.h"
Guy Benyei7f92f2d2012-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 Carruthb1ba0ef2013-01-19 08:09:44 +000040#include "llvm/Config/config.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000041#include "llvm/Support/Compiler.h"
42#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000043#include "llvm/Support/Format.h"
Guy Benyei7f92f2d2012-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 Kyrtzidisc6f5c6a2013-01-10 18:54:52 +000053
54#if HAVE_PTHREAD_H
55#include <pthread.h>
56#endif
Guy Benyei7f92f2d2012-12-18 14:30:41 +000057
58using namespace clang;
59using namespace clang::cxcursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000060using namespace clang::cxtu;
61using namespace clang::cxindex;
62
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000063CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
64 if (!AU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +000065 return 0;
66 CXTranslationUnit D = new CXTranslationUnitImpl();
67 D->CIdx = CIdx;
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000068 D->TheASTUnit = AU;
Dmitri Gribenkoaca3e562013-02-03 13:52:47 +000069 D->StringPool = new cxstring::CXStringPool();
Guy Benyei7f92f2d2012-12-18 14:30:41 +000070 D->Diagnostics = 0;
71 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Fariborz Jahanian88b95212012-12-18 23:02:59 +000072 D->FormatContext = 0;
73 D->FormatInMemoryUniqueId = 0;
Guy Benyei7f92f2d2012-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 Wendlingccdfdd72013-01-23 08:25:41 +0000133 CXSourceRange Result = {
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +0000134 { &SM, &LangOpts },
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000135 R.getBegin().getRawEncoding(),
136 EndLoc.getRawEncoding()
137 };
Guy Benyei7f92f2d2012-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 Gribenkoe22339c2013-01-23 17:25:27 +0000168 const Decl *D = getCursorDecl(Cursor);
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000227bool CursorVisitor::visitFileRegion() {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000228 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000229 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000230
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000231 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000247 return false;
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000255 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000256
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000257 if (visitDeclsFromFileRegion(File, Offset, Length))
258 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000259
260 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000261 return visitPreprocessedEntitiesInRegion();
262
263 return false;
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000278bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000279 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000280 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000293 return false;
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000301 return false;
Guy Benyei7f92f2d2012-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 Topper09d19ef2013-07-04 03:08:24 +0000312 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
313 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000344 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000345 }
346
347 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000348 return false;
Guy Benyei7f92f2d2012-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 Kyrtzidis389dc562013-03-08 20:42:33 +0000363 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
364 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000365 }
366
367 DC = D->getLexicalDeclContext();
368 }
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000369
370 return false;
Guy Benyei7f92f2d2012-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 Kyrtzidis333e44c2013-05-07 20:37:17 +0000430 if (!PPE)
431 continue;
432
Guy Benyei7f92f2d2012-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 Gribenkoe22339c2013-01-23 17:25:27 +0000474 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-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 Gribenkoff74f962013-01-26 15:29:08 +0000482 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000483 return Visit(S);
484
485 return false;
486 }
487
488 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000489 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000490 return Visit(E);
491
492 return false;
493 }
494
495 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000496 CXTranslationUnit TU = getCursorTU(Cursor);
497 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-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 Gribenko5694feb2013-01-26 18:53:38 +0000507 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-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 Gribenko67812b22013-01-11 21:01:49 +0000525 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-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 Gribenko7d914382013-01-26 18:08:08 +0000533 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000534 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
535 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
536 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
537 A->getInterfaceLoc(), TU));
538 }
539
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000540 // If pointing inside a macro definition, check if the token is an identifier
541 // that was ever defined as a macro. In such a case, create a "pseudo" macro
542 // expansion cursor for that token.
543 SourceLocation BeginLoc = RegionOfInterest.getBegin();
544 if (Cursor.kind == CXCursor_MacroDefinition &&
545 BeginLoc == RegionOfInterest.getEnd()) {
546 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000547 const MacroInfo *MI =
548 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000549 if (MacroDefinition *MacroDef =
550 checkForMacroInMacroDefinition(MI, Loc, TU))
551 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
552 }
553
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000554 // Nothing to visit at the moment.
555 return false;
556}
557
558bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
559 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
560 if (Visit(TSInfo->getTypeLoc()))
561 return true;
562
563 if (Stmt *Body = B->getBody())
564 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
565
566 return false;
567}
568
Ted Kremenek943f9092013-02-21 01:29:01 +0000569Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000570 if (RegionOfInterest.isValid()) {
571 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
572 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000573 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000574
575 switch (CompareRegionOfInterest(Range)) {
576 case RangeBefore:
577 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000578 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000579
580 case RangeAfter:
581 // This declaration comes after the region of interest; we're done.
582 return false;
583
584 case RangeOverlap:
585 // This declaration overlaps the region of interest; visit it.
586 break;
587 }
588 }
589 return true;
590}
591
592bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
593 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
594
595 // FIXME: Eventually remove. This part of a hack to support proper
596 // iteration over all Decls contained lexically within an ObjC container.
597 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
598 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
599
600 for ( ; I != E; ++I) {
601 Decl *D = *I;
602 if (D->getLexicalDeclContext() != DC)
603 continue;
604 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
605
606 // Ignore synthesized ivars here, otherwise if we have something like:
607 // @synthesize prop = _prop;
608 // and '_prop' is not declared, we will encounter a '_prop' ivar before
609 // encountering the 'prop' synthesize declaration and we will think that
610 // we passed the region-of-interest.
611 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
612 if (ivarD->getSynthesize())
613 continue;
614 }
615
616 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
617 // declarations is a mismatch with the compiler semantics.
618 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
619 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
620 if (!ID->isThisDeclarationADefinition())
621 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
622
623 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
624 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
625 if (!PD->isThisDeclarationADefinition())
626 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
627 }
628
Ted Kremenek943f9092013-02-21 01:29:01 +0000629 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000630 if (!V.hasValue())
631 continue;
632 if (!V.getValue())
633 return false;
634 if (Visit(Cursor, true))
635 return true;
636 }
637 return false;
638}
639
640bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
641 llvm_unreachable("Translation units are visited directly by Visit()");
642}
643
644bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
645 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
646 return Visit(TSInfo->getTypeLoc());
647
648 return false;
649}
650
651bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
652 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
653 return Visit(TSInfo->getTypeLoc());
654
655 return false;
656}
657
658bool CursorVisitor::VisitTagDecl(TagDecl *D) {
659 return VisitDeclContext(D);
660}
661
662bool CursorVisitor::VisitClassTemplateSpecializationDecl(
663 ClassTemplateSpecializationDecl *D) {
664 bool ShouldVisitBody = false;
665 switch (D->getSpecializationKind()) {
666 case TSK_Undeclared:
667 case TSK_ImplicitInstantiation:
668 // Nothing to visit
669 return false;
670
671 case TSK_ExplicitInstantiationDeclaration:
672 case TSK_ExplicitInstantiationDefinition:
673 break;
674
675 case TSK_ExplicitSpecialization:
676 ShouldVisitBody = true;
677 break;
678 }
679
680 // Visit the template arguments used in the specialization.
681 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
682 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000683 if (TemplateSpecializationTypeLoc TSTLoc =
684 TL.getAs<TemplateSpecializationTypeLoc>()) {
685 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
686 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000687 return true;
688 }
689 }
690
691 if (ShouldVisitBody && VisitCXXRecordDecl(D))
692 return true;
693
694 return false;
695}
696
697bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
698 ClassTemplatePartialSpecializationDecl *D) {
699 // FIXME: Visit the "outer" template parameter lists on the TagDecl
700 // before visiting these template parameters.
701 if (VisitTemplateParameters(D->getTemplateParameters()))
702 return true;
703
704 // Visit the partial specialization arguments.
Enea Zaffanellac1cef082013-08-10 07:24:53 +0000705 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
706 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
707 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000708 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
709 return true;
710
711 return VisitCXXRecordDecl(D);
712}
713
714bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
715 // Visit the default argument.
716 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
717 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
718 if (Visit(DefArg->getTypeLoc()))
719 return true;
720
721 return false;
722}
723
724bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
725 if (Expr *Init = D->getInitExpr())
726 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
727 return false;
728}
729
730bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000731 unsigned NumParamList = DD->getNumTemplateParameterLists();
732 for (unsigned i = 0; i < NumParamList; i++) {
733 TemplateParameterList* Params = DD->getTemplateParameterList(i);
734 if (VisitTemplateParameters(Params))
735 return true;
736 }
737
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000738 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
739 if (Visit(TSInfo->getTypeLoc()))
740 return true;
741
742 // Visit the nested-name-specifier, if present.
743 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
744 if (VisitNestedNameSpecifierLoc(QualifierLoc))
745 return true;
746
747 return false;
748}
749
750/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer767b3d22013-09-22 14:10:29 +0000751static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
752 CXXCtorInitializer *const *Y) {
753 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000754}
755
756bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000757 unsigned NumParamList = ND->getNumTemplateParameterLists();
758 for (unsigned i = 0; i < NumParamList; i++) {
759 TemplateParameterList* Params = ND->getTemplateParameterList(i);
760 if (VisitTemplateParameters(Params))
761 return true;
762 }
763
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000764 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
765 // Visit the function declaration's syntactic components in the order
766 // written. This requires a bit of work.
767 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000768 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000769
770 // If we have a function declared directly (without the use of a typedef),
771 // visit just the return type. Otherwise, just visit the function's type
772 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000773 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000774 (!FTL && Visit(TL)))
775 return true;
776
777 // Visit the nested-name-specifier, if present.
778 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
779 if (VisitNestedNameSpecifierLoc(QualifierLoc))
780 return true;
781
782 // Visit the declaration name.
783 if (VisitDeclarationNameInfo(ND->getNameInfo()))
784 return true;
785
786 // FIXME: Visit explicitly-specified template arguments!
787
788 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000789 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000790 return true;
791
Bill Wendlingad017fa2012-12-20 19:22:21 +0000792 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000793 }
794
795 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
796 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
797 // Find the initializers that were written in the source.
798 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
799 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
800 IEnd = Constructor->init_end();
801 I != IEnd; ++I) {
802 if (!(*I)->isWritten())
803 continue;
804
805 WrittenInits.push_back(*I);
806 }
807
808 // Sort the initializers in source order
809 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
810 &CompareCXXCtorInitializers);
811
812 // Visit the initializers in source order
813 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
814 CXXCtorInitializer *Init = WrittenInits[I];
815 if (Init->isAnyMemberInitializer()) {
816 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
817 Init->getMemberLocation(), TU)))
818 return true;
819 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
820 if (Visit(TInfo->getTypeLoc()))
821 return true;
822 }
823
824 // Visit the initializer value.
825 if (Expr *Initializer = Init->getInit())
826 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
827 return true;
828 }
829 }
830
831 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
832 return true;
833 }
834
835 return false;
836}
837
838bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
839 if (VisitDeclaratorDecl(D))
840 return true;
841
842 if (Expr *BitWidth = D->getBitWidth())
843 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
844
845 return false;
846}
847
848bool CursorVisitor::VisitVarDecl(VarDecl *D) {
849 if (VisitDeclaratorDecl(D))
850 return true;
851
852 if (Expr *Init = D->getInit())
853 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
854
855 return false;
856}
857
858bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
859 if (VisitDeclaratorDecl(D))
860 return true;
861
862 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
863 if (Expr *DefArg = D->getDefaultArgument())
864 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
870 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
871 // before visiting these template parameters.
872 if (VisitTemplateParameters(D->getTemplateParameters()))
873 return true;
874
875 return VisitFunctionDecl(D->getTemplatedDecl());
876}
877
878bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
879 // FIXME: Visit the "outer" template parameter lists on the TagDecl
880 // before visiting these template parameters.
881 if (VisitTemplateParameters(D->getTemplateParameters()))
882 return true;
883
884 return VisitCXXRecordDecl(D->getTemplatedDecl());
885}
886
887bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
892 VisitTemplateArgumentLoc(D->getDefaultArgument()))
893 return true;
894
895 return false;
896}
897
898bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
899 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
900 if (Visit(TSInfo->getTypeLoc()))
901 return true;
902
903 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
904 PEnd = ND->param_end();
905 P != PEnd; ++P) {
906 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
907 return true;
908 }
909
910 if (ND->isThisDeclarationADefinition() &&
911 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
912 return true;
913
914 return false;
915}
916
917template <typename DeclIt>
918static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
919 SourceManager &SM, SourceLocation EndLoc,
920 SmallVectorImpl<Decl *> &Decls) {
921 DeclIt next = *DI_current;
922 while (++next != DE_current) {
923 Decl *D_next = *next;
924 if (!D_next)
925 break;
926 SourceLocation L = D_next->getLocStart();
927 if (!L.isValid())
928 break;
929 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
930 *DI_current = next;
931 Decls.push_back(D_next);
932 continue;
933 }
934 break;
935 }
936}
937
938namespace {
939 struct ContainerDeclsSort {
940 SourceManager &SM;
941 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
942 bool operator()(Decl *A, Decl *B) {
943 SourceLocation L_A = A->getLocStart();
944 SourceLocation L_B = B->getLocStart();
945 assert(L_A.isValid() && L_B.isValid());
946 return SM.isBeforeInTranslationUnit(L_A, L_B);
947 }
948 };
949}
950
951bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
952 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
953 // an @implementation can lexically contain Decls that are not properly
954 // nested in the AST. When we identify such cases, we need to retrofit
955 // this nesting here.
956 if (!DI_current && !FileDI_current)
957 return VisitDeclContext(D);
958
959 // Scan the Decls that immediately come after the container
960 // in the current DeclContext. If any fall within the
961 // container's lexical region, stash them into a vector
962 // for later processing.
963 SmallVector<Decl *, 24> DeclsInContainer;
964 SourceLocation EndLoc = D->getSourceRange().getEnd();
965 SourceManager &SM = AU->getSourceManager();
966 if (EndLoc.isValid()) {
967 if (DI_current) {
968 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
969 DeclsInContainer);
970 } else {
971 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
972 DeclsInContainer);
973 }
974 }
975
976 // The common case.
977 if (DeclsInContainer.empty())
978 return VisitDeclContext(D);
979
980 // Get all the Decls in the DeclContext, and sort them with the
981 // additional ones we've collected. Then visit them.
982 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
983 I!=E; ++I) {
984 Decl *subDecl = *I;
985 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
986 subDecl->getLocStart().isInvalid())
987 continue;
988 DeclsInContainer.push_back(subDecl);
989 }
990
991 // Now sort the Decls so that they appear in lexical order.
992 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
993 ContainerDeclsSort(SM));
994
995 // Now visit the decls.
996 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
997 E = DeclsInContainer.end(); I != E; ++I) {
998 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +0000999 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001000 if (!V.hasValue())
1001 continue;
1002 if (!V.getValue())
1003 return false;
1004 if (Visit(Cursor, true))
1005 return true;
1006 }
1007 return false;
1008}
1009
1010bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1011 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1012 TU)))
1013 return true;
1014
1015 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1016 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1017 E = ND->protocol_end(); I != E; ++I, ++PL)
1018 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1019 return true;
1020
1021 return VisitObjCContainerDecl(ND);
1022}
1023
1024bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1025 if (!PID->isThisDeclarationADefinition())
1026 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1027
1028 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1029 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1030 E = PID->protocol_end(); I != E; ++I, ++PL)
1031 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1032 return true;
1033
1034 return VisitObjCContainerDecl(PID);
1035}
1036
1037bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1038 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1039 return true;
1040
1041 // FIXME: This implements a workaround with @property declarations also being
1042 // installed in the DeclContext for the @interface. Eventually this code
1043 // should be removed.
1044 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1045 if (!CDecl || !CDecl->IsClassExtension())
1046 return false;
1047
1048 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1049 if (!ID)
1050 return false;
1051
1052 IdentifierInfo *PropertyId = PD->getIdentifier();
1053 ObjCPropertyDecl *prevDecl =
1054 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1055
1056 if (!prevDecl)
1057 return false;
1058
1059 // Visit synthesized methods since they will be skipped when visiting
1060 // the @interface.
1061 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1062 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1063 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1064 return true;
1065
1066 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1067 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1068 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1069 return true;
1070
1071 return false;
1072}
1073
1074bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1075 if (!D->isThisDeclarationADefinition()) {
1076 // Forward declaration is treated like a reference.
1077 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1078 }
1079
1080 // Issue callbacks for super class.
1081 if (D->getSuperClass() &&
1082 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1083 D->getSuperClassLoc(),
1084 TU)))
1085 return true;
1086
1087 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1088 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1089 E = D->protocol_end(); I != E; ++I, ++PL)
1090 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1091 return true;
1092
1093 return VisitObjCContainerDecl(D);
1094}
1095
1096bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1101 // 'ID' could be null when dealing with invalid code.
1102 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1103 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1104 return true;
1105
1106 return VisitObjCImplDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1110#if 0
1111 // Issue callbacks for super class.
1112 // FIXME: No source location information!
1113 if (D->getSuperClass() &&
1114 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1115 D->getSuperClassLoc(),
1116 TU)))
1117 return true;
1118#endif
1119
1120 return VisitObjCImplDecl(D);
1121}
1122
1123bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1124 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1125 if (PD->isIvarNameSpecified())
1126 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1127
1128 return false;
1129}
1130
1131bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1132 return VisitDeclContext(D);
1133}
1134
1135bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1136 // Visit nested-name-specifier.
1137 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1138 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1139 return true;
1140
1141 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1142 D->getTargetNameLoc(), TU));
1143}
1144
1145bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150 }
1151
1152 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1153 return true;
1154
1155 return VisitDeclarationNameInfo(D->getNameInfo());
1156}
1157
1158bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1159 // Visit nested-name-specifier.
1160 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1161 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1162 return true;
1163
1164 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1165 D->getIdentLocation(), TU));
1166}
1167
1168bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173 }
1174
1175 return VisitDeclarationNameInfo(D->getNameInfo());
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1179 UnresolvedUsingTypenameDecl *D) {
1180 // Visit nested-name-specifier.
1181 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1182 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1183 return true;
1184
1185 return false;
1186}
1187
1188bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1189 switch (Name.getName().getNameKind()) {
1190 case clang::DeclarationName::Identifier:
1191 case clang::DeclarationName::CXXLiteralOperatorName:
1192 case clang::DeclarationName::CXXOperatorName:
1193 case clang::DeclarationName::CXXUsingDirective:
1194 return false;
1195
1196 case clang::DeclarationName::CXXConstructorName:
1197 case clang::DeclarationName::CXXDestructorName:
1198 case clang::DeclarationName::CXXConversionFunctionName:
1199 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1200 return Visit(TSInfo->getTypeLoc());
1201 return false;
1202
1203 case clang::DeclarationName::ObjCZeroArgSelector:
1204 case clang::DeclarationName::ObjCOneArgSelector:
1205 case clang::DeclarationName::ObjCMultiArgSelector:
1206 // FIXME: Per-identifier location info?
1207 return false;
1208 }
1209
1210 llvm_unreachable("Invalid DeclarationName::Kind!");
1211}
1212
1213bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1214 SourceRange Range) {
1215 // FIXME: This whole routine is a hack to work around the lack of proper
1216 // source information in nested-name-specifiers (PR5791). Since we do have
1217 // a beginning source location, we can visit the first component of the
1218 // nested-name-specifier, if it's a single-token component.
1219 if (!NNS)
1220 return false;
1221
1222 // Get the first component in the nested-name-specifier.
1223 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1224 NNS = Prefix;
1225
1226 switch (NNS->getKind()) {
1227 case NestedNameSpecifier::Namespace:
1228 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1229 TU));
1230
1231 case NestedNameSpecifier::NamespaceAlias:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1233 Range.getBegin(), TU));
1234
1235 case NestedNameSpecifier::TypeSpec: {
1236 // If the type has a form where we know that the beginning of the source
1237 // range matches up with a reference cursor. Visit the appropriate reference
1238 // cursor.
1239 const Type *T = NNS->getAsType();
1240 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1241 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1242 if (const TagType *Tag = dyn_cast<TagType>(T))
1243 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1244 if (const TemplateSpecializationType *TST
1245 = dyn_cast<TemplateSpecializationType>(T))
1246 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1247 break;
1248 }
1249
1250 case NestedNameSpecifier::TypeSpecWithTemplate:
1251 case NestedNameSpecifier::Global:
1252 case NestedNameSpecifier::Identifier:
1253 break;
1254 }
1255
1256 return false;
1257}
1258
1259bool
1260CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1261 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1262 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1263 Qualifiers.push_back(Qualifier);
1264
1265 while (!Qualifiers.empty()) {
1266 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1267 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1268 switch (NNS->getKind()) {
1269 case NestedNameSpecifier::Namespace:
1270 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1271 Q.getLocalBeginLoc(),
1272 TU)))
1273 return true;
1274
1275 break;
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::TypeSpec:
1286 case NestedNameSpecifier::TypeSpecWithTemplate:
1287 if (Visit(Q.getTypeLoc()))
1288 return true;
1289
1290 break;
1291
1292 case NestedNameSpecifier::Global:
1293 case NestedNameSpecifier::Identifier:
1294 break;
1295 }
1296 }
1297
1298 return false;
1299}
1300
1301bool CursorVisitor::VisitTemplateParameters(
1302 const TemplateParameterList *Params) {
1303 if (!Params)
1304 return false;
1305
1306 for (TemplateParameterList::const_iterator P = Params->begin(),
1307 PEnd = Params->end();
1308 P != PEnd; ++P) {
1309 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1310 return true;
1311 }
1312
1313 return false;
1314}
1315
1316bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1317 switch (Name.getKind()) {
1318 case TemplateName::Template:
1319 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1320
1321 case TemplateName::OverloadedTemplate:
1322 // Visit the overloaded template set.
1323 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1324 return true;
1325
1326 return false;
1327
1328 case TemplateName::DependentTemplate:
1329 // FIXME: Visit nested-name-specifier.
1330 return false;
1331
1332 case TemplateName::QualifiedTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return Visit(MakeCursorTemplateRef(
1335 Name.getAsQualifiedTemplateName()->getDecl(),
1336 Loc, TU));
1337
1338 case TemplateName::SubstTemplateTemplateParm:
1339 return Visit(MakeCursorTemplateRef(
1340 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1341 Loc, TU));
1342
1343 case TemplateName::SubstTemplateTemplateParmPack:
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1346 Loc, TU));
1347 }
1348
1349 llvm_unreachable("Invalid TemplateName::Kind!");
1350}
1351
1352bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1353 switch (TAL.getArgument().getKind()) {
1354 case TemplateArgument::Null:
1355 case TemplateArgument::Integral:
1356 case TemplateArgument::Pack:
1357 return false;
1358
1359 case TemplateArgument::Type:
1360 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1361 return Visit(TSInfo->getTypeLoc());
1362 return false;
1363
1364 case TemplateArgument::Declaration:
1365 if (Expr *E = TAL.getSourceDeclExpression())
1366 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1367 return false;
1368
1369 case TemplateArgument::NullPtr:
1370 if (Expr *E = TAL.getSourceNullPtrExpression())
1371 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1372 return false;
1373
1374 case TemplateArgument::Expression:
1375 if (Expr *E = TAL.getSourceExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::Template:
1380 case TemplateArgument::TemplateExpansion:
1381 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1382 return true;
1383
1384 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1385 TAL.getTemplateNameLoc());
1386 }
1387
1388 llvm_unreachable("Invalid TemplateArgument::Kind!");
1389}
1390
1391bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1392 return VisitDeclContext(D);
1393}
1394
1395bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1396 return Visit(TL.getUnqualifiedLoc());
1397}
1398
1399bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1400 ASTContext &Context = AU->getASTContext();
1401
1402 // Some builtin types (such as Objective-C's "id", "sel", and
1403 // "Class") have associated declarations. Create cursors for those.
1404 QualType VisitType;
1405 switch (TL.getTypePtr()->getKind()) {
1406
1407 case BuiltinType::Void:
1408 case BuiltinType::NullPtr:
1409 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001410 case BuiltinType::OCLImage1d:
1411 case BuiltinType::OCLImage1dArray:
1412 case BuiltinType::OCLImage1dBuffer:
1413 case BuiltinType::OCLImage2d:
1414 case BuiltinType::OCLImage2dArray:
1415 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001416 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001417 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001418#define BUILTIN_TYPE(Id, SingletonId)
1419#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1420#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#include "clang/AST/BuiltinTypes.def"
1424 break;
1425
1426 case BuiltinType::ObjCId:
1427 VisitType = Context.getObjCIdType();
1428 break;
1429
1430 case BuiltinType::ObjCClass:
1431 VisitType = Context.getObjCClassType();
1432 break;
1433
1434 case BuiltinType::ObjCSel:
1435 VisitType = Context.getObjCSelType();
1436 break;
1437 }
1438
1439 if (!VisitType.isNull()) {
1440 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1441 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1442 TU));
1443 }
1444
1445 return false;
1446}
1447
1448bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1450}
1451
1452bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1457 if (TL.isDefinition())
1458 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1459
1460 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1468 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1469 return true;
1470
1471 return false;
1472}
1473
1474bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1475 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1476 return true;
1477
1478 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1479 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1480 TU)))
1481 return true;
1482 }
1483
1484 return false;
1485}
1486
1487bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1492 return Visit(TL.getInnerLoc());
1493}
1494
1495bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1516 return Visit(TL.getModifiedLoc());
1517}
1518
1519bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1520 bool SkipResultType) {
1521 if (!SkipResultType && Visit(TL.getResultLoc()))
1522 return true;
1523
1524 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1525 if (Decl *D = TL.getArg(I))
1526 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1527 return true;
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1533 if (Visit(TL.getElementLoc()))
1534 return true;
1535
1536 if (Expr *Size = TL.getSizeExpr())
1537 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1538
1539 return false;
1540}
1541
Reid Kleckner12df2462013-06-24 17:51:48 +00001542bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1543 return Visit(TL.getOriginalLoc());
1544}
1545
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001546bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1547 TemplateSpecializationTypeLoc TL) {
1548 // Visit the template name.
1549 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1550 TL.getTemplateNameLoc()))
1551 return true;
1552
1553 // Visit the template arguments.
1554 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1555 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1556 return true;
1557
1558 return false;
1559}
1560
1561bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1562 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1563}
1564
1565bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1566 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1567 return Visit(TSInfo->getTypeLoc());
1568
1569 return false;
1570}
1571
1572bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1573 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1574 return Visit(TSInfo->getTypeLoc());
1575
1576 return false;
1577}
1578
1579bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1580 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1581 return true;
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1587 DependentTemplateSpecializationTypeLoc TL) {
1588 // Visit the nested-name-specifier, if there is one.
1589 if (TL.getQualifierLoc() &&
1590 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 // Visit the template arguments.
1594 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1595 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1602 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1603 return true;
1604
1605 return Visit(TL.getNamedTypeLoc());
1606}
1607
1608bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1609 return Visit(TL.getPatternLoc());
1610}
1611
1612bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1613 if (Expr *E = TL.getUnderlyingExpr())
1614 return Visit(MakeCXCursor(E, StmtParent, TU));
1615
1616 return false;
1617}
1618
1619bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1620 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1621}
1622
1623bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1624 return Visit(TL.getValueLoc());
1625}
1626
1627#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1628bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1629 return Visit##PARENT##Loc(TL); \
1630}
1631
1632DEFAULT_TYPELOC_IMPL(Complex, Type)
1633DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1634DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1635DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1636DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1638DEFAULT_TYPELOC_IMPL(Vector, Type)
1639DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1640DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1641DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1642DEFAULT_TYPELOC_IMPL(Record, TagType)
1643DEFAULT_TYPELOC_IMPL(Enum, TagType)
1644DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1645DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1646DEFAULT_TYPELOC_IMPL(Auto, Type)
1647
1648bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1649 // Visit the nested-name-specifier, if present.
1650 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1651 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1652 return true;
1653
1654 if (D->isCompleteDefinition()) {
1655 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1656 E = D->bases_end(); I != E; ++I) {
1657 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1658 return true;
1659 }
1660 }
1661
1662 return VisitTagDecl(D);
1663}
1664
1665bool CursorVisitor::VisitAttributes(Decl *D) {
1666 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1667 i != e; ++i)
1668 if (Visit(MakeCXCursor(*i, D, TU)))
1669 return true;
1670
1671 return false;
1672}
1673
1674//===----------------------------------------------------------------------===//
1675// Data-recursive visitor methods.
1676//===----------------------------------------------------------------------===//
1677
1678namespace {
1679#define DEF_JOB(NAME, DATA, KIND)\
1680class NAME : public VisitorJob {\
1681public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001682 NAME(const DATA *d, CXCursor parent) : \
1683 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001684 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001685 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001686};
1687
1688DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1689DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1690DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1691DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1692DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1693 ExplicitTemplateArgsVisitKind)
1694DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1695DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1696DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1697#undef DEF_JOB
1698
1699class DeclVisit : public VisitorJob {
1700public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001701 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001702 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001703 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001704 static bool classof(const VisitorJob *VJ) {
1705 return VJ->getKind() == DeclVisitKind;
1706 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001707 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001708 bool isFirst() const { return data[1] ? true : false; }
1709};
1710class TypeLocVisit : public VisitorJob {
1711public:
1712 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1713 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1714 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1715
1716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == TypeLocVisitKind;
1718 }
1719
1720 TypeLoc get() const {
1721 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001722 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001723 }
1724};
1725
1726class LabelRefVisit : public VisitorJob {
1727public:
1728 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1729 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1730 labelLoc.getPtrEncoding()) {}
1731
1732 static bool classof(const VisitorJob *VJ) {
1733 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1734 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001735 const LabelDecl *get() const {
1736 return static_cast<const LabelDecl *>(data[0]);
1737 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001738 SourceLocation getLoc() const {
1739 return SourceLocation::getFromPtrEncoding(data[1]); }
1740};
1741
1742class NestedNameSpecifierLocVisit : public VisitorJob {
1743public:
1744 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1745 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1746 Qualifier.getNestedNameSpecifier(),
1747 Qualifier.getOpaqueData()) { }
1748
1749 static bool classof(const VisitorJob *VJ) {
1750 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1751 }
1752
1753 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001754 return NestedNameSpecifierLoc(
1755 const_cast<NestedNameSpecifier *>(
1756 static_cast<const NestedNameSpecifier *>(data[0])),
1757 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001758 }
1759};
1760
1761class DeclarationNameInfoVisit : public VisitorJob {
1762public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001763 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001764 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001765 static bool classof(const VisitorJob *VJ) {
1766 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1767 }
1768 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001769 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001770 switch (S->getStmtClass()) {
1771 default:
1772 llvm_unreachable("Unhandled Stmt");
1773 case clang::Stmt::MSDependentExistsStmtClass:
1774 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1775 case Stmt::CXXDependentScopeMemberExprClass:
1776 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1777 case Stmt::DependentScopeDeclRefExprClass:
1778 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1779 }
1780 }
1781};
1782class MemberRefVisit : public VisitorJob {
1783public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001784 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001785 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1786 L.getPtrEncoding()) {}
1787 static bool classof(const VisitorJob *VJ) {
1788 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1789 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001790 const FieldDecl *get() const {
1791 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001792 }
1793 SourceLocation getLoc() const {
1794 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1795 }
1796};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001797class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001798 friend class OMPClauseEnqueue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001799 VisitorWorkList &WL;
1800 CXCursor Parent;
1801public:
1802 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1803 : WL(wl), Parent(parent) {}
1804
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001805 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1806 void VisitBlockExpr(const BlockExpr *B);
1807 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1808 void VisitCompoundStmt(const CompoundStmt *S);
1809 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1810 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1811 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1812 void VisitCXXNewExpr(const CXXNewExpr *E);
1813 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1814 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1815 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1816 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1817 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1818 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1819 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1820 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1821 void VisitDeclRefExpr(const DeclRefExpr *D);
1822 void VisitDeclStmt(const DeclStmt *S);
1823 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1824 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1825 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1826 void VisitForStmt(const ForStmt *FS);
1827 void VisitGotoStmt(const GotoStmt *GS);
1828 void VisitIfStmt(const IfStmt *If);
1829 void VisitInitListExpr(const InitListExpr *IE);
1830 void VisitMemberExpr(const MemberExpr *M);
1831 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1832 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1833 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1834 void VisitOverloadExpr(const OverloadExpr *E);
1835 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1836 void VisitStmt(const Stmt *S);
1837 void VisitSwitchStmt(const SwitchStmt *S);
1838 void VisitWhileStmt(const WhileStmt *W);
1839 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1840 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1841 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1842 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1843 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1844 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1845 void VisitVAArgExpr(const VAArgExpr *E);
1846 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1847 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1848 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1849 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001850 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1851 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001852
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001853private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001854 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001855 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1856 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001857 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1858 void AddStmt(const Stmt *S);
1859 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001860 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001861 void EnqueueChildren(const Stmt *S);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001862 void EnqueueChildren(const OMPClause *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001863};
1864} // end anonyous namespace
1865
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001866void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001867 // 'S' should always be non-null, since it comes from the
1868 // statement we are visiting.
1869 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1870}
1871
1872void
1873EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1874 if (Qualifier)
1875 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1876}
1877
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001878void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001879 if (S)
1880 WL.push_back(StmtVisit(S, Parent));
1881}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001882void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001883 if (D)
1884 WL.push_back(DeclVisit(D, Parent, isFirst));
1885}
1886void EnqueueVisitor::
1887 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1888 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001889 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001890}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001891void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001892 if (D)
1893 WL.push_back(MemberRefVisit(D, L, Parent));
1894}
1895void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1896 if (TI)
1897 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1898 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001899void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001901 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001902 AddStmt(*Child);
1903 }
1904 if (size == WL.size())
1905 return;
1906 // Now reverse the entries we just added. This will match the DFS
1907 // ordering performed by the worklist.
1908 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1909 std::reverse(I, E);
1910}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001911namespace {
1912class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1913 EnqueueVisitor *Visitor;
1914public:
1915 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1916#define OPENMP_CLAUSE(Name, Class) \
1917 void Visit##Class(const Class *C);
1918#include "clang/Basic/OpenMPKinds.def"
1919};
1920
1921void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
1922#define PROCESS_OMP_CLAUSE_LIST(Class, Node) \
1923 for (OMPVarList<Class>::varlist_const_iterator I = Node->varlist_begin(), \
1924 E = Node->varlist_end(); \
1925 I != E; ++I) \
1926 Visitor->AddStmt(*I);
1927
1928void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
1929 PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
1930}
Alexey Bataev0c018352013-09-06 18:03:48 +00001931void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
1932 PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
1933}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001934#undef PROCESS_OMP_CLAUSE_LIST
1935}
1936void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1937 unsigned size = WL.size();
1938 OMPClauseEnqueue Visitor(this);
1939 Visitor.Visit(S);
1940 if (size == WL.size())
1941 return;
1942 // Now reverse the entries we just added. This will match the DFS
1943 // ordering performed by the worklist.
1944 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945 std::reverse(I, E);
1946}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001947void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001948 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1949}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001950void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001951 AddDecl(B->getBlockDecl());
1952}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001953void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001954 EnqueueChildren(E);
1955 AddTypeLoc(E->getTypeSourceInfo());
1956}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001957void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1958 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001959 E = S->body_rend(); I != E; ++I) {
1960 AddStmt(*I);
1961 }
1962}
1963void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001964VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001965 AddStmt(S->getSubStmt());
1966 AddDeclarationNameInfo(S);
1967 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1968 AddNestedNameSpecifierLoc(QualifierLoc);
1969}
1970
1971void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001972VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001973 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1974 AddDeclarationNameInfo(E);
1975 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1976 AddNestedNameSpecifierLoc(QualifierLoc);
1977 if (!E->isImplicitAccess())
1978 AddStmt(E->getBase());
1979}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001980void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001981 // Enqueue the initializer , if any.
1982 AddStmt(E->getInitializer());
1983 // Enqueue the array size, if any.
1984 AddStmt(E->getArraySize());
1985 // Enqueue the allocated type.
1986 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1987 // Enqueue the placement arguments.
1988 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1989 AddStmt(E->getPlacementArg(I-1));
1990}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001991void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001992 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1993 AddStmt(CE->getArg(I-1));
1994 AddStmt(CE->getCallee());
1995 AddStmt(CE->getArg(0));
1996}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001997void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1998 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001999 // Visit the name of the type being destroyed.
2000 AddTypeLoc(E->getDestroyedTypeInfo());
2001 // Visit the scope type that looks disturbingly like the nested-name-specifier
2002 // but isn't.
2003 AddTypeLoc(E->getScopeTypeInfo());
2004 // Visit the nested-name-specifier.
2005 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2006 AddNestedNameSpecifierLoc(QualifierLoc);
2007 // Visit base expression.
2008 AddStmt(E->getBase());
2009}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2011 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002012 AddTypeLoc(E->getTypeSourceInfo());
2013}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2015 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002016 EnqueueChildren(E);
2017 AddTypeLoc(E->getTypeSourceInfo());
2018}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002020 EnqueueChildren(E);
2021 if (E->isTypeOperand())
2022 AddTypeLoc(E->getTypeOperandSourceInfo());
2023}
2024
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2026 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002027 EnqueueChildren(E);
2028 AddTypeLoc(E->getTypeSourceInfo());
2029}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002031 EnqueueChildren(E);
2032 if (E->isTypeOperand())
2033 AddTypeLoc(E->getTypeOperandSourceInfo());
2034}
2035
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002037 EnqueueChildren(S);
2038 AddDecl(S->getExceptionDecl());
2039}
2040
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002042 if (DR->hasExplicitTemplateArgs()) {
2043 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2044 }
2045 WL.push_back(DeclRefExprParts(DR, Parent));
2046}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2048 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002049 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2050 AddDeclarationNameInfo(E);
2051 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2052}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002054 unsigned size = WL.size();
2055 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002056 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002057 D != DEnd; ++D) {
2058 AddDecl(*D, isFirst);
2059 isFirst = false;
2060 }
2061 if (size == WL.size())
2062 return;
2063 // Now reverse the entries we just added. This will match the DFS
2064 // ordering performed by the worklist.
2065 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2066 std::reverse(I, E);
2067}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002069 AddStmt(E->getInit());
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002070 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002071 D = E->designators_rbegin(), DEnd = E->designators_rend();
2072 D != DEnd; ++D) {
2073 if (D->isFieldDesignator()) {
2074 if (FieldDecl *Field = D->getField())
2075 AddMemberRef(Field, D->getFieldLoc());
2076 continue;
2077 }
2078 if (D->isArrayDesignator()) {
2079 AddStmt(E->getArrayIndex(*D));
2080 continue;
2081 }
2082 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2083 AddStmt(E->getArrayRangeEnd(*D));
2084 AddStmt(E->getArrayRangeStart(*D));
2085 }
2086}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002088 EnqueueChildren(E);
2089 AddTypeLoc(E->getTypeInfoAsWritten());
2090}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002092 AddStmt(FS->getBody());
2093 AddStmt(FS->getInc());
2094 AddStmt(FS->getCond());
2095 AddDecl(FS->getConditionVariable());
2096 AddStmt(FS->getInit());
2097}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002099 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2100}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002102 AddStmt(If->getElse());
2103 AddStmt(If->getThen());
2104 AddStmt(If->getCond());
2105 AddDecl(If->getConditionVariable());
2106}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002108 // We care about the syntactic form of the initializer list, only.
2109 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2110 IE = Syntactic;
2111 EnqueueChildren(IE);
2112}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002114 WL.push_back(MemberExprParts(M, Parent));
2115
2116 // If the base of the member access expression is an implicit 'this', don't
2117 // visit it.
2118 // FIXME: If we ever want to show these implicit accesses, this will be
2119 // unfortunate. However, clang_getCursor() relies on this behavior.
2120 if (!M->isImplicitAccess())
2121 AddStmt(M->getBase());
2122}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002124 AddTypeLoc(E->getEncodedTypeSourceInfo());
2125}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002127 EnqueueChildren(M);
2128 AddTypeLoc(M->getClassReceiverTypeInfo());
2129}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002131 // Visit the components of the offsetof expression.
2132 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2133 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2134 const OffsetOfNode &Node = E->getComponent(I-1);
2135 switch (Node.getKind()) {
2136 case OffsetOfNode::Array:
2137 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2138 break;
2139 case OffsetOfNode::Field:
2140 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2141 break;
2142 case OffsetOfNode::Identifier:
2143 case OffsetOfNode::Base:
2144 continue;
2145 }
2146 }
2147 // Visit the type into which we're computing the offset.
2148 AddTypeLoc(E->getTypeSourceInfo());
2149}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002151 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2152 WL.push_back(OverloadExprParts(E, Parent));
2153}
2154void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002155 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002156 EnqueueChildren(E);
2157 if (E->isArgumentType())
2158 AddTypeLoc(E->getArgumentTypeInfo());
2159}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002161 EnqueueChildren(S);
2162}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002164 AddStmt(S->getBody());
2165 AddStmt(S->getCond());
2166 AddDecl(S->getConditionVariable());
2167}
2168
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002170 AddStmt(W->getBody());
2171 AddStmt(W->getCond());
2172 AddDecl(W->getConditionVariable());
2173}
2174
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002176 AddTypeLoc(E->getQueriedTypeSourceInfo());
2177}
2178
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002180 AddTypeLoc(E->getRhsTypeSourceInfo());
2181 AddTypeLoc(E->getLhsTypeSourceInfo());
2182}
2183
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002185 for (unsigned I = E->getNumArgs(); I > 0; --I)
2186 AddTypeLoc(E->getArg(I-1));
2187}
2188
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002190 AddTypeLoc(E->getQueriedTypeSourceInfo());
2191}
2192
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002194 EnqueueChildren(E);
2195}
2196
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002198 VisitOverloadExpr(U);
2199 if (!U->isImplicitAccess())
2200 AddStmt(U->getBase());
2201}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002203 AddStmt(E->getSubExpr());
2204 AddTypeLoc(E->getWrittenTypeInfo());
2205}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002207 WL.push_back(SizeOfPackExprParts(E, Parent));
2208}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002210 // If the opaque value has a source expression, just transparently
2211 // visit that. This is useful for (e.g.) pseudo-object expressions.
2212 if (Expr *SourceExpr = E->getSourceExpr())
2213 return Visit(SourceExpr);
2214}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002216 AddStmt(E->getBody());
2217 WL.push_back(LambdaExprParts(E, Parent));
2218}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002220 // Treat the expression like its syntactic form.
2221 Visit(E->getSyntacticForm());
2222}
2223
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002224void EnqueueVisitor::VisitOMPExecutableDirective(
2225 const OMPExecutableDirective *D) {
2226 EnqueueChildren(D);
2227 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2228 E = D->clauses().end();
2229 I != E; ++I)
2230 EnqueueChildren(*I);
2231}
2232
2233void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2234 VisitOMPExecutableDirective(D);
2235}
2236
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002237void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002238 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2239}
2240
2241bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2242 if (RegionOfInterest.isValid()) {
2243 SourceRange Range = getRawCursorExtent(C);
2244 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2245 return false;
2246 }
2247 return true;
2248}
2249
2250bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2251 while (!WL.empty()) {
2252 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002253 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002254
2255 // Set the Parent field, then back to its old value once we're done.
2256 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2257
2258 switch (LI.getKind()) {
2259 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002260 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002261 if (!D)
2262 continue;
2263
2264 // For now, perform default visitation for Decls.
2265 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2266 cast<DeclVisit>(&LI)->isFirst())))
2267 return true;
2268
2269 continue;
2270 }
2271 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2272 const ASTTemplateArgumentListInfo *ArgList =
2273 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2274 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2275 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2276 Arg != ArgEnd; ++Arg) {
2277 if (VisitTemplateArgumentLoc(*Arg))
2278 return true;
2279 }
2280 continue;
2281 }
2282 case VisitorJob::TypeLocVisitKind: {
2283 // Perform default visitation for TypeLocs.
2284 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2285 return true;
2286 continue;
2287 }
2288 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002289 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002290 if (LabelStmt *stmt = LS->getStmt()) {
2291 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2292 TU))) {
2293 return true;
2294 }
2295 }
2296 continue;
2297 }
2298
2299 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2300 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2301 if (VisitNestedNameSpecifierLoc(V->get()))
2302 return true;
2303 continue;
2304 }
2305
2306 case VisitorJob::DeclarationNameInfoVisitKind: {
2307 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2308 ->get()))
2309 return true;
2310 continue;
2311 }
2312 case VisitorJob::MemberRefVisitKind: {
2313 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2314 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2315 return true;
2316 continue;
2317 }
2318 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002319 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002320 if (!S)
2321 continue;
2322
2323 // Update the current cursor.
2324 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2325 if (!IsInRegionOfInterest(Cursor))
2326 continue;
2327 switch (Visitor(Cursor, Parent, ClientData)) {
2328 case CXChildVisit_Break: return true;
2329 case CXChildVisit_Continue: break;
2330 case CXChildVisit_Recurse:
2331 if (PostChildrenVisitor)
2332 WL.push_back(PostChildrenVisit(0, Cursor));
2333 EnqueueWorkList(WL, S);
2334 break;
2335 }
2336 continue;
2337 }
2338 case VisitorJob::MemberExprPartsKind: {
2339 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002340 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002341
2342 // Visit the nested-name-specifier
2343 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2344 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2345 return true;
2346
2347 // Visit the declaration name.
2348 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2349 return true;
2350
2351 // Visit the explicitly-specified template arguments, if any.
2352 if (M->hasExplicitTemplateArgs()) {
2353 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2354 *ArgEnd = Arg + M->getNumTemplateArgs();
2355 Arg != ArgEnd; ++Arg) {
2356 if (VisitTemplateArgumentLoc(*Arg))
2357 return true;
2358 }
2359 }
2360 continue;
2361 }
2362 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002363 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002364 // Visit nested-name-specifier, if present.
2365 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2366 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2367 return true;
2368 // Visit declaration name.
2369 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2370 return true;
2371 continue;
2372 }
2373 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002374 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002375 // Visit the nested-name-specifier.
2376 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2377 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2378 return true;
2379 // Visit the declaration name.
2380 if (VisitDeclarationNameInfo(O->getNameInfo()))
2381 return true;
2382 // Visit the overloaded declaration reference.
2383 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2384 return true;
2385 continue;
2386 }
2387 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002388 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002389 NamedDecl *Pack = E->getPack();
2390 if (isa<TemplateTypeParmDecl>(Pack)) {
2391 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2392 E->getPackLoc(), TU)))
2393 return true;
2394
2395 continue;
2396 }
2397
2398 if (isa<TemplateTemplateParmDecl>(Pack)) {
2399 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2400 E->getPackLoc(), TU)))
2401 return true;
2402
2403 continue;
2404 }
2405
2406 // Non-type template parameter packs and function parameter packs are
2407 // treated like DeclRefExpr cursors.
2408 continue;
2409 }
2410
2411 case VisitorJob::LambdaExprPartsKind: {
2412 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002413 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002414 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2415 CEnd = E->explicit_capture_end();
2416 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002417 // FIXME: Lambda init-captures.
2418 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002419 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002420
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002421 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2422 C->getLocation(),
2423 TU)))
2424 return true;
2425 }
2426
2427 // Visit parameters and return type, if present.
2428 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2429 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2430 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2431 // Visit the whole type.
2432 if (Visit(TL))
2433 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002434 } else if (FunctionProtoTypeLoc Proto =
2435 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002436 if (E->hasExplicitParameters()) {
2437 // Visit parameters.
2438 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2439 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2440 return true;
2441 } else {
2442 // Visit result type.
2443 if (Visit(Proto.getResultLoc()))
2444 return true;
2445 }
2446 }
2447 }
2448 break;
2449 }
2450
2451 case VisitorJob::PostChildrenVisitKind:
2452 if (PostChildrenVisitor(Parent, ClientData))
2453 return true;
2454 break;
2455 }
2456 }
2457 return false;
2458}
2459
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002460bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002461 VisitorWorkList *WL = 0;
2462 if (!WorkListFreeList.empty()) {
2463 WL = WorkListFreeList.back();
2464 WL->clear();
2465 WorkListFreeList.pop_back();
2466 }
2467 else {
2468 WL = new VisitorWorkList();
2469 WorkListCache.push_back(WL);
2470 }
2471 EnqueueWorkList(*WL, S);
2472 bool result = RunVisitorWorkList(*WL);
2473 WorkListFreeList.push_back(WL);
2474 return result;
2475}
2476
2477namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002478typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002479RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2480 const DeclarationNameInfo &NI,
2481 const SourceRange &QLoc,
2482 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2483 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2484 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2485 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2486
2487 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2488
2489 RefNamePieces Pieces;
2490
2491 if (WantQualifier && QLoc.isValid())
2492 Pieces.push_back(QLoc);
2493
2494 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2495 Pieces.push_back(NI.getLoc());
2496
2497 if (WantTemplateArgs && TemplateArgs)
2498 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2499 TemplateArgs->RAngleLoc));
2500
2501 if (Kind == DeclarationName::CXXOperatorName) {
2502 Pieces.push_back(SourceLocation::getFromRawEncoding(
2503 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2504 Pieces.push_back(SourceLocation::getFromRawEncoding(
2505 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2506 }
2507
2508 if (WantSinglePiece) {
2509 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2510 Pieces.clear();
2511 Pieces.push_back(R);
2512 }
2513
2514 return Pieces;
2515}
2516}
2517
2518//===----------------------------------------------------------------------===//
2519// Misc. API hooks.
2520//===----------------------------------------------------------------------===//
2521
2522static llvm::sys::Mutex EnableMultithreadingMutex;
2523static bool EnabledMultithreading;
2524
Chad Rosier90836282013-03-27 18:28:23 +00002525static void fatal_error_handler(void *user_data, const std::string& reason,
2526 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002527 // Write the result out to stderr avoiding errs() because raw_ostreams can
2528 // call report_fatal_error.
2529 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2530 ::abort();
2531}
2532
2533extern "C" {
2534CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2535 int displayDiagnostics) {
2536 // Disable pretty stack trace functionality, which will otherwise be a very
2537 // poor citizen of the world and set up all sorts of signal handlers.
2538 llvm::DisablePrettyStackTrace = true;
2539
2540 // We use crash recovery to make some of our APIs more reliable, implicitly
2541 // enable it.
2542 llvm::CrashRecoveryContext::Enable();
2543
2544 // Enable support for multithreading in LLVM.
2545 {
2546 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2547 if (!EnabledMultithreading) {
2548 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2549 llvm::llvm_start_multithreaded();
2550 EnabledMultithreading = true;
2551 }
2552 }
2553
2554 CIndexer *CIdxr = new CIndexer();
2555 if (excludeDeclarationsFromPCH)
2556 CIdxr->setOnlyLocalDecls();
2557 if (displayDiagnostics)
2558 CIdxr->setDisplayDiagnostics();
2559
2560 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2561 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2562 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2563 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2564 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2565 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2566
2567 return CIdxr;
2568}
2569
2570void clang_disposeIndex(CXIndex CIdx) {
2571 if (CIdx)
2572 delete static_cast<CIndexer *>(CIdx);
2573}
2574
2575void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2576 if (CIdx)
2577 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2578}
2579
2580unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2581 if (CIdx)
2582 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2583 return 0;
2584}
2585
2586void clang_toggleCrashRecovery(unsigned isEnabled) {
2587 if (isEnabled)
2588 llvm::CrashRecoveryContext::Enable();
2589 else
2590 llvm::CrashRecoveryContext::Disable();
2591}
2592
2593CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2594 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002595 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002596 return 0;
2597
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002598 LOG_FUNC_SECTION {
2599 *Log << ast_filename;
2600 }
2601
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002602 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2603 FileSystemOptions FileSystemOpts;
2604
2605 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2606 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2607 CXXIdx->getOnlyLocalDecls(),
2608 0, 0,
2609 /*CaptureDiagnostics=*/true,
2610 /*AllowPCHWithCompilerErrors=*/true,
2611 /*UserFilesAreVolatile=*/true);
2612 return MakeCXTranslationUnit(CXXIdx, TU);
2613}
2614
2615unsigned clang_defaultEditingTranslationUnitOptions() {
2616 return CXTranslationUnit_PrecompiledPreamble |
2617 CXTranslationUnit_CacheCompletionResults;
2618}
2619
2620CXTranslationUnit
2621clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2622 const char *source_filename,
2623 int num_command_line_args,
2624 const char * const *command_line_args,
2625 unsigned num_unsaved_files,
2626 struct CXUnsavedFile *unsaved_files) {
2627 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2628 return clang_parseTranslationUnit(CIdx, source_filename,
2629 command_line_args, num_command_line_args,
2630 unsaved_files, num_unsaved_files,
2631 Options);
2632}
2633
2634struct ParseTranslationUnitInfo {
2635 CXIndex CIdx;
2636 const char *source_filename;
2637 const char *const *command_line_args;
2638 int num_command_line_args;
2639 struct CXUnsavedFile *unsaved_files;
2640 unsigned num_unsaved_files;
2641 unsigned options;
2642 CXTranslationUnit result;
2643};
2644static void clang_parseTranslationUnit_Impl(void *UserData) {
2645 ParseTranslationUnitInfo *PTUI =
2646 static_cast<ParseTranslationUnitInfo*>(UserData);
2647 CXIndex CIdx = PTUI->CIdx;
2648 const char *source_filename = PTUI->source_filename;
2649 const char * const *command_line_args = PTUI->command_line_args;
2650 int num_command_line_args = PTUI->num_command_line_args;
2651 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2652 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2653 unsigned options = PTUI->options;
2654 PTUI->result = 0;
2655
2656 if (!CIdx)
2657 return;
2658
2659 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2660
2661 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2662 setThreadBackgroundPriority();
2663
2664 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2665 // FIXME: Add a flag for modules.
2666 TranslationUnitKind TUKind
2667 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2668 bool CacheCodeCompetionResults
2669 = options & CXTranslationUnit_CacheCompletionResults;
2670 bool IncludeBriefCommentsInCodeCompletion
2671 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2672 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2673 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2674
2675 // Configure the diagnostics.
2676 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002677 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002678
2679 // Recover resources if we crash before exiting this function.
2680 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2681 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2682 DiagCleanup(Diags.getPtr());
2683
2684 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2685 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2686
2687 // Recover resources if we crash before exiting this function.
2688 llvm::CrashRecoveryContextCleanupRegistrar<
2689 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2690
2691 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2692 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2693 const llvm::MemoryBuffer *Buffer
2694 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2695 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2696 Buffer));
2697 }
2698
2699 OwningPtr<std::vector<const char *> >
2700 Args(new std::vector<const char*>());
2701
2702 // Recover resources if we crash before exiting this method.
2703 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2704 ArgsCleanup(Args.get());
2705
2706 // Since the Clang C library is primarily used by batch tools dealing with
2707 // (often very broken) source code, where spell-checking can have a
2708 // significant negative impact on performance (particularly when
2709 // precompiled headers are involved), we disable it by default.
2710 // Only do this if we haven't found a spell-checking-related argument.
2711 bool FoundSpellCheckingArgument = false;
2712 for (int I = 0; I != num_command_line_args; ++I) {
2713 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2714 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2715 FoundSpellCheckingArgument = true;
2716 break;
2717 }
2718 }
2719 if (!FoundSpellCheckingArgument)
2720 Args->push_back("-fno-spell-checking");
2721
2722 Args->insert(Args->end(), command_line_args,
2723 command_line_args + num_command_line_args);
2724
2725 // The 'source_filename' argument is optional. If the caller does not
2726 // specify it then it is assumed that the source file is specified
2727 // in the actual argument list.
2728 // Put the source file after command_line_args otherwise if '-x' flag is
2729 // present it will be unused.
2730 if (source_filename)
2731 Args->push_back(source_filename);
2732
2733 // Do we need the detailed preprocessing record?
2734 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2735 Args->push_back("-Xclang");
2736 Args->push_back("-detailed-preprocessing-record");
2737 }
2738
2739 unsigned NumErrors = Diags->getClient()->getNumErrors();
2740 OwningPtr<ASTUnit> ErrUnit;
2741 OwningPtr<ASTUnit> Unit(
2742 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2743 /* vector::data() not portable */,
2744 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2745 Diags,
2746 CXXIdx->getClangResourcesPath(),
2747 CXXIdx->getOnlyLocalDecls(),
2748 /*CaptureDiagnostics=*/true,
2749 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2750 RemappedFiles->size(),
2751 /*RemappedFilesKeepOriginalName=*/true,
2752 PrecompilePreamble,
2753 TUKind,
2754 CacheCodeCompetionResults,
2755 IncludeBriefCommentsInCodeCompletion,
2756 /*AllowPCHWithCompilerErrors=*/true,
2757 SkipFunctionBodies,
2758 /*UserFilesAreVolatile=*/true,
2759 ForSerialization,
2760 &ErrUnit));
2761
2762 if (NumErrors != Diags->getClient()->getNumErrors()) {
2763 // Make sure to check that 'Unit' is non-NULL.
2764 if (CXXIdx->getDisplayDiagnostics())
2765 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2766 }
2767
2768 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2769}
2770CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2771 const char *source_filename,
2772 const char * const *command_line_args,
2773 int num_command_line_args,
2774 struct CXUnsavedFile *unsaved_files,
2775 unsigned num_unsaved_files,
2776 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002777 LOG_FUNC_SECTION {
2778 *Log << source_filename << ": ";
2779 for (int i = 0; i != num_command_line_args; ++i)
2780 *Log << command_line_args[i] << " ";
2781 }
2782
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002783 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2784 num_command_line_args, unsaved_files,
2785 num_unsaved_files, options, 0 };
2786 llvm::CrashRecoveryContext CRC;
2787
2788 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2789 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2790 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2791 fprintf(stderr, " 'command_line_args' : [");
2792 for (int i = 0; i != num_command_line_args; ++i) {
2793 if (i)
2794 fprintf(stderr, ", ");
2795 fprintf(stderr, "'%s'", command_line_args[i]);
2796 }
2797 fprintf(stderr, "],\n");
2798 fprintf(stderr, " 'unsaved_files' : [");
2799 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2800 if (i)
2801 fprintf(stderr, ", ");
2802 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2803 unsaved_files[i].Length);
2804 }
2805 fprintf(stderr, "],\n");
2806 fprintf(stderr, " 'options' : %d,\n", options);
2807 fprintf(stderr, "}\n");
2808
2809 return 0;
2810 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2811 PrintLibclangResourceUsage(PTUI.result);
2812 }
2813
2814 return PTUI.result;
2815}
2816
2817unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2818 return CXSaveTranslationUnit_None;
2819}
2820
2821namespace {
2822
2823struct SaveTranslationUnitInfo {
2824 CXTranslationUnit TU;
2825 const char *FileName;
2826 unsigned options;
2827 CXSaveError result;
2828};
2829
2830}
2831
2832static void clang_saveTranslationUnit_Impl(void *UserData) {
2833 SaveTranslationUnitInfo *STUI =
2834 static_cast<SaveTranslationUnitInfo*>(UserData);
2835
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002836 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002837 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2838 setThreadBackgroundPriority();
2839
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002840 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002841 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2842}
2843
2844int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2845 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002846 LOG_FUNC_SECTION {
2847 *Log << TU << ' ' << FileName;
2848 }
2849
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002850 if (!TU)
2851 return CXSaveError_InvalidTU;
2852
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002853 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002854 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2855 if (!CXXUnit->hasSema())
2856 return CXSaveError_InvalidTU;
2857
2858 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2859
2860 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2861 getenv("LIBCLANG_NOTHREADS")) {
2862 clang_saveTranslationUnit_Impl(&STUI);
2863
2864 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2865 PrintLibclangResourceUsage(TU);
2866
2867 return STUI.result;
2868 }
2869
2870 // We have an AST that has invalid nodes due to compiler errors.
2871 // Use a crash recovery thread for protection.
2872
2873 llvm::CrashRecoveryContext CRC;
2874
2875 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2876 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2877 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2878 fprintf(stderr, " 'options' : %d,\n", options);
2879 fprintf(stderr, "}\n");
2880
2881 return CXSaveError_Unknown;
2882
2883 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2884 PrintLibclangResourceUsage(TU);
2885 }
2886
2887 return STUI.result;
2888}
2889
2890void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2891 if (CTUnit) {
2892 // If the translation unit has been marked as unsafe to free, just discard
2893 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002894 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002895 return;
2896
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002897 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002898 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002899 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2900 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002901 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002902 delete CTUnit;
2903 }
2904}
2905
2906unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2907 return CXReparse_None;
2908}
2909
2910struct ReparseTranslationUnitInfo {
2911 CXTranslationUnit TU;
2912 unsigned num_unsaved_files;
2913 struct CXUnsavedFile *unsaved_files;
2914 unsigned options;
2915 int result;
2916};
2917
2918static void clang_reparseTranslationUnit_Impl(void *UserData) {
2919 ReparseTranslationUnitInfo *RTUI =
2920 static_cast<ReparseTranslationUnitInfo*>(UserData);
2921 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002922 if (!TU)
2923 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002924
2925 // Reset the associated diagnostics.
2926 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2927 TU->Diagnostics = 0;
2928
2929 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2930 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2931 unsigned options = RTUI->options;
2932 (void) options;
2933 RTUI->result = 1;
2934
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002935 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002936 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2937 setThreadBackgroundPriority();
2938
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002939 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002940 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2941
2942 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2943 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2944
2945 // Recover resources if we crash before exiting this function.
2946 llvm::CrashRecoveryContextCleanupRegistrar<
2947 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2948
2949 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2950 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2951 const llvm::MemoryBuffer *Buffer
2952 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2953 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2954 Buffer));
2955 }
2956
2957 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2958 RemappedFiles->size()))
2959 RTUI->result = 0;
2960}
2961
2962int clang_reparseTranslationUnit(CXTranslationUnit TU,
2963 unsigned num_unsaved_files,
2964 struct CXUnsavedFile *unsaved_files,
2965 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002966 LOG_FUNC_SECTION {
2967 *Log << TU;
2968 }
2969
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002970 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2971 options, 0 };
2972
2973 if (getenv("LIBCLANG_NOTHREADS")) {
2974 clang_reparseTranslationUnit_Impl(&RTUI);
2975 return RTUI.result;
2976 }
2977
2978 llvm::CrashRecoveryContext CRC;
2979
2980 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2981 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002982 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002983 return 1;
2984 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2985 PrintLibclangResourceUsage(TU);
2986
2987 return RTUI.result;
2988}
2989
2990
2991CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2992 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002993 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002994
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002995 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002996 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002997}
2998
2999CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003000 if (!TU)
3001 return clang_getNullCursor();
3002
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003003 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003004 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3005}
3006
3007} // end: extern "C"
3008
3009//===----------------------------------------------------------------------===//
3010// CXFile Operations.
3011//===----------------------------------------------------------------------===//
3012
3013extern "C" {
3014CXString clang_getFileName(CXFile SFile) {
3015 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00003016 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003017
3018 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003019 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003020}
3021
3022time_t clang_getFileTime(CXFile SFile) {
3023 if (!SFile)
3024 return 0;
3025
3026 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3027 return FEnt->getModificationTime();
3028}
3029
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003030CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3031 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003032 return 0;
3033
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003034 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003035
3036 FileManager &FMgr = CXXUnit->getFileManager();
3037 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3038}
3039
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003040unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3041 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003042 return 0;
3043
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003044 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003045 FileEntry *FEnt = static_cast<FileEntry *>(file);
3046 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3047 .isFileMultipleIncludeGuarded(FEnt);
3048}
3049
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003050int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3051 if (!file || !outID)
3052 return 1;
3053
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003054 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-08-01 21:42:11 +00003055 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3056 outID->data[0] = ID.getDevice();
3057 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003058 outID->data[2] = FEnt->getModificationTime();
3059 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003060}
3061
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003062} // end: extern "C"
3063
3064//===----------------------------------------------------------------------===//
3065// CXCursor Operations.
3066//===----------------------------------------------------------------------===//
3067
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003068static const Decl *getDeclFromExpr(const Stmt *E) {
3069 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003070 return getDeclFromExpr(CE->getSubExpr());
3071
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003072 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003073 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003074 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003075 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003076 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003077 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003078 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003079 if (PRE->isExplicitProperty())
3080 return PRE->getExplicitProperty();
3081 // It could be messaging both getter and setter as in:
3082 // ++myobj.myprop;
3083 // in which case prefer to associate the setter since it is less obvious
3084 // from inspecting the source that the setter is going to get called.
3085 if (PRE->isMessagingSetter())
3086 return PRE->getImplicitPropertySetter();
3087 return PRE->getImplicitPropertyGetter();
3088 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003089 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003090 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003091 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003092 if (Expr *Src = OVE->getSourceExpr())
3093 return getDeclFromExpr(Src);
3094
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003095 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003096 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003097 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003098 if (!CE->isElidable())
3099 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003100 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003101 return OME->getMethodDecl();
3102
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003103 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003104 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003105 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003106 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3107 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003108 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003109 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3110 isa<ParmVarDecl>(SizeOfPack->getPack()))
3111 return SizeOfPack->getPack();
3112
3113 return 0;
3114}
3115
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003116static SourceLocation getLocationFromExpr(const Expr *E) {
3117 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003118 return getLocationFromExpr(CE->getSubExpr());
3119
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003120 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003121 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003122 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003123 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003124 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003125 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003126 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003127 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003128 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003129 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003130 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003131 return PropRef->getLocation();
3132
3133 return E->getLocStart();
3134}
3135
3136extern "C" {
3137
3138unsigned clang_visitChildren(CXCursor parent,
3139 CXCursorVisitor visitor,
3140 CXClientData client_data) {
3141 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3142 /*VisitPreprocessorLast=*/false);
3143 return CursorVis.VisitChildren(parent);
3144}
3145
3146#ifndef __has_feature
3147#define __has_feature(x) 0
3148#endif
3149#if __has_feature(blocks)
3150typedef enum CXChildVisitResult
3151 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3152
3153static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3154 CXClientData client_data) {
3155 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3156 return block(cursor, parent);
3157}
3158#else
3159// If we are compiled with a compiler that doesn't have native blocks support,
3160// define and call the block manually, so the
3161typedef struct _CXChildVisitResult
3162{
3163 void *isa;
3164 int flags;
3165 int reserved;
3166 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3167 CXCursor);
3168} *CXCursorVisitorBlock;
3169
3170static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3171 CXClientData client_data) {
3172 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3173 return block->invoke(block, cursor, parent);
3174}
3175#endif
3176
3177
3178unsigned clang_visitChildrenWithBlock(CXCursor parent,
3179 CXCursorVisitorBlock block) {
3180 return clang_visitChildren(parent, visitWithBlock, block);
3181}
3182
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003183static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003184 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003185 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003186
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003187 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003188 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003189 if (const ObjCPropertyImplDecl *PropImpl =
3190 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003191 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003192 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003193
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003194 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003196 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003198 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 }
3200
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003201 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003202 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003204 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3206 // and returns different names. NamedDecl returns the class name and
3207 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003208 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209
3210 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003211 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003212
3213 SmallString<1024> S;
3214 llvm::raw_svector_ostream os(S);
3215 ND->printName(os);
3216
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003217 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003218}
3219
3220CXString clang_getCursorSpelling(CXCursor C) {
3221 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003222 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003223
3224 if (clang_isReference(C.kind)) {
3225 switch (C.kind) {
3226 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003227 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003228 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003229 }
3230 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003231 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003232 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003233 }
3234 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003235 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003236 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003237 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003238 }
3239 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003240 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003241 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 }
3243 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003244 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003245 assert(Type && "Missing type decl");
3246
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003247 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003248 getAsString());
3249 }
3250 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003251 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003252 assert(Template && "Missing template decl");
3253
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003254 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003255 }
3256
3257 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003258 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003259 assert(NS && "Missing namespace decl");
3260
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003261 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003262 }
3263
3264 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003265 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003266 assert(Field && "Missing member decl");
3267
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003268 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003269 }
3270
3271 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003272 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003273 assert(Label && "Missing label");
3274
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003275 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003276 }
3277
3278 case CXCursor_OverloadedDeclRef: {
3279 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003280 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3281 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003282 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003283 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003284 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003285 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003286 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003287 OverloadedTemplateStorage *Ovl
3288 = Storage.get<OverloadedTemplateStorage*>();
3289 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003290 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003291 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003292 }
3293
3294 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003295 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003296 assert(Var && "Missing variable decl");
3297
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003298 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003299 }
3300
3301 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003302 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003303 }
3304 }
3305
3306 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003307 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003308 if (D)
3309 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003310 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003311 }
3312
3313 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003314 const Stmt *S = getCursorStmt(C);
3315 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003316 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003317
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003318 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003319 }
3320
3321 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003322 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003323 ->getNameStart());
3324
3325 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003326 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003327 ->getNameStart());
3328
3329 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003330 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003331
3332 if (clang_isDeclaration(C.kind))
3333 return getDeclSpelling(getCursorDecl(C));
3334
3335 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003336 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003337 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003338 }
3339
3340 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003341 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003342 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003343 }
3344
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003345 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003346}
3347
3348CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3349 unsigned pieceIndex,
3350 unsigned options) {
3351 if (clang_Cursor_isNull(C))
3352 return clang_getNullRange();
3353
3354 ASTContext &Ctx = getCursorContext(C);
3355
3356 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003357 const Stmt *S = getCursorStmt(C);
3358 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003359 if (pieceIndex > 0)
3360 return clang_getNullRange();
3361 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3362 }
3363
3364 return clang_getNullRange();
3365 }
3366
3367 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003368 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003369 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3370 if (pieceIndex >= ME->getNumSelectorLocs())
3371 return clang_getNullRange();
3372 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3373 }
3374 }
3375
3376 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3377 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003378 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003379 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3380 if (pieceIndex >= MD->getNumSelectorLocs())
3381 return clang_getNullRange();
3382 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3383 }
3384 }
3385
3386 if (C.kind == CXCursor_ObjCCategoryDecl ||
3387 C.kind == CXCursor_ObjCCategoryImplDecl) {
3388 if (pieceIndex > 0)
3389 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003390 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003391 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3392 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003393 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003394 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3395 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3396 }
3397
3398 if (C.kind == CXCursor_ModuleImportDecl) {
3399 if (pieceIndex > 0)
3400 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003401 if (const ImportDecl *ImportD =
3402 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003403 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3404 if (!Locs.empty())
3405 return cxloc::translateSourceRange(Ctx,
3406 SourceRange(Locs.front(), Locs.back()));
3407 }
3408 return clang_getNullRange();
3409 }
3410
3411 // FIXME: A CXCursor_InclusionDirective should give the location of the
3412 // filename, but we don't keep track of this.
3413
3414 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3415 // but we don't keep track of this.
3416
3417 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3418 // but we don't keep track of this.
3419
3420 // Default handling, give the location of the cursor.
3421
3422 if (pieceIndex > 0)
3423 return clang_getNullRange();
3424
3425 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3426 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3427 return cxloc::translateSourceRange(Ctx, Loc);
3428}
3429
3430CXString clang_getCursorDisplayName(CXCursor C) {
3431 if (!clang_isDeclaration(C.kind))
3432 return clang_getCursorSpelling(C);
3433
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003434 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003435 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003436 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003437
3438 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003439 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003440 D = FunTmpl->getTemplatedDecl();
3441
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003442 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003443 SmallString<64> Str;
3444 llvm::raw_svector_ostream OS(Str);
3445 OS << *Function;
3446 if (Function->getPrimaryTemplate())
3447 OS << "<>";
3448 OS << "(";
3449 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3450 if (I)
3451 OS << ", ";
3452 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3453 }
3454
3455 if (Function->isVariadic()) {
3456 if (Function->getNumParams())
3457 OS << ", ";
3458 OS << "...";
3459 }
3460 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003461 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003462 }
3463
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003464 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003465 SmallString<64> Str;
3466 llvm::raw_svector_ostream OS(Str);
3467 OS << *ClassTemplate;
3468 OS << "<";
3469 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3470 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3471 if (I)
3472 OS << ", ";
3473
3474 NamedDecl *Param = Params->getParam(I);
3475 if (Param->getIdentifier()) {
3476 OS << Param->getIdentifier()->getName();
3477 continue;
3478 }
3479
3480 // There is no parameter name, which makes this tricky. Try to come up
3481 // with something useful that isn't too long.
3482 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3483 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3484 else if (NonTypeTemplateParmDecl *NTTP
3485 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3486 OS << NTTP->getType().getAsString(Policy);
3487 else
3488 OS << "template<...> class";
3489 }
3490
3491 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003492 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 }
3494
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003495 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003496 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3497 // If the type was explicitly written, use that.
3498 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003499 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003500
Benjamin Kramer5eada842013-02-22 15:46:01 +00003501 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003502 llvm::raw_svector_ostream OS(Str);
3503 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003504 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 ClassSpec->getTemplateArgs().data(),
3506 ClassSpec->getTemplateArgs().size(),
3507 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003508 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 }
3510
3511 return clang_getCursorSpelling(C);
3512}
3513
3514CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3515 switch (Kind) {
3516 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003517 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003518 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003519 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003520 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003521 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003522 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003523 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003524 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003525 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003526 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003644 case CXCursor_ObjCSelfExpr:
3645 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003739 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003740 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003741 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003742 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003743 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003744 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003745 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003746 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003747 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003748 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003749 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003750 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003751 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003752 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003753 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003754 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003755 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003756 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003757 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003758 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003759 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003760 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003761 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003762 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003763 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003764 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003765 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003766 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003767 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003768 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003769 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003770 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003771 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003772 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003773 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003774 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003775 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003776 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003777 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003778 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003779 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003780 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003781 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003782 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003783 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003784 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003785 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003786 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003787 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003788 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003789 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003790 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003791 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003792 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003793 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003794 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003795 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003797 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003798 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003799 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003801 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003802 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003803 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003804 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003806 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003807 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003808 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003809 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003810 case CXCursor_OMPParallelDirective:
3811 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003812 }
3813
3814 llvm_unreachable("Unhandled CXCursorKind");
3815}
3816
3817struct GetCursorData {
3818 SourceLocation TokenBeginLoc;
3819 bool PointsAtMacroArgExpansion;
3820 bool VisitedObjCPropertyImplDecl;
3821 SourceLocation VisitedDeclaratorDeclStartLoc;
3822 CXCursor &BestCursor;
3823
3824 GetCursorData(SourceManager &SM,
3825 SourceLocation tokenBegin, CXCursor &outputCursor)
3826 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3827 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3828 VisitedObjCPropertyImplDecl = false;
3829 }
3830};
3831
3832static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3833 CXCursor parent,
3834 CXClientData client_data) {
3835 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3836 CXCursor *BestCursor = &Data->BestCursor;
3837
3838 // If we point inside a macro argument we should provide info of what the
3839 // token is so use the actual cursor, don't replace it with a macro expansion
3840 // cursor.
3841 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3842 return CXChildVisit_Recurse;
3843
3844 if (clang_isDeclaration(cursor.kind)) {
3845 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003846 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003847 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3848 if (MD->isImplicit())
3849 return CXChildVisit_Break;
3850
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003851 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003852 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3853 // Check that when we have multiple @class references in the same line,
3854 // that later ones do not override the previous ones.
3855 // If we have:
3856 // @class Foo, Bar;
3857 // source ranges for both start at '@', so 'Bar' will end up overriding
3858 // 'Foo' even though the cursor location was at 'Foo'.
3859 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3860 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003861 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003862 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3863 if (PrevID != ID &&
3864 !PrevID->isThisDeclarationADefinition() &&
3865 !ID->isThisDeclarationADefinition())
3866 return CXChildVisit_Break;
3867 }
3868
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003869 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003870 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3871 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3872 // Check that when we have multiple declarators in the same line,
3873 // that later ones do not override the previous ones.
3874 // If we have:
3875 // int Foo, Bar;
3876 // source ranges for both start at 'int', so 'Bar' will end up overriding
3877 // 'Foo' even though the cursor location was at 'Foo'.
3878 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3879 return CXChildVisit_Break;
3880 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3881
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003882 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003883 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3884 (void)PropImp;
3885 // Check that when we have multiple @synthesize in the same line,
3886 // that later ones do not override the previous ones.
3887 // If we have:
3888 // @synthesize Foo, Bar;
3889 // source ranges for both start at '@', so 'Bar' will end up overriding
3890 // 'Foo' even though the cursor location was at 'Foo'.
3891 if (Data->VisitedObjCPropertyImplDecl)
3892 return CXChildVisit_Break;
3893 Data->VisitedObjCPropertyImplDecl = true;
3894 }
3895 }
3896
3897 if (clang_isExpression(cursor.kind) &&
3898 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003899 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003900 // Avoid having the cursor of an expression replace the declaration cursor
3901 // when the expression source range overlaps the declaration range.
3902 // This can happen for C++ constructor expressions whose range generally
3903 // include the variable declaration, e.g.:
3904 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3905 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3906 D->getLocation() == Data->TokenBeginLoc)
3907 return CXChildVisit_Break;
3908 }
3909 }
3910
3911 // If our current best cursor is the construction of a temporary object,
3912 // don't replace that cursor with a type reference, because we want
3913 // clang_getCursor() to point at the constructor.
3914 if (clang_isExpression(BestCursor->kind) &&
3915 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3916 cursor.kind == CXCursor_TypeRef) {
3917 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3918 // as having the actual point on the type reference.
3919 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3920 return CXChildVisit_Recurse;
3921 }
3922
3923 *BestCursor = cursor;
3924 return CXChildVisit_Recurse;
3925}
3926
3927CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3928 if (!TU)
3929 return clang_getNullCursor();
3930
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003931 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003932 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3933
3934 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3935 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3936
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003937 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003938 CXFile SearchFile;
3939 unsigned SearchLine, SearchColumn;
3940 CXFile ResultFile;
3941 unsigned ResultLine, ResultColumn;
3942 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3943 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3944 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3945
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003946 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3947 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003948 &ResultColumn, 0);
3949 SearchFileName = clang_getFileName(SearchFile);
3950 ResultFileName = clang_getFileName(ResultFile);
3951 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3952 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003953 *Log << llvm::format("(%s:%d:%d) = %s",
3954 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3955 clang_getCString(KindSpelling))
3956 << llvm::format("(%s:%d:%d):%s%s",
3957 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3958 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003959 clang_disposeString(SearchFileName);
3960 clang_disposeString(ResultFileName);
3961 clang_disposeString(KindSpelling);
3962 clang_disposeString(USR);
3963
3964 CXCursor Definition = clang_getCursorDefinition(Result);
3965 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3966 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3967 CXString DefinitionKindSpelling
3968 = clang_getCursorKindSpelling(Definition.kind);
3969 CXFile DefinitionFile;
3970 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003971 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003972 &DefinitionLine, &DefinitionColumn, 0);
3973 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003974 *Log << llvm::format(" -> %s(%s:%d:%d)",
3975 clang_getCString(DefinitionKindSpelling),
3976 clang_getCString(DefinitionFileName),
3977 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003978 clang_disposeString(DefinitionFileName);
3979 clang_disposeString(DefinitionKindSpelling);
3980 }
3981 }
3982
3983 return Result;
3984}
3985
3986CXCursor clang_getNullCursor(void) {
3987 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3988}
3989
3990unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003991 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3992 // can't set consistently. For example, when visiting a DeclStmt we will set
3993 // it but we don't set it on the result of clang_getCursorDefinition for
3994 // a reference of the same declaration.
3995 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3996 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3997 // to provide that kind of info.
3998 if (clang_isDeclaration(X.kind))
3999 X.data[1] = 0;
4000 if (clang_isDeclaration(Y.kind))
4001 Y.data[1] = 0;
4002
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004003 return X == Y;
4004}
4005
4006unsigned clang_hashCursor(CXCursor C) {
4007 unsigned Index = 0;
4008 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4009 Index = 1;
4010
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004011 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004012 std::make_pair(C.kind, C.data[Index]));
4013}
4014
4015unsigned clang_isInvalid(enum CXCursorKind K) {
4016 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4017}
4018
4019unsigned clang_isDeclaration(enum CXCursorKind K) {
4020 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4021 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4022}
4023
4024unsigned clang_isReference(enum CXCursorKind K) {
4025 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4026}
4027
4028unsigned clang_isExpression(enum CXCursorKind K) {
4029 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4030}
4031
4032unsigned clang_isStatement(enum CXCursorKind K) {
4033 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4034}
4035
4036unsigned clang_isAttribute(enum CXCursorKind K) {
4037 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4038}
4039
4040unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4041 return K == CXCursor_TranslationUnit;
4042}
4043
4044unsigned clang_isPreprocessing(enum CXCursorKind K) {
4045 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4046}
4047
4048unsigned clang_isUnexposed(enum CXCursorKind K) {
4049 switch (K) {
4050 case CXCursor_UnexposedDecl:
4051 case CXCursor_UnexposedExpr:
4052 case CXCursor_UnexposedStmt:
4053 case CXCursor_UnexposedAttr:
4054 return true;
4055 default:
4056 return false;
4057 }
4058}
4059
4060CXCursorKind clang_getCursorKind(CXCursor C) {
4061 return C.kind;
4062}
4063
4064CXSourceLocation clang_getCursorLocation(CXCursor C) {
4065 if (clang_isReference(C.kind)) {
4066 switch (C.kind) {
4067 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004068 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004069 = getCursorObjCSuperClassRef(C);
4070 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4071 }
4072
4073 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004074 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004075 = getCursorObjCProtocolRef(C);
4076 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4077 }
4078
4079 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004080 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004081 = getCursorObjCClassRef(C);
4082 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4083 }
4084
4085 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004086 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004087 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4088 }
4089
4090 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004091 std::pair<const TemplateDecl *, SourceLocation> P =
4092 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004093 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4094 }
4095
4096 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004097 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004102 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004103 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4104 }
4105
4106 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004107 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004108 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4109 }
4110
4111 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004112 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004113 if (!BaseSpec)
4114 return clang_getNullLocation();
4115
4116 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4117 return cxloc::translateSourceLocation(getCursorContext(C),
4118 TSInfo->getTypeLoc().getBeginLoc());
4119
4120 return cxloc::translateSourceLocation(getCursorContext(C),
4121 BaseSpec->getLocStart());
4122 }
4123
4124 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004125 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004126 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4127 }
4128
4129 case CXCursor_OverloadedDeclRef:
4130 return cxloc::translateSourceLocation(getCursorContext(C),
4131 getCursorOverloadedDeclRef(C).second);
4132
4133 default:
4134 // FIXME: Need a way to enumerate all non-reference cases.
4135 llvm_unreachable("Missed a reference kind");
4136 }
4137 }
4138
4139 if (clang_isExpression(C.kind))
4140 return cxloc::translateSourceLocation(getCursorContext(C),
4141 getLocationFromExpr(getCursorExpr(C)));
4142
4143 if (clang_isStatement(C.kind))
4144 return cxloc::translateSourceLocation(getCursorContext(C),
4145 getCursorStmt(C)->getLocStart());
4146
4147 if (C.kind == CXCursor_PreprocessingDirective) {
4148 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4149 return cxloc::translateSourceLocation(getCursorContext(C), L);
4150 }
4151
4152 if (C.kind == CXCursor_MacroExpansion) {
4153 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004154 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004155 return cxloc::translateSourceLocation(getCursorContext(C), L);
4156 }
4157
4158 if (C.kind == CXCursor_MacroDefinition) {
4159 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4160 return cxloc::translateSourceLocation(getCursorContext(C), L);
4161 }
4162
4163 if (C.kind == CXCursor_InclusionDirective) {
4164 SourceLocation L
4165 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4166 return cxloc::translateSourceLocation(getCursorContext(C), L);
4167 }
4168
4169 if (!clang_isDeclaration(C.kind))
4170 return clang_getNullLocation();
4171
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004172 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004173 if (!D)
4174 return clang_getNullLocation();
4175
4176 SourceLocation Loc = D->getLocation();
4177 // FIXME: Multiple variables declared in a single declaration
4178 // currently lack the information needed to correctly determine their
4179 // ranges when accounting for the type-specifier. We use context
4180 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4181 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004182 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004183 if (!cxcursor::isFirstInDeclGroup(C))
4184 Loc = VD->getLocation();
4185 }
4186
4187 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004188 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004189 Loc = MD->getSelectorStartLoc();
4190
4191 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4192}
4193
4194} // end extern "C"
4195
4196CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4197 assert(TU);
4198
4199 // Guard against an invalid SourceLocation, or we may assert in one
4200 // of the following calls.
4201 if (SLoc.isInvalid())
4202 return clang_getNullCursor();
4203
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004204 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004205
4206 // Translate the given source location to make it point at the beginning of
4207 // the token under the cursor.
4208 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4209 CXXUnit->getASTContext().getLangOpts());
4210
4211 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4212 if (SLoc.isValid()) {
4213 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4214 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4215 /*VisitPreprocessorLast=*/true,
4216 /*VisitIncludedEntities=*/false,
4217 SourceLocation(SLoc));
4218 CursorVis.visitFileRegion();
4219 }
4220
4221 return Result;
4222}
4223
4224static SourceRange getRawCursorExtent(CXCursor C) {
4225 if (clang_isReference(C.kind)) {
4226 switch (C.kind) {
4227 case CXCursor_ObjCSuperClassRef:
4228 return getCursorObjCSuperClassRef(C).second;
4229
4230 case CXCursor_ObjCProtocolRef:
4231 return getCursorObjCProtocolRef(C).second;
4232
4233 case CXCursor_ObjCClassRef:
4234 return getCursorObjCClassRef(C).second;
4235
4236 case CXCursor_TypeRef:
4237 return getCursorTypeRef(C).second;
4238
4239 case CXCursor_TemplateRef:
4240 return getCursorTemplateRef(C).second;
4241
4242 case CXCursor_NamespaceRef:
4243 return getCursorNamespaceRef(C).second;
4244
4245 case CXCursor_MemberRef:
4246 return getCursorMemberRef(C).second;
4247
4248 case CXCursor_CXXBaseSpecifier:
4249 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4250
4251 case CXCursor_LabelRef:
4252 return getCursorLabelRef(C).second;
4253
4254 case CXCursor_OverloadedDeclRef:
4255 return getCursorOverloadedDeclRef(C).second;
4256
4257 case CXCursor_VariableRef:
4258 return getCursorVariableRef(C).second;
4259
4260 default:
4261 // FIXME: Need a way to enumerate all non-reference cases.
4262 llvm_unreachable("Missed a reference kind");
4263 }
4264 }
4265
4266 if (clang_isExpression(C.kind))
4267 return getCursorExpr(C)->getSourceRange();
4268
4269 if (clang_isStatement(C.kind))
4270 return getCursorStmt(C)->getSourceRange();
4271
4272 if (clang_isAttribute(C.kind))
4273 return getCursorAttr(C)->getRange();
4274
4275 if (C.kind == CXCursor_PreprocessingDirective)
4276 return cxcursor::getCursorPreprocessingDirective(C);
4277
4278 if (C.kind == CXCursor_MacroExpansion) {
4279 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004280 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004281 return TU->mapRangeFromPreamble(Range);
4282 }
4283
4284 if (C.kind == CXCursor_MacroDefinition) {
4285 ASTUnit *TU = getCursorASTUnit(C);
4286 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4287 return TU->mapRangeFromPreamble(Range);
4288 }
4289
4290 if (C.kind == CXCursor_InclusionDirective) {
4291 ASTUnit *TU = getCursorASTUnit(C);
4292 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4293 return TU->mapRangeFromPreamble(Range);
4294 }
4295
4296 if (C.kind == CXCursor_TranslationUnit) {
4297 ASTUnit *TU = getCursorASTUnit(C);
4298 FileID MainID = TU->getSourceManager().getMainFileID();
4299 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4300 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4301 return SourceRange(Start, End);
4302 }
4303
4304 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004305 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004306 if (!D)
4307 return SourceRange();
4308
4309 SourceRange R = D->getSourceRange();
4310 // FIXME: Multiple variables declared in a single declaration
4311 // currently lack the information needed to correctly determine their
4312 // ranges when accounting for the type-specifier. We use context
4313 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4314 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004315 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004316 if (!cxcursor::isFirstInDeclGroup(C))
4317 R.setBegin(VD->getLocation());
4318 }
4319 return R;
4320 }
4321 return SourceRange();
4322}
4323
4324/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4325/// the decl-specifier-seq for declarations.
4326static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4327 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004328 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004329 if (!D)
4330 return SourceRange();
4331
4332 SourceRange R = D->getSourceRange();
4333
4334 // Adjust the start of the location for declarations preceded by
4335 // declaration specifiers.
4336 SourceLocation StartLoc;
4337 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4338 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4339 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004340 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004341 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4342 StartLoc = TI->getTypeLoc().getLocStart();
4343 }
4344
4345 if (StartLoc.isValid() && R.getBegin().isValid() &&
4346 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4347 R.setBegin(StartLoc);
4348
4349 // FIXME: Multiple variables declared in a single declaration
4350 // currently lack the information needed to correctly determine their
4351 // ranges when accounting for the type-specifier. We use context
4352 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4353 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004354 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004355 if (!cxcursor::isFirstInDeclGroup(C))
4356 R.setBegin(VD->getLocation());
4357 }
4358
4359 return R;
4360 }
4361
4362 return getRawCursorExtent(C);
4363}
4364
4365extern "C" {
4366
4367CXSourceRange clang_getCursorExtent(CXCursor C) {
4368 SourceRange R = getRawCursorExtent(C);
4369 if (R.isInvalid())
4370 return clang_getNullRange();
4371
4372 return cxloc::translateSourceRange(getCursorContext(C), R);
4373}
4374
4375CXCursor clang_getCursorReferenced(CXCursor C) {
4376 if (clang_isInvalid(C.kind))
4377 return clang_getNullCursor();
4378
4379 CXTranslationUnit tu = getCursorTU(C);
4380 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004381 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004382 if (!D)
4383 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004384 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004385 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004386 if (const ObjCPropertyImplDecl *PropImpl =
4387 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004388 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4389 return MakeCXCursor(Property, tu);
4390
4391 return C;
4392 }
4393
4394 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004395 const Expr *E = getCursorExpr(C);
4396 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004397 if (D) {
4398 CXCursor declCursor = MakeCXCursor(D, tu);
4399 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4400 declCursor);
4401 return declCursor;
4402 }
4403
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004404 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004405 return MakeCursorOverloadedDeclRef(Ovl, tu);
4406
4407 return clang_getNullCursor();
4408 }
4409
4410 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004411 const Stmt *S = getCursorStmt(C);
4412 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004413 if (LabelDecl *label = Goto->getLabel())
4414 if (LabelStmt *labelS = label->getStmt())
4415 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4416
4417 return clang_getNullCursor();
4418 }
4419
4420 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004421 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004422 return MakeMacroDefinitionCursor(Def, tu);
4423 }
4424
4425 if (!clang_isReference(C.kind))
4426 return clang_getNullCursor();
4427
4428 switch (C.kind) {
4429 case CXCursor_ObjCSuperClassRef:
4430 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4431
4432 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004433 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4434 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004435 return MakeCXCursor(Def, tu);
4436
4437 return MakeCXCursor(Prot, tu);
4438 }
4439
4440 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004441 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4442 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004443 return MakeCXCursor(Def, tu);
4444
4445 return MakeCXCursor(Class, tu);
4446 }
4447
4448 case CXCursor_TypeRef:
4449 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4450
4451 case CXCursor_TemplateRef:
4452 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4453
4454 case CXCursor_NamespaceRef:
4455 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4456
4457 case CXCursor_MemberRef:
4458 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4459
4460 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004461 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004462 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4463 tu ));
4464 }
4465
4466 case CXCursor_LabelRef:
4467 // FIXME: We end up faking the "parent" declaration here because we
4468 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004469 return MakeCXCursor(getCursorLabelRef(C).first,
4470 cxtu::getASTUnit(tu)->getASTContext()
4471 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004472 tu);
4473
4474 case CXCursor_OverloadedDeclRef:
4475 return C;
4476
4477 case CXCursor_VariableRef:
4478 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4479
4480 default:
4481 // We would prefer to enumerate all non-reference cursor kinds here.
4482 llvm_unreachable("Unhandled reference cursor kind");
4483 }
4484}
4485
4486CXCursor clang_getCursorDefinition(CXCursor C) {
4487 if (clang_isInvalid(C.kind))
4488 return clang_getNullCursor();
4489
4490 CXTranslationUnit TU = getCursorTU(C);
4491
4492 bool WasReference = false;
4493 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4494 C = clang_getCursorReferenced(C);
4495 WasReference = true;
4496 }
4497
4498 if (C.kind == CXCursor_MacroExpansion)
4499 return clang_getCursorReferenced(C);
4500
4501 if (!clang_isDeclaration(C.kind))
4502 return clang_getNullCursor();
4503
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004504 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004505 if (!D)
4506 return clang_getNullCursor();
4507
4508 switch (D->getKind()) {
4509 // Declaration kinds that don't really separate the notions of
4510 // declaration and definition.
4511 case Decl::Namespace:
4512 case Decl::Typedef:
4513 case Decl::TypeAlias:
4514 case Decl::TypeAliasTemplate:
4515 case Decl::TemplateTypeParm:
4516 case Decl::EnumConstant:
4517 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004518 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004519 case Decl::IndirectField:
4520 case Decl::ObjCIvar:
4521 case Decl::ObjCAtDefsField:
4522 case Decl::ImplicitParam:
4523 case Decl::ParmVar:
4524 case Decl::NonTypeTemplateParm:
4525 case Decl::TemplateTemplateParm:
4526 case Decl::ObjCCategoryImpl:
4527 case Decl::ObjCImplementation:
4528 case Decl::AccessSpec:
4529 case Decl::LinkageSpec:
4530 case Decl::ObjCPropertyImpl:
4531 case Decl::FileScopeAsm:
4532 case Decl::StaticAssert:
4533 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004534 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004535 case Decl::Label: // FIXME: Is this right??
4536 case Decl::ClassScopeFunctionSpecialization:
4537 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004538 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004539 return C;
4540
4541 // Declaration kinds that don't make any sense here, but are
4542 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004543 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004544 case Decl::TranslationUnit:
4545 break;
4546
4547 // Declaration kinds for which the definition is not resolvable.
4548 case Decl::UnresolvedUsingTypename:
4549 case Decl::UnresolvedUsingValue:
4550 break;
4551
4552 case Decl::UsingDirective:
4553 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4554 TU);
4555
4556 case Decl::NamespaceAlias:
4557 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4558
4559 case Decl::Enum:
4560 case Decl::Record:
4561 case Decl::CXXRecord:
4562 case Decl::ClassTemplateSpecialization:
4563 case Decl::ClassTemplatePartialSpecialization:
4564 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4565 return MakeCXCursor(Def, TU);
4566 return clang_getNullCursor();
4567
4568 case Decl::Function:
4569 case Decl::CXXMethod:
4570 case Decl::CXXConstructor:
4571 case Decl::CXXDestructor:
4572 case Decl::CXXConversion: {
4573 const FunctionDecl *Def = 0;
4574 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004575 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004576 return clang_getNullCursor();
4577 }
4578
Larisse Voufoef4579c2013-08-06 01:03:05 +00004579 case Decl::Var:
4580 case Decl::VarTemplateSpecialization:
4581 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004582 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004583 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004584 return MakeCXCursor(Def, TU);
4585 return clang_getNullCursor();
4586 }
4587
4588 case Decl::FunctionTemplate: {
4589 const FunctionDecl *Def = 0;
4590 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4591 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4592 return clang_getNullCursor();
4593 }
4594
4595 case Decl::ClassTemplate: {
4596 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4597 ->getDefinition())
4598 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4599 TU);
4600 return clang_getNullCursor();
4601 }
4602
Larisse Voufoef4579c2013-08-06 01:03:05 +00004603 case Decl::VarTemplate: {
4604 if (VarDecl *Def =
4605 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4606 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4607 return clang_getNullCursor();
4608 }
4609
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004610 case Decl::Using:
4611 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4612 D->getLocation(), TU);
4613
4614 case Decl::UsingShadow:
4615 return clang_getCursorDefinition(
4616 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4617 TU));
4618
4619 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004620 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004621 if (Method->isThisDeclarationADefinition())
4622 return C;
4623
4624 // Dig out the method definition in the associated
4625 // @implementation, if we have it.
4626 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004627 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004628 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4629 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4630 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4631 Method->isInstanceMethod()))
4632 if (Def->isThisDeclarationADefinition())
4633 return MakeCXCursor(Def, TU);
4634
4635 return clang_getNullCursor();
4636 }
4637
4638 case Decl::ObjCCategory:
4639 if (ObjCCategoryImplDecl *Impl
4640 = cast<ObjCCategoryDecl>(D)->getImplementation())
4641 return MakeCXCursor(Impl, TU);
4642 return clang_getNullCursor();
4643
4644 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004645 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004646 return MakeCXCursor(Def, TU);
4647 return clang_getNullCursor();
4648
4649 case Decl::ObjCInterface: {
4650 // There are two notions of a "definition" for an Objective-C
4651 // class: the interface and its implementation. When we resolved a
4652 // reference to an Objective-C class, produce the @interface as
4653 // the definition; when we were provided with the interface,
4654 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004655 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004656 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004657 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004658 return MakeCXCursor(Def, TU);
4659 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4660 return MakeCXCursor(Impl, TU);
4661 return clang_getNullCursor();
4662 }
4663
4664 case Decl::ObjCProperty:
4665 // FIXME: We don't really know where to find the
4666 // ObjCPropertyImplDecls that implement this property.
4667 return clang_getNullCursor();
4668
4669 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004670 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004671 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004672 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004673 return MakeCXCursor(Def, TU);
4674
4675 return clang_getNullCursor();
4676
4677 case Decl::Friend:
4678 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4679 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4680 return clang_getNullCursor();
4681
4682 case Decl::FriendTemplate:
4683 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4684 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4685 return clang_getNullCursor();
4686 }
4687
4688 return clang_getNullCursor();
4689}
4690
4691unsigned clang_isCursorDefinition(CXCursor C) {
4692 if (!clang_isDeclaration(C.kind))
4693 return 0;
4694
4695 return clang_getCursorDefinition(C) == C;
4696}
4697
4698CXCursor clang_getCanonicalCursor(CXCursor C) {
4699 if (!clang_isDeclaration(C.kind))
4700 return C;
4701
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004702 if (const Decl *D = getCursorDecl(C)) {
4703 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004704 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4705 return MakeCXCursor(CatD, getCursorTU(C));
4706
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004707 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4708 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004709 return MakeCXCursor(IFD, getCursorTU(C));
4710
4711 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4712 }
4713
4714 return C;
4715}
4716
4717int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4718 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4719}
4720
4721unsigned clang_getNumOverloadedDecls(CXCursor C) {
4722 if (C.kind != CXCursor_OverloadedDeclRef)
4723 return 0;
4724
4725 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004726 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004727 return E->getNumDecls();
4728
4729 if (OverloadedTemplateStorage *S
4730 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4731 return S->size();
4732
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004733 const Decl *D = Storage.get<const Decl *>();
4734 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004735 return Using->shadow_size();
4736
4737 return 0;
4738}
4739
4740CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4741 if (cursor.kind != CXCursor_OverloadedDeclRef)
4742 return clang_getNullCursor();
4743
4744 if (index >= clang_getNumOverloadedDecls(cursor))
4745 return clang_getNullCursor();
4746
4747 CXTranslationUnit TU = getCursorTU(cursor);
4748 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004749 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004750 return MakeCXCursor(E->decls_begin()[index], TU);
4751
4752 if (OverloadedTemplateStorage *S
4753 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4754 return MakeCXCursor(S->begin()[index], TU);
4755
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004756 const Decl *D = Storage.get<const Decl *>();
4757 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004758 // FIXME: This is, unfortunately, linear time.
4759 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4760 std::advance(Pos, index);
4761 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4762 }
4763
4764 return clang_getNullCursor();
4765}
4766
4767void clang_getDefinitionSpellingAndExtent(CXCursor C,
4768 const char **startBuf,
4769 const char **endBuf,
4770 unsigned *startLine,
4771 unsigned *startColumn,
4772 unsigned *endLine,
4773 unsigned *endColumn) {
4774 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004775 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004776 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4777
4778 SourceManager &SM = FD->getASTContext().getSourceManager();
4779 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4780 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4781 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4782 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4783 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4784 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4785}
4786
4787
4788CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4789 unsigned PieceIndex) {
4790 RefNamePieces Pieces;
4791
4792 switch (C.kind) {
4793 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004794 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004795 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4796 E->getQualifierLoc().getSourceRange());
4797 break;
4798
4799 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004800 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004801 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4802 E->getQualifierLoc().getSourceRange(),
4803 E->getOptionalExplicitTemplateArgs());
4804 break;
4805
4806 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004807 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004808 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004809 const Expr *Callee = OCE->getCallee();
4810 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004811 Callee = ICE->getSubExpr();
4812
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004813 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004814 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4815 DRE->getQualifierLoc().getSourceRange());
4816 }
4817 break;
4818
4819 default:
4820 break;
4821 }
4822
4823 if (Pieces.empty()) {
4824 if (PieceIndex == 0)
4825 return clang_getCursorExtent(C);
4826 } else if (PieceIndex < Pieces.size()) {
4827 SourceRange R = Pieces[PieceIndex];
4828 if (R.isValid())
4829 return cxloc::translateSourceRange(getCursorContext(C), R);
4830 }
4831
4832 return clang_getNullRange();
4833}
4834
4835void clang_enableStackTraces(void) {
4836 llvm::sys::PrintStackTraceOnErrorSignal();
4837}
4838
4839void clang_executeOnThread(void (*fn)(void*), void *user_data,
4840 unsigned stack_size) {
4841 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4842}
4843
4844} // end: extern "C"
4845
4846//===----------------------------------------------------------------------===//
4847// Token-based Operations.
4848//===----------------------------------------------------------------------===//
4849
4850/* CXToken layout:
4851 * int_data[0]: a CXTokenKind
4852 * int_data[1]: starting token location
4853 * int_data[2]: token length
4854 * int_data[3]: reserved
4855 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4856 * otherwise unused.
4857 */
4858extern "C" {
4859
4860CXTokenKind clang_getTokenKind(CXToken CXTok) {
4861 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4862}
4863
4864CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4865 switch (clang_getTokenKind(CXTok)) {
4866 case CXToken_Identifier:
4867 case CXToken_Keyword:
4868 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004869 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004870 ->getNameStart());
4871
4872 case CXToken_Literal: {
4873 // We have stashed the starting pointer in the ptr_data field. Use it.
4874 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004875 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004876 }
4877
4878 case CXToken_Punctuation:
4879 case CXToken_Comment:
4880 break;
4881 }
4882
4883 // We have to find the starting buffer pointer the hard way, by
4884 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004885 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004886 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004887 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004888
4889 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4890 std::pair<FileID, unsigned> LocInfo
4891 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4892 bool Invalid = false;
4893 StringRef Buffer
4894 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4895 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004896 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004897
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004898 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004899}
4900
4901CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004902 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004903 if (!CXXUnit)
4904 return clang_getNullLocation();
4905
4906 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4907 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4908}
4909
4910CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004911 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004912 if (!CXXUnit)
4913 return clang_getNullRange();
4914
4915 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4916 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4917}
4918
4919static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4920 SmallVectorImpl<CXToken> &CXTokens) {
4921 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4922 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004923 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004924 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004925 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004926
4927 // Cannot tokenize across files.
4928 if (BeginLocInfo.first != EndLocInfo.first)
4929 return;
4930
4931 // Create a lexer
4932 bool Invalid = false;
4933 StringRef Buffer
4934 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4935 if (Invalid)
4936 return;
4937
4938 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4939 CXXUnit->getASTContext().getLangOpts(),
4940 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4941 Lex.SetCommentRetentionState(true);
4942
4943 // Lex tokens until we hit the end of the range.
4944 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4945 Token Tok;
4946 bool previousWasAt = false;
4947 do {
4948 // Lex the next token
4949 Lex.LexFromRawLexer(Tok);
4950 if (Tok.is(tok::eof))
4951 break;
4952
4953 // Initialize the CXToken.
4954 CXToken CXTok;
4955
4956 // - Common fields
4957 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4958 CXTok.int_data[2] = Tok.getLength();
4959 CXTok.int_data[3] = 0;
4960
4961 // - Kind-specific fields
4962 if (Tok.isLiteral()) {
4963 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004964 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004965 } else if (Tok.is(tok::raw_identifier)) {
4966 // Lookup the identifier to determine whether we have a keyword.
4967 IdentifierInfo *II
4968 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4969
4970 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4971 CXTok.int_data[0] = CXToken_Keyword;
4972 }
4973 else {
4974 CXTok.int_data[0] = Tok.is(tok::identifier)
4975 ? CXToken_Identifier
4976 : CXToken_Keyword;
4977 }
4978 CXTok.ptr_data = II;
4979 } else if (Tok.is(tok::comment)) {
4980 CXTok.int_data[0] = CXToken_Comment;
4981 CXTok.ptr_data = 0;
4982 } else {
4983 CXTok.int_data[0] = CXToken_Punctuation;
4984 CXTok.ptr_data = 0;
4985 }
4986 CXTokens.push_back(CXTok);
4987 previousWasAt = Tok.is(tok::at);
4988 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4989}
4990
4991void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4992 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004993 LOG_FUNC_SECTION {
4994 *Log << TU << ' ' << Range;
4995 }
4996
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004997 if (Tokens)
4998 *Tokens = 0;
4999 if (NumTokens)
5000 *NumTokens = 0;
5001
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005002 if (!TU)
5003 return;
5004
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005005 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005006 if (!CXXUnit || !Tokens || !NumTokens)
5007 return;
5008
5009 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5010
5011 SourceRange R = cxloc::translateCXSourceRange(Range);
5012 if (R.isInvalid())
5013 return;
5014
5015 SmallVector<CXToken, 32> CXTokens;
5016 getTokens(CXXUnit, R, CXTokens);
5017
5018 if (CXTokens.empty())
5019 return;
5020
5021 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5022 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5023 *NumTokens = CXTokens.size();
5024}
5025
5026void clang_disposeTokens(CXTranslationUnit TU,
5027 CXToken *Tokens, unsigned NumTokens) {
5028 free(Tokens);
5029}
5030
5031} // end: extern "C"
5032
5033//===----------------------------------------------------------------------===//
5034// Token annotation APIs.
5035//===----------------------------------------------------------------------===//
5036
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005037static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5038 CXCursor parent,
5039 CXClientData client_data);
5040static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5041 CXClientData client_data);
5042
5043namespace {
5044class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005045 CXToken *Tokens;
5046 CXCursor *Cursors;
5047 unsigned NumTokens;
5048 unsigned TokIdx;
5049 unsigned PreprocessingTokIdx;
5050 CursorVisitor AnnotateVis;
5051 SourceManager &SrcMgr;
5052 bool HasContextSensitiveKeywords;
5053
5054 struct PostChildrenInfo {
5055 CXCursor Cursor;
5056 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005057 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005058 unsigned BeforeChildrenTokenIdx;
5059 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005060 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005061
5062 bool MoreTokens() const { return TokIdx < NumTokens; }
5063 unsigned NextToken() const { return TokIdx; }
5064 void AdvanceToken() { ++TokIdx; }
5065 SourceLocation GetTokenLoc(unsigned tokI) {
5066 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5067 }
5068 bool isFunctionMacroToken(unsigned tokI) const {
5069 return Tokens[tokI].int_data[3] != 0;
5070 }
5071 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5072 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5073 }
5074
5075 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005076 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005077 SourceRange);
5078
5079public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005080 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005081 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005082 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005083 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005084 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005085 AnnotateTokensVisitor, this,
5086 /*VisitPreprocessorLast=*/true,
5087 /*VisitIncludedEntities=*/false,
5088 RegionOfInterest,
5089 /*VisitDeclsOnly=*/false,
5090 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005091 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005092 HasContextSensitiveKeywords(false) { }
5093
5094 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5095 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5096 bool postVisitChildren(CXCursor cursor);
5097 void AnnotateTokens();
5098
5099 /// \brief Determine whether the annotator saw any cursors that have
5100 /// context-sensitive keywords.
5101 bool hasContextSensitiveKeywords() const {
5102 return HasContextSensitiveKeywords;
5103 }
5104
5105 ~AnnotateTokensWorker() {
5106 assert(PostChildrenInfos.empty());
5107 }
5108};
5109}
5110
5111void AnnotateTokensWorker::AnnotateTokens() {
5112 // Walk the AST within the region of interest, annotating tokens
5113 // along the way.
5114 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005115}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005116
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005117static inline void updateCursorAnnotation(CXCursor &Cursor,
5118 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005119 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005120 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005121 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005122}
5123
5124/// \brief It annotates and advances tokens with a cursor until the comparison
5125//// between the cursor location and the source range is the same as
5126/// \arg compResult.
5127///
5128/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5129/// Pass RangeOverlap to annotate tokens inside a range.
5130void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5131 RangeComparisonResult compResult,
5132 SourceRange range) {
5133 while (MoreTokens()) {
5134 const unsigned I = NextToken();
5135 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005136 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5137 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005138
5139 SourceLocation TokLoc = GetTokenLoc(I);
5140 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005141 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005142 AdvanceToken();
5143 continue;
5144 }
5145 break;
5146 }
5147}
5148
5149/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005150/// \returns true if it advanced beyond all macro tokens, false otherwise.
5151bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005152 CXCursor updateC,
5153 RangeComparisonResult compResult,
5154 SourceRange range) {
5155 assert(MoreTokens());
5156 assert(isFunctionMacroToken(NextToken()) &&
5157 "Should be called only for macro arg tokens");
5158
5159 // This works differently than annotateAndAdvanceTokens; because expanded
5160 // macro arguments can have arbitrary translation-unit source order, we do not
5161 // advance the token index one by one until a token fails the range test.
5162 // We only advance once past all of the macro arg tokens if all of them
5163 // pass the range test. If one of them fails we keep the token index pointing
5164 // at the start of the macro arg tokens so that the failing token will be
5165 // annotated by a subsequent annotation try.
5166
5167 bool atLeastOneCompFail = false;
5168
5169 unsigned I = NextToken();
5170 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5171 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5172 if (TokLoc.isFileID())
5173 continue; // not macro arg token, it's parens or comma.
5174 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5175 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5176 Cursors[I] = updateC;
5177 } else
5178 atLeastOneCompFail = true;
5179 }
5180
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005181 if (atLeastOneCompFail)
5182 return false;
5183
5184 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5185 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005186}
5187
5188enum CXChildVisitResult
5189AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005190 SourceRange cursorRange = getRawCursorExtent(cursor);
5191 if (cursorRange.isInvalid())
5192 return CXChildVisit_Recurse;
5193
5194 if (!HasContextSensitiveKeywords) {
5195 // Objective-C properties can have context-sensitive keywords.
5196 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005197 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005198 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5199 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5200 }
5201 // Objective-C methods can have context-sensitive keywords.
5202 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5203 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005204 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005205 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5206 if (Method->getObjCDeclQualifier())
5207 HasContextSensitiveKeywords = true;
5208 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005209 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5210 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005211 P != PEnd; ++P) {
5212 if ((*P)->getObjCDeclQualifier()) {
5213 HasContextSensitiveKeywords = true;
5214 break;
5215 }
5216 }
5217 }
5218 }
5219 }
5220 // C++ methods can have context-sensitive keywords.
5221 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005222 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005223 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5224 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5225 HasContextSensitiveKeywords = true;
5226 }
5227 }
5228 // C++ classes can have context-sensitive keywords.
5229 else if (cursor.kind == CXCursor_StructDecl ||
5230 cursor.kind == CXCursor_ClassDecl ||
5231 cursor.kind == CXCursor_ClassTemplate ||
5232 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005233 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005234 if (D->hasAttr<FinalAttr>())
5235 HasContextSensitiveKeywords = true;
5236 }
5237 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005238
5239 // Don't override a property annotation with its getter/setter method.
5240 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5241 parent.kind == CXCursor_ObjCPropertyDecl)
5242 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005243
5244 if (clang_isPreprocessing(cursor.kind)) {
5245 // Items in the preprocessing record are kept separate from items in
5246 // declarations, so we keep a separate token index.
5247 unsigned SavedTokIdx = TokIdx;
5248 TokIdx = PreprocessingTokIdx;
5249
5250 // Skip tokens up until we catch up to the beginning of the preprocessing
5251 // entry.
5252 while (MoreTokens()) {
5253 const unsigned I = NextToken();
5254 SourceLocation TokLoc = GetTokenLoc(I);
5255 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5256 case RangeBefore:
5257 AdvanceToken();
5258 continue;
5259 case RangeAfter:
5260 case RangeOverlap:
5261 break;
5262 }
5263 break;
5264 }
5265
5266 // Look at all of the tokens within this range.
5267 while (MoreTokens()) {
5268 const unsigned I = NextToken();
5269 SourceLocation TokLoc = GetTokenLoc(I);
5270 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5271 case RangeBefore:
5272 llvm_unreachable("Infeasible");
5273 case RangeAfter:
5274 break;
5275 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005276 // For macro expansions, just note where the beginning of the macro
5277 // expansion occurs.
5278 if (cursor.kind == CXCursor_MacroExpansion) {
5279 if (TokLoc == cursorRange.getBegin())
5280 Cursors[I] = cursor;
5281 AdvanceToken();
5282 break;
5283 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005284 // We may have already annotated macro names inside macro definitions.
5285 if (Cursors[I].kind != CXCursor_MacroExpansion)
5286 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005287 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005288 continue;
5289 }
5290 break;
5291 }
5292
5293 // Save the preprocessing token index; restore the non-preprocessing
5294 // token index.
5295 PreprocessingTokIdx = TokIdx;
5296 TokIdx = SavedTokIdx;
5297 return CXChildVisit_Recurse;
5298 }
5299
5300 if (cursorRange.isInvalid())
5301 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005302
5303 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005304 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005305 const enum CXCursorKind K = clang_getCursorKind(parent);
5306 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005307 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5308 // Attributes are annotated out-of-order, skip tokens until we reach it.
5309 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005310 ? clang_getNullCursor() : parent;
5311
5312 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5313
5314 // Avoid having the cursor of an expression "overwrite" the annotation of the
5315 // variable declaration that it belongs to.
5316 // This can happen for C++ constructor expressions whose range generally
5317 // include the variable declaration, e.g.:
5318 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5319 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005320 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005321 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005322 const unsigned I = NextToken();
5323 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5324 E->getLocStart() == D->getLocation() &&
5325 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005326 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005327 AdvanceToken();
5328 }
5329 }
5330 }
5331
5332 // Before recursing into the children keep some state that we are going
5333 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5334 // extra work after the child nodes are visited.
5335 // Note that we don't call VisitChildren here to avoid traversing statements
5336 // code-recursively which can blow the stack.
5337
5338 PostChildrenInfo Info;
5339 Info.Cursor = cursor;
5340 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005341 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005342 Info.BeforeChildrenTokenIdx = NextToken();
5343 PostChildrenInfos.push_back(Info);
5344
5345 return CXChildVisit_Recurse;
5346}
5347
5348bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5349 if (PostChildrenInfos.empty())
5350 return false;
5351 const PostChildrenInfo &Info = PostChildrenInfos.back();
5352 if (!clang_equalCursors(Info.Cursor, cursor))
5353 return false;
5354
5355 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5356 const unsigned AfterChildren = NextToken();
5357 SourceRange cursorRange = Info.CursorRange;
5358
5359 // Scan the tokens that are at the end of the cursor, but are not captured
5360 // but the child cursors.
5361 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5362
5363 // Scan the tokens that are at the beginning of the cursor, but are not
5364 // capture by the child cursors.
5365 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5366 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5367 break;
5368
5369 Cursors[I] = cursor;
5370 }
5371
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005372 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5373 // encountered the attribute cursor.
5374 if (clang_isAttribute(cursor.kind))
5375 TokIdx = Info.BeforeReachingCursorIdx;
5376
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005377 PostChildrenInfos.pop_back();
5378 return false;
5379}
5380
5381static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5382 CXCursor parent,
5383 CXClientData client_data) {
5384 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5385}
5386
5387static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5388 CXClientData client_data) {
5389 return static_cast<AnnotateTokensWorker*>(client_data)->
5390 postVisitChildren(cursor);
5391}
5392
5393namespace {
5394
5395/// \brief Uses the macro expansions in the preprocessing record to find
5396/// and mark tokens that are macro arguments. This info is used by the
5397/// AnnotateTokensWorker.
5398class MarkMacroArgTokensVisitor {
5399 SourceManager &SM;
5400 CXToken *Tokens;
5401 unsigned NumTokens;
5402 unsigned CurIdx;
5403
5404public:
5405 MarkMacroArgTokensVisitor(SourceManager &SM,
5406 CXToken *tokens, unsigned numTokens)
5407 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5408
5409 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5410 if (cursor.kind != CXCursor_MacroExpansion)
5411 return CXChildVisit_Continue;
5412
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005413 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005414 if (macroRange.getBegin() == macroRange.getEnd())
5415 return CXChildVisit_Continue; // it's not a function macro.
5416
5417 for (; CurIdx < NumTokens; ++CurIdx) {
5418 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5419 macroRange.getBegin()))
5420 break;
5421 }
5422
5423 if (CurIdx == NumTokens)
5424 return CXChildVisit_Break;
5425
5426 for (; CurIdx < NumTokens; ++CurIdx) {
5427 SourceLocation tokLoc = getTokenLoc(CurIdx);
5428 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5429 break;
5430
5431 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5432 }
5433
5434 if (CurIdx == NumTokens)
5435 return CXChildVisit_Break;
5436
5437 return CXChildVisit_Continue;
5438 }
5439
5440private:
5441 SourceLocation getTokenLoc(unsigned tokI) {
5442 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5443 }
5444
5445 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5446 // The third field is reserved and currently not used. Use it here
5447 // to mark macro arg expanded tokens with their expanded locations.
5448 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5449 }
5450};
5451
5452} // end anonymous namespace
5453
5454static CXChildVisitResult
5455MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5456 CXClientData client_data) {
5457 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5458 parent);
5459}
5460
5461namespace {
5462 struct clang_annotateTokens_Data {
5463 CXTranslationUnit TU;
5464 ASTUnit *CXXUnit;
5465 CXToken *Tokens;
5466 unsigned NumTokens;
5467 CXCursor *Cursors;
5468 };
5469}
5470
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005471/// \brief Used by \c annotatePreprocessorTokens.
5472/// \returns true if lexing was finished, false otherwise.
5473static bool lexNext(Lexer &Lex, Token &Tok,
5474 unsigned &NextIdx, unsigned NumTokens) {
5475 if (NextIdx >= NumTokens)
5476 return true;
5477
5478 ++NextIdx;
5479 Lex.LexFromRawLexer(Tok);
5480 if (Tok.is(tok::eof))
5481 return true;
5482
5483 return false;
5484}
5485
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005486static void annotatePreprocessorTokens(CXTranslationUnit TU,
5487 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005488 CXCursor *Cursors,
5489 CXToken *Tokens,
5490 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005491 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005492
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005493 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005494 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5495 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005496 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005497 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005498 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005499
5500 if (BeginLocInfo.first != EndLocInfo.first)
5501 return;
5502
5503 StringRef Buffer;
5504 bool Invalid = false;
5505 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5506 if (Buffer.empty() || Invalid)
5507 return;
5508
5509 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5510 CXXUnit->getASTContext().getLangOpts(),
5511 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5512 Buffer.end());
5513 Lex.SetCommentRetentionState(true);
5514
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005515 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005516 // Lex tokens in raw mode until we hit the end of the range, to avoid
5517 // entering #includes or expanding macros.
5518 while (true) {
5519 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005520 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5521 break;
5522 unsigned TokIdx = NextIdx-1;
5523 assert(Tok.getLocation() ==
5524 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005525
5526 reprocess:
5527 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005528 // We have found a preprocessing directive. Annotate the tokens
5529 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005530 //
5531 // FIXME: Some simple tests here could identify macro definitions and
5532 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005533
5534 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005535 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5536 break;
5537
5538 MacroInfo *MI = 0;
5539 if (Tok.is(tok::raw_identifier) &&
5540 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5541 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5542 break;
5543
5544 if (Tok.is(tok::raw_identifier)) {
5545 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5546 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5547 SourceLocation MappedTokLoc =
5548 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5549 MI = getMacroInfo(II, MappedTokLoc, TU);
5550 }
5551 }
5552
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005553 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005554 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005555 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5556 finished = true;
5557 break;
5558 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005559 // If we are in a macro definition, check if the token was ever a
5560 // macro name and annotate it if that's the case.
5561 if (MI) {
5562 SourceLocation SaveLoc = Tok.getLocation();
5563 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5564 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5565 Tok.setLocation(SaveLoc);
5566 if (MacroDef)
5567 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5568 Tok.getLocation(), TU);
5569 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005570 } while (!Tok.isAtStartOfLine());
5571
5572 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5573 assert(TokIdx <= LastIdx);
5574 SourceLocation EndLoc =
5575 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5576 CXCursor Cursor =
5577 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5578
5579 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005580 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005581
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005582 if (finished)
5583 break;
5584 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005585 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005586 }
5587}
5588
5589// This gets run a separate thread to avoid stack blowout.
5590static void clang_annotateTokensImpl(void *UserData) {
5591 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5592 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5593 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5594 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5595 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5596
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005597 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005598 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5599 setThreadBackgroundPriority();
5600
5601 // Determine the region of interest, which contains all of the tokens.
5602 SourceRange RegionOfInterest;
5603 RegionOfInterest.setBegin(
5604 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5605 RegionOfInterest.setEnd(
5606 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5607 Tokens[NumTokens-1])));
5608
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005609 // Relex the tokens within the source range to look for preprocessing
5610 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005611 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005612
5613 // If begin location points inside a macro argument, set it to the expansion
5614 // location so we can have the full context when annotating semantically.
5615 {
5616 SourceManager &SM = CXXUnit->getSourceManager();
5617 SourceLocation Loc =
5618 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5619 if (Loc.isMacroID())
5620 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5621 }
5622
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005623 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5624 // Search and mark tokens that are macro argument expansions.
5625 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5626 Tokens, NumTokens);
5627 CursorVisitor MacroArgMarker(TU,
5628 MarkMacroArgTokensVisitorDelegate, &Visitor,
5629 /*VisitPreprocessorLast=*/true,
5630 /*VisitIncludedEntities=*/false,
5631 RegionOfInterest);
5632 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5633 }
5634
5635 // Annotate all of the source locations in the region of interest that map to
5636 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005637 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005638
5639 // FIXME: We use a ridiculous stack size here because the data-recursion
5640 // algorithm uses a large stack frame than the non-data recursive version,
5641 // and AnnotationTokensWorker currently transforms the data-recursion
5642 // algorithm back into a traditional recursion by explicitly calling
5643 // VisitChildren(). We will need to remove this explicit recursive call.
5644 W.AnnotateTokens();
5645
5646 // If we ran into any entities that involve context-sensitive keywords,
5647 // take another pass through the tokens to mark them as such.
5648 if (W.hasContextSensitiveKeywords()) {
5649 for (unsigned I = 0; I != NumTokens; ++I) {
5650 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5651 continue;
5652
5653 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5654 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005655 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005656 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5657 if (Property->getPropertyAttributesAsWritten() != 0 &&
5658 llvm::StringSwitch<bool>(II->getName())
5659 .Case("readonly", true)
5660 .Case("assign", true)
5661 .Case("unsafe_unretained", true)
5662 .Case("readwrite", true)
5663 .Case("retain", true)
5664 .Case("copy", true)
5665 .Case("nonatomic", true)
5666 .Case("atomic", true)
5667 .Case("getter", true)
5668 .Case("setter", true)
5669 .Case("strong", true)
5670 .Case("weak", true)
5671 .Default(false))
5672 Tokens[I].int_data[0] = CXToken_Keyword;
5673 }
5674 continue;
5675 }
5676
5677 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5678 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5679 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5680 if (llvm::StringSwitch<bool>(II->getName())
5681 .Case("in", true)
5682 .Case("out", true)
5683 .Case("inout", true)
5684 .Case("oneway", true)
5685 .Case("bycopy", true)
5686 .Case("byref", true)
5687 .Default(false))
5688 Tokens[I].int_data[0] = CXToken_Keyword;
5689 continue;
5690 }
5691
5692 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5693 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5694 Tokens[I].int_data[0] = CXToken_Keyword;
5695 continue;
5696 }
5697 }
5698 }
5699}
5700
5701extern "C" {
5702
5703void clang_annotateTokens(CXTranslationUnit TU,
5704 CXToken *Tokens, unsigned NumTokens,
5705 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005706 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005707 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005708 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005709 }
5710
5711 LOG_FUNC_SECTION {
5712 *Log << TU << ' ';
5713 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5714 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5715 *Log << clang_getRange(bloc, eloc);
5716 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005717
5718 // Any token we don't specifically annotate will have a NULL cursor.
5719 CXCursor C = clang_getNullCursor();
5720 for (unsigned I = 0; I != NumTokens; ++I)
5721 Cursors[I] = C;
5722
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005723 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005724 if (!CXXUnit)
5725 return;
5726
5727 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5728
5729 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5730 llvm::CrashRecoveryContext CRC;
5731 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5732 GetSafetyThreadStackSize() * 2)) {
5733 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5734 }
5735}
5736
5737} // end: extern "C"
5738
5739//===----------------------------------------------------------------------===//
5740// Operations for querying linkage of a cursor.
5741//===----------------------------------------------------------------------===//
5742
5743extern "C" {
5744CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5745 if (!clang_isDeclaration(cursor.kind))
5746 return CXLinkage_Invalid;
5747
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005748 const Decl *D = cxcursor::getCursorDecl(cursor);
5749 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005750 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005751 case NoLinkage:
5752 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005753 case InternalLinkage: return CXLinkage_Internal;
5754 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5755 case ExternalLinkage: return CXLinkage_External;
5756 };
5757
5758 return CXLinkage_Invalid;
5759}
5760} // end: extern "C"
5761
5762//===----------------------------------------------------------------------===//
5763// Operations for querying language of a cursor.
5764//===----------------------------------------------------------------------===//
5765
5766static CXLanguageKind getDeclLanguage(const Decl *D) {
5767 if (!D)
5768 return CXLanguage_C;
5769
5770 switch (D->getKind()) {
5771 default:
5772 break;
5773 case Decl::ImplicitParam:
5774 case Decl::ObjCAtDefsField:
5775 case Decl::ObjCCategory:
5776 case Decl::ObjCCategoryImpl:
5777 case Decl::ObjCCompatibleAlias:
5778 case Decl::ObjCImplementation:
5779 case Decl::ObjCInterface:
5780 case Decl::ObjCIvar:
5781 case Decl::ObjCMethod:
5782 case Decl::ObjCProperty:
5783 case Decl::ObjCPropertyImpl:
5784 case Decl::ObjCProtocol:
5785 return CXLanguage_ObjC;
5786 case Decl::CXXConstructor:
5787 case Decl::CXXConversion:
5788 case Decl::CXXDestructor:
5789 case Decl::CXXMethod:
5790 case Decl::CXXRecord:
5791 case Decl::ClassTemplate:
5792 case Decl::ClassTemplatePartialSpecialization:
5793 case Decl::ClassTemplateSpecialization:
5794 case Decl::Friend:
5795 case Decl::FriendTemplate:
5796 case Decl::FunctionTemplate:
5797 case Decl::LinkageSpec:
5798 case Decl::Namespace:
5799 case Decl::NamespaceAlias:
5800 case Decl::NonTypeTemplateParm:
5801 case Decl::StaticAssert:
5802 case Decl::TemplateTemplateParm:
5803 case Decl::TemplateTypeParm:
5804 case Decl::UnresolvedUsingTypename:
5805 case Decl::UnresolvedUsingValue:
5806 case Decl::Using:
5807 case Decl::UsingDirective:
5808 case Decl::UsingShadow:
5809 return CXLanguage_CPlusPlus;
5810 }
5811
5812 return CXLanguage_C;
5813}
5814
5815extern "C" {
5816
5817enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5818 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005819 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005820 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5821 return CXAvailability_Available;
5822
5823 switch (D->getAvailability()) {
5824 case AR_Available:
5825 case AR_NotYetIntroduced:
5826 return CXAvailability_Available;
5827
5828 case AR_Deprecated:
5829 return CXAvailability_Deprecated;
5830
5831 case AR_Unavailable:
5832 return CXAvailability_NotAvailable;
5833 }
5834 }
5835
5836 return CXAvailability_Available;
5837}
5838
5839static CXVersion convertVersion(VersionTuple In) {
5840 CXVersion Out = { -1, -1, -1 };
5841 if (In.empty())
5842 return Out;
5843
5844 Out.Major = In.getMajor();
5845
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005846 Optional<unsigned> Minor = In.getMinor();
5847 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005848 Out.Minor = *Minor;
5849 else
5850 return Out;
5851
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005852 Optional<unsigned> Subminor = In.getSubminor();
5853 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005854 Out.Subminor = *Subminor;
5855
5856 return Out;
5857}
5858
5859int clang_getCursorPlatformAvailability(CXCursor cursor,
5860 int *always_deprecated,
5861 CXString *deprecated_message,
5862 int *always_unavailable,
5863 CXString *unavailable_message,
5864 CXPlatformAvailability *availability,
5865 int availability_size) {
5866 if (always_deprecated)
5867 *always_deprecated = 0;
5868 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005869 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005870 if (always_unavailable)
5871 *always_unavailable = 0;
5872 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005873 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005874
5875 if (!clang_isDeclaration(cursor.kind))
5876 return 0;
5877
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005878 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005879 if (!D)
5880 return 0;
5881
5882 int N = 0;
5883 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5884 ++A) {
5885 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5886 if (always_deprecated)
5887 *always_deprecated = 1;
5888 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005889 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005890 continue;
5891 }
5892
5893 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5894 if (always_unavailable)
5895 *always_unavailable = 1;
5896 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005897 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005898 }
5899 continue;
5900 }
5901
5902 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5903 if (N < availability_size) {
5904 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005905 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005906 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5907 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5908 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5909 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005910 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005911 }
5912 ++N;
5913 }
5914 }
5915
5916 return N;
5917}
5918
5919void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5920 clang_disposeString(availability->Platform);
5921 clang_disposeString(availability->Message);
5922}
5923
5924CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5925 if (clang_isDeclaration(cursor.kind))
5926 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5927
5928 return CXLanguage_Invalid;
5929}
5930
5931 /// \brief If the given cursor is the "templated" declaration
5932 /// descibing a class or function template, return the class or
5933 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005934static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005935 if (!D)
5936 return 0;
5937
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005938 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005939 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5940 return FunTmpl;
5941
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005942 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005943 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5944 return ClassTmpl;
5945
5946 return D;
5947}
5948
5949CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5950 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005951 if (const Decl *D = getCursorDecl(cursor)) {
5952 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005953 if (!DC)
5954 return clang_getNullCursor();
5955
5956 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5957 getCursorTU(cursor));
5958 }
5959 }
5960
5961 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005962 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005963 return MakeCXCursor(D, getCursorTU(cursor));
5964 }
5965
5966 return clang_getNullCursor();
5967}
5968
5969CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5970 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005971 if (const Decl *D = getCursorDecl(cursor)) {
5972 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005973 if (!DC)
5974 return clang_getNullCursor();
5975
5976 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5977 getCursorTU(cursor));
5978 }
5979 }
5980
5981 // FIXME: Note that we can't easily compute the lexical context of a
5982 // statement or expression, so we return nothing.
5983 return clang_getNullCursor();
5984}
5985
5986CXFile clang_getIncludedFile(CXCursor cursor) {
5987 if (cursor.kind != CXCursor_InclusionDirective)
5988 return 0;
5989
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005990 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005991 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005992}
5993
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005994unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5995 if (C.kind != CXCursor_ObjCPropertyDecl)
5996 return CXObjCPropertyAttr_noattr;
5997
5998 unsigned Result = CXObjCPropertyAttr_noattr;
5999 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6000 ObjCPropertyDecl::PropertyAttributeKind Attr =
6001 PD->getPropertyAttributesAsWritten();
6002
6003#define SET_CXOBJCPROP_ATTR(A) \
6004 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6005 Result |= CXObjCPropertyAttr_##A
6006 SET_CXOBJCPROP_ATTR(readonly);
6007 SET_CXOBJCPROP_ATTR(getter);
6008 SET_CXOBJCPROP_ATTR(assign);
6009 SET_CXOBJCPROP_ATTR(readwrite);
6010 SET_CXOBJCPROP_ATTR(retain);
6011 SET_CXOBJCPROP_ATTR(copy);
6012 SET_CXOBJCPROP_ATTR(nonatomic);
6013 SET_CXOBJCPROP_ATTR(setter);
6014 SET_CXOBJCPROP_ATTR(atomic);
6015 SET_CXOBJCPROP_ATTR(weak);
6016 SET_CXOBJCPROP_ATTR(strong);
6017 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6018#undef SET_CXOBJCPROP_ATTR
6019
6020 return Result;
6021}
6022
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006023unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6024 if (!clang_isDeclaration(C.kind))
6025 return CXObjCDeclQualifier_None;
6026
6027 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6028 const Decl *D = getCursorDecl(C);
6029 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6030 QT = MD->getObjCDeclQualifier();
6031 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6032 QT = PD->getObjCDeclQualifier();
6033 if (QT == Decl::OBJC_TQ_None)
6034 return CXObjCDeclQualifier_None;
6035
6036 unsigned Result = CXObjCDeclQualifier_None;
6037 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6038 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6039 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6040 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6041 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6042 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6043
6044 return Result;
6045}
6046
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006047unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6048 if (!clang_isDeclaration(C.kind))
6049 return 0;
6050
6051 const Decl *D = getCursorDecl(C);
6052 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6053 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6054 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6055 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6056
6057 return 0;
6058}
6059
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006060unsigned clang_Cursor_isVariadic(CXCursor C) {
6061 if (!clang_isDeclaration(C.kind))
6062 return 0;
6063
6064 const Decl *D = getCursorDecl(C);
6065 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6066 return FD->isVariadic();
6067 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6068 return MD->isVariadic();
6069
6070 return 0;
6071}
6072
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006073CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6074 if (!clang_isDeclaration(C.kind))
6075 return clang_getNullRange();
6076
6077 const Decl *D = getCursorDecl(C);
6078 ASTContext &Context = getCursorContext(C);
6079 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6080 if (!RC)
6081 return clang_getNullRange();
6082
6083 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6084}
6085
6086CXString clang_Cursor_getRawCommentText(CXCursor C) {
6087 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006088 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006089
6090 const Decl *D = getCursorDecl(C);
6091 ASTContext &Context = getCursorContext(C);
6092 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6093 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6094 StringRef();
6095
6096 // Don't duplicate the string because RawText points directly into source
6097 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006098 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006099}
6100
6101CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6102 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006103 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006104
6105 const Decl *D = getCursorDecl(C);
6106 const ASTContext &Context = getCursorContext(C);
6107 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6108
6109 if (RC) {
6110 StringRef BriefText = RC->getBriefText(Context);
6111
6112 // Don't duplicate the string because RawComment ensures that this memory
6113 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006114 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006115 }
6116
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006117 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006118}
6119
6120CXComment clang_Cursor_getParsedComment(CXCursor C) {
6121 if (!clang_isDeclaration(C.kind))
6122 return cxcomment::createCXComment(NULL, NULL);
6123
6124 const Decl *D = getCursorDecl(C);
6125 const ASTContext &Context = getCursorContext(C);
6126 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6127
6128 return cxcomment::createCXComment(FC, getCursorTU(C));
6129}
6130
6131CXModule clang_Cursor_getModule(CXCursor C) {
6132 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006133 if (const ImportDecl *ImportD =
6134 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006135 return ImportD->getImportedModule();
6136 }
6137
6138 return 0;
6139}
6140
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006141CXFile clang_Module_getASTFile(CXModule CXMod) {
6142 if (!CXMod)
6143 return 0;
6144 Module *Mod = static_cast<Module*>(CXMod);
6145 return const_cast<FileEntry *>(Mod->getASTFile());
6146}
6147
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006148CXModule clang_Module_getParent(CXModule CXMod) {
6149 if (!CXMod)
6150 return 0;
6151 Module *Mod = static_cast<Module*>(CXMod);
6152 return Mod->Parent;
6153}
6154
6155CXString clang_Module_getName(CXModule CXMod) {
6156 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006157 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006158 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006159 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006160}
6161
6162CXString clang_Module_getFullName(CXModule CXMod) {
6163 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006164 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006165 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006166 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006167}
6168
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006169unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6170 CXModule CXMod) {
6171 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006172 return 0;
6173 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006174 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6175 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6176 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006177}
6178
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006179CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6180 CXModule CXMod, unsigned Index) {
6181 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006182 return 0;
6183 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006184 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006185
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006186 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6187 if (Index < TopHeaders.size())
6188 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006189
6190 return 0;
6191}
6192
6193} // end: extern "C"
6194
6195//===----------------------------------------------------------------------===//
6196// C++ AST instrospection.
6197//===----------------------------------------------------------------------===//
6198
6199extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006200unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6201 if (!clang_isDeclaration(C.kind))
6202 return 0;
6203
6204 const CXXMethodDecl *Method = 0;
6205 const Decl *D = cxcursor::getCursorDecl(C);
6206 if (const FunctionTemplateDecl *FunTmpl =
6207 dyn_cast_or_null<FunctionTemplateDecl>(D))
6208 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6209 else
6210 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6211 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6212}
6213
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006214unsigned clang_CXXMethod_isStatic(CXCursor C) {
6215 if (!clang_isDeclaration(C.kind))
6216 return 0;
6217
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006218 const CXXMethodDecl *Method = 0;
6219 const Decl *D = cxcursor::getCursorDecl(C);
6220 if (const FunctionTemplateDecl *FunTmpl =
6221 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006222 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6223 else
6224 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6225 return (Method && Method->isStatic()) ? 1 : 0;
6226}
6227
6228unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6229 if (!clang_isDeclaration(C.kind))
6230 return 0;
6231
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006232 const CXXMethodDecl *Method = 0;
6233 const Decl *D = cxcursor::getCursorDecl(C);
6234 if (const FunctionTemplateDecl *FunTmpl =
6235 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006236 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6237 else
6238 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6239 return (Method && Method->isVirtual()) ? 1 : 0;
6240}
6241} // end: extern "C"
6242
6243//===----------------------------------------------------------------------===//
6244// Attribute introspection.
6245//===----------------------------------------------------------------------===//
6246
6247extern "C" {
6248CXType clang_getIBOutletCollectionType(CXCursor C) {
6249 if (C.kind != CXCursor_IBOutletCollectionAttr)
6250 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6251
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006252 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006253 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6254
6255 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6256}
6257} // end: extern "C"
6258
6259//===----------------------------------------------------------------------===//
6260// Inspecting memory usage.
6261//===----------------------------------------------------------------------===//
6262
6263typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6264
6265static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6266 enum CXTUResourceUsageKind k,
6267 unsigned long amount) {
6268 CXTUResourceUsageEntry entry = { k, amount };
6269 entries.push_back(entry);
6270}
6271
6272extern "C" {
6273
6274const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6275 const char *str = "";
6276 switch (kind) {
6277 case CXTUResourceUsage_AST:
6278 str = "ASTContext: expressions, declarations, and types";
6279 break;
6280 case CXTUResourceUsage_Identifiers:
6281 str = "ASTContext: identifiers";
6282 break;
6283 case CXTUResourceUsage_Selectors:
6284 str = "ASTContext: selectors";
6285 break;
6286 case CXTUResourceUsage_GlobalCompletionResults:
6287 str = "Code completion: cached global results";
6288 break;
6289 case CXTUResourceUsage_SourceManagerContentCache:
6290 str = "SourceManager: content cache allocator";
6291 break;
6292 case CXTUResourceUsage_AST_SideTables:
6293 str = "ASTContext: side tables";
6294 break;
6295 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6296 str = "SourceManager: malloc'ed memory buffers";
6297 break;
6298 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6299 str = "SourceManager: mmap'ed memory buffers";
6300 break;
6301 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6302 str = "ExternalASTSource: malloc'ed memory buffers";
6303 break;
6304 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6305 str = "ExternalASTSource: mmap'ed memory buffers";
6306 break;
6307 case CXTUResourceUsage_Preprocessor:
6308 str = "Preprocessor: malloc'ed memory";
6309 break;
6310 case CXTUResourceUsage_PreprocessingRecord:
6311 str = "Preprocessor: PreprocessingRecord";
6312 break;
6313 case CXTUResourceUsage_SourceManager_DataStructures:
6314 str = "SourceManager: data structures and tables";
6315 break;
6316 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6317 str = "Preprocessor: header search tables";
6318 break;
6319 }
6320 return str;
6321}
6322
6323CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6324 if (!TU) {
6325 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6326 return usage;
6327 }
6328
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006329 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006330 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6331 ASTContext &astContext = astUnit->getASTContext();
6332
6333 // How much memory is used by AST nodes and types?
6334 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6335 (unsigned long) astContext.getASTAllocatedMemory());
6336
6337 // How much memory is used by identifiers?
6338 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6339 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6340
6341 // How much memory is used for selectors?
6342 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6343 (unsigned long) astContext.Selectors.getTotalMemory());
6344
6345 // How much memory is used by ASTContext's side tables?
6346 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6347 (unsigned long) astContext.getSideTableAllocatedMemory());
6348
6349 // How much memory is used for caching global code completion results?
6350 unsigned long completionBytes = 0;
6351 if (GlobalCodeCompletionAllocator *completionAllocator =
6352 astUnit->getCachedCompletionAllocator().getPtr()) {
6353 completionBytes = completionAllocator->getTotalMemory();
6354 }
6355 createCXTUResourceUsageEntry(*entries,
6356 CXTUResourceUsage_GlobalCompletionResults,
6357 completionBytes);
6358
6359 // How much memory is being used by SourceManager's content cache?
6360 createCXTUResourceUsageEntry(*entries,
6361 CXTUResourceUsage_SourceManagerContentCache,
6362 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6363
6364 // How much memory is being used by the MemoryBuffer's in SourceManager?
6365 const SourceManager::MemoryBufferSizes &srcBufs =
6366 astUnit->getSourceManager().getMemoryBufferSizes();
6367
6368 createCXTUResourceUsageEntry(*entries,
6369 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6370 (unsigned long) srcBufs.malloc_bytes);
6371 createCXTUResourceUsageEntry(*entries,
6372 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6373 (unsigned long) srcBufs.mmap_bytes);
6374 createCXTUResourceUsageEntry(*entries,
6375 CXTUResourceUsage_SourceManager_DataStructures,
6376 (unsigned long) astContext.getSourceManager()
6377 .getDataStructureSizes());
6378
6379 // How much memory is being used by the ExternalASTSource?
6380 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6381 const ExternalASTSource::MemoryBufferSizes &sizes =
6382 esrc->getMemoryBufferSizes();
6383
6384 createCXTUResourceUsageEntry(*entries,
6385 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6386 (unsigned long) sizes.malloc_bytes);
6387 createCXTUResourceUsageEntry(*entries,
6388 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6389 (unsigned long) sizes.mmap_bytes);
6390 }
6391
6392 // How much memory is being used by the Preprocessor?
6393 Preprocessor &pp = astUnit->getPreprocessor();
6394 createCXTUResourceUsageEntry(*entries,
6395 CXTUResourceUsage_Preprocessor,
6396 pp.getTotalMemory());
6397
6398 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6399 createCXTUResourceUsageEntry(*entries,
6400 CXTUResourceUsage_PreprocessingRecord,
6401 pRec->getTotalMemory());
6402 }
6403
6404 createCXTUResourceUsageEntry(*entries,
6405 CXTUResourceUsage_Preprocessor_HeaderSearch,
6406 pp.getHeaderSearchInfo().getTotalMemory());
6407
6408 CXTUResourceUsage usage = { (void*) entries.get(),
6409 (unsigned) entries->size(),
6410 entries->size() ? &(*entries)[0] : 0 };
6411 entries.take();
6412 return usage;
6413}
6414
6415void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6416 if (usage.data)
6417 delete (MemUsageEntries*) usage.data;
6418}
6419
6420} // end extern "C"
6421
6422void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6423 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6424 for (unsigned I = 0; I != Usage.numEntries; ++I)
6425 fprintf(stderr, " %s: %lu\n",
6426 clang_getTUResourceUsageName(Usage.entries[I].kind),
6427 Usage.entries[I].amount);
6428
6429 clang_disposeCXTUResourceUsage(Usage);
6430}
6431
6432//===----------------------------------------------------------------------===//
6433// Misc. utility functions.
6434//===----------------------------------------------------------------------===//
6435
6436/// Default to using an 8 MB stack size on "safety" threads.
6437static unsigned SafetyStackThreadSize = 8 << 20;
6438
6439namespace clang {
6440
6441bool RunSafely(llvm::CrashRecoveryContext &CRC,
6442 void (*Fn)(void*), void *UserData,
6443 unsigned Size) {
6444 if (!Size)
6445 Size = GetSafetyThreadStackSize();
6446 if (Size)
6447 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6448 return CRC.RunSafely(Fn, UserData);
6449}
6450
6451unsigned GetSafetyThreadStackSize() {
6452 return SafetyStackThreadSize;
6453}
6454
6455void SetSafetyThreadStackSize(unsigned Value) {
6456 SafetyStackThreadSize = Value;
6457}
6458
6459}
6460
6461void clang::setThreadBackgroundPriority() {
6462 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6463 return;
6464
6465 // FIXME: Move to llvm/Support and make it cross-platform.
6466#ifdef __APPLE__
6467 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6468#endif
6469}
6470
6471void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6472 if (!Unit)
6473 return;
6474
6475 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6476 DEnd = Unit->stored_diag_end();
6477 D != DEnd; ++D) {
6478 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6479 CXString Msg = clang_formatDiagnostic(&Diag,
6480 clang_defaultDiagnosticDisplayOptions());
6481 fprintf(stderr, "%s\n", clang_getCString(Msg));
6482 clang_disposeString(Msg);
6483 }
6484#ifdef LLVM_ON_WIN32
6485 // On Windows, force a flush, since there may be multiple copies of
6486 // stderr and stdout in the file system, all with different buffers
6487 // but writing to the same device.
6488 fflush(stderr);
6489#endif
6490}
6491
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006492MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6493 SourceLocation MacroDefLoc,
6494 CXTranslationUnit TU){
6495 if (MacroDefLoc.isInvalid() || !TU)
6496 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006497 if (!II.hadMacroDefinition())
6498 return 0;
6499
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006500 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006501 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006502 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006503 if (MD) {
6504 for (MacroDirective::DefInfo
6505 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6506 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6507 return Def.getMacroInfo();
6508 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006509 }
6510
6511 return 0;
6512}
6513
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006514const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6515 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006516 if (!MacroDef || !TU)
6517 return 0;
6518 const IdentifierInfo *II = MacroDef->getName();
6519 if (!II)
6520 return 0;
6521
6522 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6523}
6524
6525MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6526 const Token &Tok,
6527 CXTranslationUnit TU) {
6528 if (!MI || !TU)
6529 return 0;
6530 if (Tok.isNot(tok::raw_identifier))
6531 return 0;
6532
6533 if (MI->getNumTokens() == 0)
6534 return 0;
6535 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6536 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006537 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006538
6539 // Check that the token is inside the definition and not its argument list.
6540 SourceManager &SM = Unit->getSourceManager();
6541 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6542 return 0;
6543 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6544 return 0;
6545
6546 Preprocessor &PP = Unit->getPreprocessor();
6547 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6548 if (!PPRec)
6549 return 0;
6550
6551 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6552 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6553 if (!II.hadMacroDefinition())
6554 return 0;
6555
6556 // Check that the identifier is not one of the macro arguments.
6557 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6558 return 0;
6559
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006560 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6561 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006562 return 0;
6563
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006564 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006565}
6566
6567MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6568 SourceLocation Loc,
6569 CXTranslationUnit TU) {
6570 if (Loc.isInvalid() || !MI || !TU)
6571 return 0;
6572
6573 if (MI->getNumTokens() == 0)
6574 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006575 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006576 Preprocessor &PP = Unit->getPreprocessor();
6577 if (!PP.getPreprocessingRecord())
6578 return 0;
6579 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6580 Token Tok;
6581 if (PP.getRawToken(Loc, Tok))
6582 return 0;
6583
6584 return checkForMacroInMacroDefinition(MI, Tok, TU);
6585}
6586
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006587extern "C" {
6588
6589CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006590 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006591}
6592
6593} // end: extern "C"
6594
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006595Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6596 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006597 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006598 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006599 if (Unit->isMainFileAST())
6600 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006601 return *this;
6602 }
6603 }
6604
6605 LogOS << "<NULL TU>";
6606 return *this;
6607}
6608
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006609Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6610 *this << FE->getName();
6611 return *this;
6612}
6613
6614Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6615 CXString cursorName = clang_getCursorDisplayName(cursor);
6616 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6617 clang_disposeString(cursorName);
6618 return *this;
6619}
6620
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006621Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6622 CXFile File;
6623 unsigned Line, Column;
6624 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6625 CXString FileName = clang_getFileName(File);
6626 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6627 clang_disposeString(FileName);
6628 return *this;
6629}
6630
6631Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6632 CXSourceLocation BLoc = clang_getRangeStart(range);
6633 CXSourceLocation ELoc = clang_getRangeEnd(range);
6634
6635 CXFile BFile;
6636 unsigned BLine, BColumn;
6637 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6638
6639 CXFile EFile;
6640 unsigned ELine, EColumn;
6641 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6642
6643 CXString BFileName = clang_getFileName(BFile);
6644 if (BFile == EFile) {
6645 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6646 BLine, BColumn, ELine, EColumn);
6647 } else {
6648 CXString EFileName = clang_getFileName(EFile);
6649 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6650 BLine, BColumn)
6651 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6652 ELine, EColumn);
6653 clang_disposeString(EFileName);
6654 }
6655 clang_disposeString(BFileName);
6656 return *this;
6657}
6658
6659Logger &cxindex::Logger::operator<<(CXString Str) {
6660 *this << clang_getCString(Str);
6661 return *this;
6662}
6663
6664Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6665 LogOS << Fmt;
6666 return *this;
6667}
6668
6669cxindex::Logger::~Logger() {
6670 LogOS.flush();
6671
6672 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6673
6674 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6675
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006676 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006677 OS << "[libclang:" << Name << ':';
6678
6679 // FIXME: Portability.
6680#if HAVE_PTHREAD_H && __APPLE__
6681 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6682 OS << tid << ':';
6683#endif
6684
6685 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6686 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6687 OS << Msg.str() << '\n';
6688
6689 if (Trace) {
6690 llvm::sys::PrintStackTrace(stderr);
6691 OS << "--------------------------------------------------\n";
6692 }
6693}