blob: 967750f954a54f0f6e0097a200597dcfbfa772f5 [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;
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001914 /// \brief Process clauses with list of variables.
1915 template <typename T>
1916 void VisitOMPClauseList(T *Node);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001917public:
1918 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1919#define OPENMP_CLAUSE(Name, Class) \
1920 void Visit##Class(const Class *C);
1921#include "clang/Basic/OpenMPKinds.def"
1922};
1923
1924void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001925
1926template<typename T>
1927void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1928 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1929 E = Node->varlist_end();
1930 I != E; ++I)
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001931 Visitor->AddStmt(*I);
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001932}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001933
1934void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001935 VisitOMPClauseList(C);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001936}
Alexey Bataevd195bc32013-10-01 05:32:34 +00001937void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1938 const OMPFirstprivateClause *C) {
1939 VisitOMPClauseList(C);
1940}
Alexey Bataev0c018352013-09-06 18:03:48 +00001941void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001942 VisitOMPClauseList(C);
Alexey Bataev0c018352013-09-06 18:03:48 +00001943}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001944}
Alexey Bataev543c4ae2013-09-24 03:17:45 +00001945
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001946void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1947 unsigned size = WL.size();
1948 OMPClauseEnqueue Visitor(this);
1949 Visitor.Visit(S);
1950 if (size == WL.size())
1951 return;
1952 // Now reverse the entries we just added. This will match the DFS
1953 // ordering performed by the worklist.
1954 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1955 std::reverse(I, E);
1956}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001957void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001958 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1959}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001961 AddDecl(B->getBlockDecl());
1962}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001963void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001964 EnqueueChildren(E);
1965 AddTypeLoc(E->getTypeSourceInfo());
1966}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001967void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1968 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001969 E = S->body_rend(); I != E; ++I) {
1970 AddStmt(*I);
1971 }
1972}
1973void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001974VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001975 AddStmt(S->getSubStmt());
1976 AddDeclarationNameInfo(S);
1977 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1978 AddNestedNameSpecifierLoc(QualifierLoc);
1979}
1980
1981void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001982VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1984 AddDeclarationNameInfo(E);
1985 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1986 AddNestedNameSpecifierLoc(QualifierLoc);
1987 if (!E->isImplicitAccess())
1988 AddStmt(E->getBase());
1989}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001990void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001991 // Enqueue the initializer , if any.
1992 AddStmt(E->getInitializer());
1993 // Enqueue the array size, if any.
1994 AddStmt(E->getArraySize());
1995 // Enqueue the allocated type.
1996 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1997 // Enqueue the placement arguments.
1998 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1999 AddStmt(E->getPlacementArg(I-1));
2000}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002001void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002002 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2003 AddStmt(CE->getArg(I-1));
2004 AddStmt(CE->getCallee());
2005 AddStmt(CE->getArg(0));
2006}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002007void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2008 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002009 // Visit the name of the type being destroyed.
2010 AddTypeLoc(E->getDestroyedTypeInfo());
2011 // Visit the scope type that looks disturbingly like the nested-name-specifier
2012 // but isn't.
2013 AddTypeLoc(E->getScopeTypeInfo());
2014 // Visit the nested-name-specifier.
2015 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2016 AddNestedNameSpecifierLoc(QualifierLoc);
2017 // Visit base expression.
2018 AddStmt(E->getBase());
2019}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2021 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002022 AddTypeLoc(E->getTypeSourceInfo());
2023}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002024void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2025 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002026 EnqueueChildren(E);
2027 AddTypeLoc(E->getTypeSourceInfo());
2028}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002029void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002030 EnqueueChildren(E);
2031 if (E->isTypeOperand())
2032 AddTypeLoc(E->getTypeOperandSourceInfo());
2033}
2034
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2036 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002037 EnqueueChildren(E);
2038 AddTypeLoc(E->getTypeSourceInfo());
2039}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002041 EnqueueChildren(E);
2042 if (E->isTypeOperand())
2043 AddTypeLoc(E->getTypeOperandSourceInfo());
2044}
2045
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002047 EnqueueChildren(S);
2048 AddDecl(S->getExceptionDecl());
2049}
2050
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002052 if (DR->hasExplicitTemplateArgs()) {
2053 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2054 }
2055 WL.push_back(DeclRefExprParts(DR, Parent));
2056}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2058 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002059 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2060 AddDeclarationNameInfo(E);
2061 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2062}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002064 unsigned size = WL.size();
2065 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002066 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002067 D != DEnd; ++D) {
2068 AddDecl(*D, isFirst);
2069 isFirst = false;
2070 }
2071 if (size == WL.size())
2072 return;
2073 // Now reverse the entries we just added. This will match the DFS
2074 // ordering performed by the worklist.
2075 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2076 std::reverse(I, E);
2077}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002079 AddStmt(E->getInit());
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002080 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002081 D = E->designators_rbegin(), DEnd = E->designators_rend();
2082 D != DEnd; ++D) {
2083 if (D->isFieldDesignator()) {
2084 if (FieldDecl *Field = D->getField())
2085 AddMemberRef(Field, D->getFieldLoc());
2086 continue;
2087 }
2088 if (D->isArrayDesignator()) {
2089 AddStmt(E->getArrayIndex(*D));
2090 continue;
2091 }
2092 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2093 AddStmt(E->getArrayRangeEnd(*D));
2094 AddStmt(E->getArrayRangeStart(*D));
2095 }
2096}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002098 EnqueueChildren(E);
2099 AddTypeLoc(E->getTypeInfoAsWritten());
2100}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002102 AddStmt(FS->getBody());
2103 AddStmt(FS->getInc());
2104 AddStmt(FS->getCond());
2105 AddDecl(FS->getConditionVariable());
2106 AddStmt(FS->getInit());
2107}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002109 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2110}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002112 AddStmt(If->getElse());
2113 AddStmt(If->getThen());
2114 AddStmt(If->getCond());
2115 AddDecl(If->getConditionVariable());
2116}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002118 // We care about the syntactic form of the initializer list, only.
2119 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2120 IE = Syntactic;
2121 EnqueueChildren(IE);
2122}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002124 WL.push_back(MemberExprParts(M, Parent));
2125
2126 // If the base of the member access expression is an implicit 'this', don't
2127 // visit it.
2128 // FIXME: If we ever want to show these implicit accesses, this will be
2129 // unfortunate. However, clang_getCursor() relies on this behavior.
2130 if (!M->isImplicitAccess())
2131 AddStmt(M->getBase());
2132}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002134 AddTypeLoc(E->getEncodedTypeSourceInfo());
2135}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002137 EnqueueChildren(M);
2138 AddTypeLoc(M->getClassReceiverTypeInfo());
2139}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002141 // Visit the components of the offsetof expression.
2142 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2143 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2144 const OffsetOfNode &Node = E->getComponent(I-1);
2145 switch (Node.getKind()) {
2146 case OffsetOfNode::Array:
2147 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2148 break;
2149 case OffsetOfNode::Field:
2150 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2151 break;
2152 case OffsetOfNode::Identifier:
2153 case OffsetOfNode::Base:
2154 continue;
2155 }
2156 }
2157 // Visit the type into which we're computing the offset.
2158 AddTypeLoc(E->getTypeSourceInfo());
2159}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002161 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2162 WL.push_back(OverloadExprParts(E, Parent));
2163}
2164void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002165 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002166 EnqueueChildren(E);
2167 if (E->isArgumentType())
2168 AddTypeLoc(E->getArgumentTypeInfo());
2169}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002171 EnqueueChildren(S);
2172}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002174 AddStmt(S->getBody());
2175 AddStmt(S->getCond());
2176 AddDecl(S->getConditionVariable());
2177}
2178
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002180 AddStmt(W->getBody());
2181 AddStmt(W->getCond());
2182 AddDecl(W->getConditionVariable());
2183}
2184
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002186 AddTypeLoc(E->getQueriedTypeSourceInfo());
2187}
2188
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002190 AddTypeLoc(E->getRhsTypeSourceInfo());
2191 AddTypeLoc(E->getLhsTypeSourceInfo());
2192}
2193
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002195 for (unsigned I = E->getNumArgs(); I > 0; --I)
2196 AddTypeLoc(E->getArg(I-1));
2197}
2198
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002200 AddTypeLoc(E->getQueriedTypeSourceInfo());
2201}
2202
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002204 EnqueueChildren(E);
2205}
2206
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002208 VisitOverloadExpr(U);
2209 if (!U->isImplicitAccess())
2210 AddStmt(U->getBase());
2211}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002213 AddStmt(E->getSubExpr());
2214 AddTypeLoc(E->getWrittenTypeInfo());
2215}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002217 WL.push_back(SizeOfPackExprParts(E, Parent));
2218}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002220 // If the opaque value has a source expression, just transparently
2221 // visit that. This is useful for (e.g.) pseudo-object expressions.
2222 if (Expr *SourceExpr = E->getSourceExpr())
2223 return Visit(SourceExpr);
2224}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002226 AddStmt(E->getBody());
2227 WL.push_back(LambdaExprParts(E, Parent));
2228}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002230 // Treat the expression like its syntactic form.
2231 Visit(E->getSyntacticForm());
2232}
2233
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002234void EnqueueVisitor::VisitOMPExecutableDirective(
2235 const OMPExecutableDirective *D) {
2236 EnqueueChildren(D);
2237 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2238 E = D->clauses().end();
2239 I != E; ++I)
2240 EnqueueChildren(*I);
2241}
2242
2243void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2244 VisitOMPExecutableDirective(D);
2245}
2246
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002247void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002248 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2249}
2250
2251bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2252 if (RegionOfInterest.isValid()) {
2253 SourceRange Range = getRawCursorExtent(C);
2254 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2255 return false;
2256 }
2257 return true;
2258}
2259
2260bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2261 while (!WL.empty()) {
2262 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002263 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002264
2265 // Set the Parent field, then back to its old value once we're done.
2266 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2267
2268 switch (LI.getKind()) {
2269 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002270 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002271 if (!D)
2272 continue;
2273
2274 // For now, perform default visitation for Decls.
2275 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2276 cast<DeclVisit>(&LI)->isFirst())))
2277 return true;
2278
2279 continue;
2280 }
2281 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2282 const ASTTemplateArgumentListInfo *ArgList =
2283 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2284 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2285 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2286 Arg != ArgEnd; ++Arg) {
2287 if (VisitTemplateArgumentLoc(*Arg))
2288 return true;
2289 }
2290 continue;
2291 }
2292 case VisitorJob::TypeLocVisitKind: {
2293 // Perform default visitation for TypeLocs.
2294 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2295 return true;
2296 continue;
2297 }
2298 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002299 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002300 if (LabelStmt *stmt = LS->getStmt()) {
2301 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2302 TU))) {
2303 return true;
2304 }
2305 }
2306 continue;
2307 }
2308
2309 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2310 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2311 if (VisitNestedNameSpecifierLoc(V->get()))
2312 return true;
2313 continue;
2314 }
2315
2316 case VisitorJob::DeclarationNameInfoVisitKind: {
2317 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2318 ->get()))
2319 return true;
2320 continue;
2321 }
2322 case VisitorJob::MemberRefVisitKind: {
2323 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2324 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2325 return true;
2326 continue;
2327 }
2328 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002329 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002330 if (!S)
2331 continue;
2332
2333 // Update the current cursor.
2334 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2335 if (!IsInRegionOfInterest(Cursor))
2336 continue;
2337 switch (Visitor(Cursor, Parent, ClientData)) {
2338 case CXChildVisit_Break: return true;
2339 case CXChildVisit_Continue: break;
2340 case CXChildVisit_Recurse:
2341 if (PostChildrenVisitor)
2342 WL.push_back(PostChildrenVisit(0, Cursor));
2343 EnqueueWorkList(WL, S);
2344 break;
2345 }
2346 continue;
2347 }
2348 case VisitorJob::MemberExprPartsKind: {
2349 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002350 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002351
2352 // Visit the nested-name-specifier
2353 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2354 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2355 return true;
2356
2357 // Visit the declaration name.
2358 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2359 return true;
2360
2361 // Visit the explicitly-specified template arguments, if any.
2362 if (M->hasExplicitTemplateArgs()) {
2363 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2364 *ArgEnd = Arg + M->getNumTemplateArgs();
2365 Arg != ArgEnd; ++Arg) {
2366 if (VisitTemplateArgumentLoc(*Arg))
2367 return true;
2368 }
2369 }
2370 continue;
2371 }
2372 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002373 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002374 // Visit nested-name-specifier, if present.
2375 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2376 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2377 return true;
2378 // Visit declaration name.
2379 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2380 return true;
2381 continue;
2382 }
2383 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002384 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002385 // Visit the nested-name-specifier.
2386 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2387 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2388 return true;
2389 // Visit the declaration name.
2390 if (VisitDeclarationNameInfo(O->getNameInfo()))
2391 return true;
2392 // Visit the overloaded declaration reference.
2393 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2394 return true;
2395 continue;
2396 }
2397 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002398 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002399 NamedDecl *Pack = E->getPack();
2400 if (isa<TemplateTypeParmDecl>(Pack)) {
2401 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2402 E->getPackLoc(), TU)))
2403 return true;
2404
2405 continue;
2406 }
2407
2408 if (isa<TemplateTemplateParmDecl>(Pack)) {
2409 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2410 E->getPackLoc(), TU)))
2411 return true;
2412
2413 continue;
2414 }
2415
2416 // Non-type template parameter packs and function parameter packs are
2417 // treated like DeclRefExpr cursors.
2418 continue;
2419 }
2420
2421 case VisitorJob::LambdaExprPartsKind: {
2422 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002423 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002424 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2425 CEnd = E->explicit_capture_end();
2426 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002427 // FIXME: Lambda init-captures.
2428 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002429 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002430
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002431 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2432 C->getLocation(),
2433 TU)))
2434 return true;
2435 }
2436
2437 // Visit parameters and return type, if present.
2438 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2439 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2440 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2441 // Visit the whole type.
2442 if (Visit(TL))
2443 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002444 } else if (FunctionProtoTypeLoc Proto =
2445 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002446 if (E->hasExplicitParameters()) {
2447 // Visit parameters.
2448 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2449 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2450 return true;
2451 } else {
2452 // Visit result type.
2453 if (Visit(Proto.getResultLoc()))
2454 return true;
2455 }
2456 }
2457 }
2458 break;
2459 }
2460
2461 case VisitorJob::PostChildrenVisitKind:
2462 if (PostChildrenVisitor(Parent, ClientData))
2463 return true;
2464 break;
2465 }
2466 }
2467 return false;
2468}
2469
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002470bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002471 VisitorWorkList *WL = 0;
2472 if (!WorkListFreeList.empty()) {
2473 WL = WorkListFreeList.back();
2474 WL->clear();
2475 WorkListFreeList.pop_back();
2476 }
2477 else {
2478 WL = new VisitorWorkList();
2479 WorkListCache.push_back(WL);
2480 }
2481 EnqueueWorkList(*WL, S);
2482 bool result = RunVisitorWorkList(*WL);
2483 WorkListFreeList.push_back(WL);
2484 return result;
2485}
2486
2487namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002488typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002489RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2490 const DeclarationNameInfo &NI,
2491 const SourceRange &QLoc,
2492 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2493 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2494 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2495 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2496
2497 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2498
2499 RefNamePieces Pieces;
2500
2501 if (WantQualifier && QLoc.isValid())
2502 Pieces.push_back(QLoc);
2503
2504 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2505 Pieces.push_back(NI.getLoc());
2506
2507 if (WantTemplateArgs && TemplateArgs)
2508 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2509 TemplateArgs->RAngleLoc));
2510
2511 if (Kind == DeclarationName::CXXOperatorName) {
2512 Pieces.push_back(SourceLocation::getFromRawEncoding(
2513 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2514 Pieces.push_back(SourceLocation::getFromRawEncoding(
2515 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2516 }
2517
2518 if (WantSinglePiece) {
2519 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2520 Pieces.clear();
2521 Pieces.push_back(R);
2522 }
2523
2524 return Pieces;
2525}
2526}
2527
2528//===----------------------------------------------------------------------===//
2529// Misc. API hooks.
2530//===----------------------------------------------------------------------===//
2531
2532static llvm::sys::Mutex EnableMultithreadingMutex;
2533static bool EnabledMultithreading;
2534
Chad Rosier90836282013-03-27 18:28:23 +00002535static void fatal_error_handler(void *user_data, const std::string& reason,
2536 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002537 // Write the result out to stderr avoiding errs() because raw_ostreams can
2538 // call report_fatal_error.
2539 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2540 ::abort();
2541}
2542
2543extern "C" {
2544CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2545 int displayDiagnostics) {
2546 // Disable pretty stack trace functionality, which will otherwise be a very
2547 // poor citizen of the world and set up all sorts of signal handlers.
2548 llvm::DisablePrettyStackTrace = true;
2549
2550 // We use crash recovery to make some of our APIs more reliable, implicitly
2551 // enable it.
2552 llvm::CrashRecoveryContext::Enable();
2553
2554 // Enable support for multithreading in LLVM.
2555 {
2556 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2557 if (!EnabledMultithreading) {
2558 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2559 llvm::llvm_start_multithreaded();
2560 EnabledMultithreading = true;
2561 }
2562 }
2563
2564 CIndexer *CIdxr = new CIndexer();
2565 if (excludeDeclarationsFromPCH)
2566 CIdxr->setOnlyLocalDecls();
2567 if (displayDiagnostics)
2568 CIdxr->setDisplayDiagnostics();
2569
2570 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2571 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2572 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2573 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2574 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2575 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2576
2577 return CIdxr;
2578}
2579
2580void clang_disposeIndex(CXIndex CIdx) {
2581 if (CIdx)
2582 delete static_cast<CIndexer *>(CIdx);
2583}
2584
2585void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2586 if (CIdx)
2587 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2588}
2589
2590unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2591 if (CIdx)
2592 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2593 return 0;
2594}
2595
2596void clang_toggleCrashRecovery(unsigned isEnabled) {
2597 if (isEnabled)
2598 llvm::CrashRecoveryContext::Enable();
2599 else
2600 llvm::CrashRecoveryContext::Disable();
2601}
2602
2603CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2604 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002605 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002606 return 0;
2607
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002608 LOG_FUNC_SECTION {
2609 *Log << ast_filename;
2610 }
2611
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002612 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2613 FileSystemOptions FileSystemOpts;
2614
2615 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2616 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2617 CXXIdx->getOnlyLocalDecls(),
2618 0, 0,
2619 /*CaptureDiagnostics=*/true,
2620 /*AllowPCHWithCompilerErrors=*/true,
2621 /*UserFilesAreVolatile=*/true);
2622 return MakeCXTranslationUnit(CXXIdx, TU);
2623}
2624
2625unsigned clang_defaultEditingTranslationUnitOptions() {
2626 return CXTranslationUnit_PrecompiledPreamble |
2627 CXTranslationUnit_CacheCompletionResults;
2628}
2629
2630CXTranslationUnit
2631clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2632 const char *source_filename,
2633 int num_command_line_args,
2634 const char * const *command_line_args,
2635 unsigned num_unsaved_files,
2636 struct CXUnsavedFile *unsaved_files) {
2637 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2638 return clang_parseTranslationUnit(CIdx, source_filename,
2639 command_line_args, num_command_line_args,
2640 unsaved_files, num_unsaved_files,
2641 Options);
2642}
2643
2644struct ParseTranslationUnitInfo {
2645 CXIndex CIdx;
2646 const char *source_filename;
2647 const char *const *command_line_args;
2648 int num_command_line_args;
2649 struct CXUnsavedFile *unsaved_files;
2650 unsigned num_unsaved_files;
2651 unsigned options;
2652 CXTranslationUnit result;
2653};
2654static void clang_parseTranslationUnit_Impl(void *UserData) {
2655 ParseTranslationUnitInfo *PTUI =
2656 static_cast<ParseTranslationUnitInfo*>(UserData);
2657 CXIndex CIdx = PTUI->CIdx;
2658 const char *source_filename = PTUI->source_filename;
2659 const char * const *command_line_args = PTUI->command_line_args;
2660 int num_command_line_args = PTUI->num_command_line_args;
2661 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2662 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2663 unsigned options = PTUI->options;
2664 PTUI->result = 0;
2665
2666 if (!CIdx)
2667 return;
2668
2669 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2670
2671 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2672 setThreadBackgroundPriority();
2673
2674 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2675 // FIXME: Add a flag for modules.
2676 TranslationUnitKind TUKind
2677 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2678 bool CacheCodeCompetionResults
2679 = options & CXTranslationUnit_CacheCompletionResults;
2680 bool IncludeBriefCommentsInCodeCompletion
2681 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2682 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2683 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2684
2685 // Configure the diagnostics.
2686 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002687 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002688
2689 // Recover resources if we crash before exiting this function.
2690 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2691 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2692 DiagCleanup(Diags.getPtr());
2693
2694 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2695 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2696
2697 // Recover resources if we crash before exiting this function.
2698 llvm::CrashRecoveryContextCleanupRegistrar<
2699 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2700
2701 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2702 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2703 const llvm::MemoryBuffer *Buffer
2704 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2705 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2706 Buffer));
2707 }
2708
2709 OwningPtr<std::vector<const char *> >
2710 Args(new std::vector<const char*>());
2711
2712 // Recover resources if we crash before exiting this method.
2713 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2714 ArgsCleanup(Args.get());
2715
2716 // Since the Clang C library is primarily used by batch tools dealing with
2717 // (often very broken) source code, where spell-checking can have a
2718 // significant negative impact on performance (particularly when
2719 // precompiled headers are involved), we disable it by default.
2720 // Only do this if we haven't found a spell-checking-related argument.
2721 bool FoundSpellCheckingArgument = false;
2722 for (int I = 0; I != num_command_line_args; ++I) {
2723 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2724 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2725 FoundSpellCheckingArgument = true;
2726 break;
2727 }
2728 }
2729 if (!FoundSpellCheckingArgument)
2730 Args->push_back("-fno-spell-checking");
2731
2732 Args->insert(Args->end(), command_line_args,
2733 command_line_args + num_command_line_args);
2734
2735 // The 'source_filename' argument is optional. If the caller does not
2736 // specify it then it is assumed that the source file is specified
2737 // in the actual argument list.
2738 // Put the source file after command_line_args otherwise if '-x' flag is
2739 // present it will be unused.
2740 if (source_filename)
2741 Args->push_back(source_filename);
2742
2743 // Do we need the detailed preprocessing record?
2744 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2745 Args->push_back("-Xclang");
2746 Args->push_back("-detailed-preprocessing-record");
2747 }
2748
2749 unsigned NumErrors = Diags->getClient()->getNumErrors();
2750 OwningPtr<ASTUnit> ErrUnit;
2751 OwningPtr<ASTUnit> Unit(
2752 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2753 /* vector::data() not portable */,
2754 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2755 Diags,
2756 CXXIdx->getClangResourcesPath(),
2757 CXXIdx->getOnlyLocalDecls(),
2758 /*CaptureDiagnostics=*/true,
2759 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2760 RemappedFiles->size(),
2761 /*RemappedFilesKeepOriginalName=*/true,
2762 PrecompilePreamble,
2763 TUKind,
2764 CacheCodeCompetionResults,
2765 IncludeBriefCommentsInCodeCompletion,
2766 /*AllowPCHWithCompilerErrors=*/true,
2767 SkipFunctionBodies,
2768 /*UserFilesAreVolatile=*/true,
2769 ForSerialization,
2770 &ErrUnit));
2771
2772 if (NumErrors != Diags->getClient()->getNumErrors()) {
2773 // Make sure to check that 'Unit' is non-NULL.
2774 if (CXXIdx->getDisplayDiagnostics())
2775 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2776 }
2777
2778 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2779}
2780CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2781 const char *source_filename,
2782 const char * const *command_line_args,
2783 int num_command_line_args,
2784 struct CXUnsavedFile *unsaved_files,
2785 unsigned num_unsaved_files,
2786 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002787 LOG_FUNC_SECTION {
2788 *Log << source_filename << ": ";
2789 for (int i = 0; i != num_command_line_args; ++i)
2790 *Log << command_line_args[i] << " ";
2791 }
2792
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002793 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2794 num_command_line_args, unsaved_files,
2795 num_unsaved_files, options, 0 };
2796 llvm::CrashRecoveryContext CRC;
2797
2798 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2799 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2800 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2801 fprintf(stderr, " 'command_line_args' : [");
2802 for (int i = 0; i != num_command_line_args; ++i) {
2803 if (i)
2804 fprintf(stderr, ", ");
2805 fprintf(stderr, "'%s'", command_line_args[i]);
2806 }
2807 fprintf(stderr, "],\n");
2808 fprintf(stderr, " 'unsaved_files' : [");
2809 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2810 if (i)
2811 fprintf(stderr, ", ");
2812 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2813 unsaved_files[i].Length);
2814 }
2815 fprintf(stderr, "],\n");
2816 fprintf(stderr, " 'options' : %d,\n", options);
2817 fprintf(stderr, "}\n");
2818
2819 return 0;
2820 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2821 PrintLibclangResourceUsage(PTUI.result);
2822 }
2823
2824 return PTUI.result;
2825}
2826
2827unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2828 return CXSaveTranslationUnit_None;
2829}
2830
2831namespace {
2832
2833struct SaveTranslationUnitInfo {
2834 CXTranslationUnit TU;
2835 const char *FileName;
2836 unsigned options;
2837 CXSaveError result;
2838};
2839
2840}
2841
2842static void clang_saveTranslationUnit_Impl(void *UserData) {
2843 SaveTranslationUnitInfo *STUI =
2844 static_cast<SaveTranslationUnitInfo*>(UserData);
2845
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002846 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002847 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2848 setThreadBackgroundPriority();
2849
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002850 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002851 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2852}
2853
2854int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2855 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002856 LOG_FUNC_SECTION {
2857 *Log << TU << ' ' << FileName;
2858 }
2859
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002860 if (!TU)
2861 return CXSaveError_InvalidTU;
2862
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002863 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002864 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2865 if (!CXXUnit->hasSema())
2866 return CXSaveError_InvalidTU;
2867
2868 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2869
2870 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2871 getenv("LIBCLANG_NOTHREADS")) {
2872 clang_saveTranslationUnit_Impl(&STUI);
2873
2874 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2875 PrintLibclangResourceUsage(TU);
2876
2877 return STUI.result;
2878 }
2879
2880 // We have an AST that has invalid nodes due to compiler errors.
2881 // Use a crash recovery thread for protection.
2882
2883 llvm::CrashRecoveryContext CRC;
2884
2885 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2886 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2887 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2888 fprintf(stderr, " 'options' : %d,\n", options);
2889 fprintf(stderr, "}\n");
2890
2891 return CXSaveError_Unknown;
2892
2893 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2894 PrintLibclangResourceUsage(TU);
2895 }
2896
2897 return STUI.result;
2898}
2899
2900void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2901 if (CTUnit) {
2902 // If the translation unit has been marked as unsafe to free, just discard
2903 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002904 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002905 return;
2906
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002907 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002908 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002909 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2910 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002911 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002912 delete CTUnit;
2913 }
2914}
2915
2916unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2917 return CXReparse_None;
2918}
2919
2920struct ReparseTranslationUnitInfo {
2921 CXTranslationUnit TU;
2922 unsigned num_unsaved_files;
2923 struct CXUnsavedFile *unsaved_files;
2924 unsigned options;
2925 int result;
2926};
2927
2928static void clang_reparseTranslationUnit_Impl(void *UserData) {
2929 ReparseTranslationUnitInfo *RTUI =
2930 static_cast<ReparseTranslationUnitInfo*>(UserData);
2931 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002932 if (!TU)
2933 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002934
2935 // Reset the associated diagnostics.
2936 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2937 TU->Diagnostics = 0;
2938
2939 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2940 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2941 unsigned options = RTUI->options;
2942 (void) options;
2943 RTUI->result = 1;
2944
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002945 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002946 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2947 setThreadBackgroundPriority();
2948
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002949 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002950 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2951
2952 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2953 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2954
2955 // Recover resources if we crash before exiting this function.
2956 llvm::CrashRecoveryContextCleanupRegistrar<
2957 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2958
2959 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2960 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2961 const llvm::MemoryBuffer *Buffer
2962 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2963 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2964 Buffer));
2965 }
2966
2967 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2968 RemappedFiles->size()))
2969 RTUI->result = 0;
2970}
2971
2972int clang_reparseTranslationUnit(CXTranslationUnit TU,
2973 unsigned num_unsaved_files,
2974 struct CXUnsavedFile *unsaved_files,
2975 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002976 LOG_FUNC_SECTION {
2977 *Log << TU;
2978 }
2979
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002980 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2981 options, 0 };
2982
2983 if (getenv("LIBCLANG_NOTHREADS")) {
2984 clang_reparseTranslationUnit_Impl(&RTUI);
2985 return RTUI.result;
2986 }
2987
2988 llvm::CrashRecoveryContext CRC;
2989
2990 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2991 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002992 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002993 return 1;
2994 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2995 PrintLibclangResourceUsage(TU);
2996
2997 return RTUI.result;
2998}
2999
3000
3001CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3002 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003003 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003004
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003005 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003006 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003007}
3008
3009CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003010 if (!TU)
3011 return clang_getNullCursor();
3012
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003014 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3015}
3016
3017} // end: extern "C"
3018
3019//===----------------------------------------------------------------------===//
3020// CXFile Operations.
3021//===----------------------------------------------------------------------===//
3022
3023extern "C" {
3024CXString clang_getFileName(CXFile SFile) {
3025 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00003026 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003027
3028 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003029 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003030}
3031
3032time_t clang_getFileTime(CXFile SFile) {
3033 if (!SFile)
3034 return 0;
3035
3036 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3037 return FEnt->getModificationTime();
3038}
3039
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003040CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3041 if (!TU)
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
3046 FileManager &FMgr = CXXUnit->getFileManager();
3047 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3048}
3049
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003050unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3051 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003052 return 0;
3053
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003055 FileEntry *FEnt = static_cast<FileEntry *>(file);
3056 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3057 .isFileMultipleIncludeGuarded(FEnt);
3058}
3059
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003060int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3061 if (!file || !outID)
3062 return 1;
3063
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003064 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-08-01 21:42:11 +00003065 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3066 outID->data[0] = ID.getDevice();
3067 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003068 outID->data[2] = FEnt->getModificationTime();
3069 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003070}
3071
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003072} // end: extern "C"
3073
3074//===----------------------------------------------------------------------===//
3075// CXCursor Operations.
3076//===----------------------------------------------------------------------===//
3077
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003078static const Decl *getDeclFromExpr(const Stmt *E) {
3079 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003080 return getDeclFromExpr(CE->getSubExpr());
3081
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003082 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003083 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003084 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003085 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003086 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003087 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003088 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003089 if (PRE->isExplicitProperty())
3090 return PRE->getExplicitProperty();
3091 // It could be messaging both getter and setter as in:
3092 // ++myobj.myprop;
3093 // in which case prefer to associate the setter since it is less obvious
3094 // from inspecting the source that the setter is going to get called.
3095 if (PRE->isMessagingSetter())
3096 return PRE->getImplicitPropertySetter();
3097 return PRE->getImplicitPropertyGetter();
3098 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003099 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003100 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003101 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003102 if (Expr *Src = OVE->getSourceExpr())
3103 return getDeclFromExpr(Src);
3104
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003105 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003106 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003107 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003108 if (!CE->isElidable())
3109 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003110 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003111 return OME->getMethodDecl();
3112
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003113 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003114 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003115 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003116 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3117 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003118 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003119 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3120 isa<ParmVarDecl>(SizeOfPack->getPack()))
3121 return SizeOfPack->getPack();
3122
3123 return 0;
3124}
3125
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003126static SourceLocation getLocationFromExpr(const Expr *E) {
3127 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003128 return getLocationFromExpr(CE->getSubExpr());
3129
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003130 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003131 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003132 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003134 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003136 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003137 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003138 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003139 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003140 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003141 return PropRef->getLocation();
3142
3143 return E->getLocStart();
3144}
3145
3146extern "C" {
3147
3148unsigned clang_visitChildren(CXCursor parent,
3149 CXCursorVisitor visitor,
3150 CXClientData client_data) {
3151 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3152 /*VisitPreprocessorLast=*/false);
3153 return CursorVis.VisitChildren(parent);
3154}
3155
3156#ifndef __has_feature
3157#define __has_feature(x) 0
3158#endif
3159#if __has_feature(blocks)
3160typedef enum CXChildVisitResult
3161 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3162
3163static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3164 CXClientData client_data) {
3165 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3166 return block(cursor, parent);
3167}
3168#else
3169// If we are compiled with a compiler that doesn't have native blocks support,
3170// define and call the block manually, so the
3171typedef struct _CXChildVisitResult
3172{
3173 void *isa;
3174 int flags;
3175 int reserved;
3176 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3177 CXCursor);
3178} *CXCursorVisitorBlock;
3179
3180static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3181 CXClientData client_data) {
3182 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3183 return block->invoke(block, cursor, parent);
3184}
3185#endif
3186
3187
3188unsigned clang_visitChildrenWithBlock(CXCursor parent,
3189 CXCursorVisitorBlock block) {
3190 return clang_visitChildren(parent, visitWithBlock, block);
3191}
3192
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003193static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003194 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003195 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003196
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003197 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003198 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003199 if (const ObjCPropertyImplDecl *PropImpl =
3200 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003201 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003202 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003204 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003206 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003207
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003208 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209 }
3210
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003211 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003212 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003213
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003214 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003215 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3216 // and returns different names. NamedDecl returns the class name and
3217 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003218 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003219
3220 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003221 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003222
3223 SmallString<1024> S;
3224 llvm::raw_svector_ostream os(S);
3225 ND->printName(os);
3226
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003227 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003228}
3229
3230CXString clang_getCursorSpelling(CXCursor C) {
3231 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003232 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003233
3234 if (clang_isReference(C.kind)) {
3235 switch (C.kind) {
3236 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003237 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003238 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003239 }
3240 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003241 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003242 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003243 }
3244 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003245 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003247 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003248 }
3249 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003250 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003251 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003252 }
3253 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003254 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003255 assert(Type && "Missing type decl");
3256
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003257 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 getAsString());
3259 }
3260 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003261 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003262 assert(Template && "Missing template decl");
3263
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003264 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003265 }
3266
3267 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003268 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003269 assert(NS && "Missing namespace decl");
3270
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003271 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003272 }
3273
3274 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003275 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003276 assert(Field && "Missing member decl");
3277
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003278 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003279 }
3280
3281 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003282 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003283 assert(Label && "Missing label");
3284
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003285 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003286 }
3287
3288 case CXCursor_OverloadedDeclRef: {
3289 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003290 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3291 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003292 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003293 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003294 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003295 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003296 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003297 OverloadedTemplateStorage *Ovl
3298 = Storage.get<OverloadedTemplateStorage*>();
3299 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003300 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003301 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003302 }
3303
3304 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003305 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003306 assert(Var && "Missing variable decl");
3307
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003308 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003309 }
3310
3311 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003312 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003313 }
3314 }
3315
3316 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003317 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003318 if (D)
3319 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003320 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003321 }
3322
3323 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003324 const Stmt *S = getCursorStmt(C);
3325 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003326 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003327
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003328 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003329 }
3330
3331 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003332 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003333 ->getNameStart());
3334
3335 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003336 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003337 ->getNameStart());
3338
3339 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003340 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003341
3342 if (clang_isDeclaration(C.kind))
3343 return getDeclSpelling(getCursorDecl(C));
3344
3345 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003346 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003347 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003348 }
3349
3350 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003351 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003352 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003353 }
3354
Argyrios Kyrtzidis51337112013-09-25 00:14:38 +00003355 if (C.kind == CXCursor_PackedAttr) {
3356 return cxstring::createRef("packed");
3357 }
3358
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003359 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003360}
3361
3362CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3363 unsigned pieceIndex,
3364 unsigned options) {
3365 if (clang_Cursor_isNull(C))
3366 return clang_getNullRange();
3367
3368 ASTContext &Ctx = getCursorContext(C);
3369
3370 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003371 const Stmt *S = getCursorStmt(C);
3372 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003373 if (pieceIndex > 0)
3374 return clang_getNullRange();
3375 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3376 }
3377
3378 return clang_getNullRange();
3379 }
3380
3381 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003382 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003383 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3384 if (pieceIndex >= ME->getNumSelectorLocs())
3385 return clang_getNullRange();
3386 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3387 }
3388 }
3389
3390 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3391 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003392 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003393 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3394 if (pieceIndex >= MD->getNumSelectorLocs())
3395 return clang_getNullRange();
3396 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3397 }
3398 }
3399
3400 if (C.kind == CXCursor_ObjCCategoryDecl ||
3401 C.kind == CXCursor_ObjCCategoryImplDecl) {
3402 if (pieceIndex > 0)
3403 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003404 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003405 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3406 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003407 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003408 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3409 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3410 }
3411
3412 if (C.kind == CXCursor_ModuleImportDecl) {
3413 if (pieceIndex > 0)
3414 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003415 if (const ImportDecl *ImportD =
3416 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003417 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3418 if (!Locs.empty())
3419 return cxloc::translateSourceRange(Ctx,
3420 SourceRange(Locs.front(), Locs.back()));
3421 }
3422 return clang_getNullRange();
3423 }
3424
3425 // FIXME: A CXCursor_InclusionDirective should give the location of the
3426 // filename, but we don't keep track of this.
3427
3428 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3429 // but we don't keep track of this.
3430
3431 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3432 // but we don't keep track of this.
3433
3434 // Default handling, give the location of the cursor.
3435
3436 if (pieceIndex > 0)
3437 return clang_getNullRange();
3438
3439 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3440 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3441 return cxloc::translateSourceRange(Ctx, Loc);
3442}
3443
3444CXString clang_getCursorDisplayName(CXCursor C) {
3445 if (!clang_isDeclaration(C.kind))
3446 return clang_getCursorSpelling(C);
3447
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003448 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003449 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003450 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451
3452 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003453 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003454 D = FunTmpl->getTemplatedDecl();
3455
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003456 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003457 SmallString<64> Str;
3458 llvm::raw_svector_ostream OS(Str);
3459 OS << *Function;
3460 if (Function->getPrimaryTemplate())
3461 OS << "<>";
3462 OS << "(";
3463 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3464 if (I)
3465 OS << ", ";
3466 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3467 }
3468
3469 if (Function->isVariadic()) {
3470 if (Function->getNumParams())
3471 OS << ", ";
3472 OS << "...";
3473 }
3474 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003475 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003476 }
3477
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003478 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 SmallString<64> Str;
3480 llvm::raw_svector_ostream OS(Str);
3481 OS << *ClassTemplate;
3482 OS << "<";
3483 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3484 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3485 if (I)
3486 OS << ", ";
3487
3488 NamedDecl *Param = Params->getParam(I);
3489 if (Param->getIdentifier()) {
3490 OS << Param->getIdentifier()->getName();
3491 continue;
3492 }
3493
3494 // There is no parameter name, which makes this tricky. Try to come up
3495 // with something useful that isn't too long.
3496 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3497 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3498 else if (NonTypeTemplateParmDecl *NTTP
3499 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3500 OS << NTTP->getType().getAsString(Policy);
3501 else
3502 OS << "template<...> class";
3503 }
3504
3505 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003506 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 }
3508
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003509 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3511 // If the type was explicitly written, use that.
3512 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003513 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003514
Benjamin Kramer5eada842013-02-22 15:46:01 +00003515 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003516 llvm::raw_svector_ostream OS(Str);
3517 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003518 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 ClassSpec->getTemplateArgs().data(),
3520 ClassSpec->getTemplateArgs().size(),
3521 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003522 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 }
3524
3525 return clang_getCursorSpelling(C);
3526}
3527
3528CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3529 switch (Kind) {
3530 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003652 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003653 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003658 case CXCursor_ObjCSelfExpr:
3659 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003740 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003742 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003743 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003744 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003745 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003746 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003747 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003748 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003749 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003750 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003751 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003752 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003753 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003754 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003755 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003756 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003757 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003758 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003759 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003760 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003761 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003762 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003763 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003764 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003765 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003766 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003767 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003768 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003769 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003770 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003771 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003772 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003773 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003774 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003775 return cxstring::createRef("asm label");
Argyrios Kyrtzidis51337112013-09-25 00:14:38 +00003776 case CXCursor_PackedAttr:
3777 return cxstring::createRef("attribute(packed)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003778 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003779 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003780 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003781 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003782 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003783 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003784 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003785 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003786 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003787 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003788 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003789 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003790 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003791 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003792 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003794 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003797 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003798 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003799 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003801 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003802 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003803 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003804 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003805 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003806 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003807 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003808 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003809 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003810 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003811 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003812 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003813 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003814 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003815 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003816 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003817 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003818 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003820 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003822 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003823 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003824 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003825 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003826 case CXCursor_OMPParallelDirective:
3827 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003828 }
3829
3830 llvm_unreachable("Unhandled CXCursorKind");
3831}
3832
3833struct GetCursorData {
3834 SourceLocation TokenBeginLoc;
3835 bool PointsAtMacroArgExpansion;
3836 bool VisitedObjCPropertyImplDecl;
3837 SourceLocation VisitedDeclaratorDeclStartLoc;
3838 CXCursor &BestCursor;
3839
3840 GetCursorData(SourceManager &SM,
3841 SourceLocation tokenBegin, CXCursor &outputCursor)
3842 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3843 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3844 VisitedObjCPropertyImplDecl = false;
3845 }
3846};
3847
3848static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3849 CXCursor parent,
3850 CXClientData client_data) {
3851 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3852 CXCursor *BestCursor = &Data->BestCursor;
3853
3854 // If we point inside a macro argument we should provide info of what the
3855 // token is so use the actual cursor, don't replace it with a macro expansion
3856 // cursor.
3857 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3858 return CXChildVisit_Recurse;
3859
3860 if (clang_isDeclaration(cursor.kind)) {
3861 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003862 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003863 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3864 if (MD->isImplicit())
3865 return CXChildVisit_Break;
3866
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003867 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003868 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3869 // Check that when we have multiple @class references in the same line,
3870 // that later ones do not override the previous ones.
3871 // If we have:
3872 // @class Foo, Bar;
3873 // source ranges for both start at '@', so 'Bar' will end up overriding
3874 // 'Foo' even though the cursor location was at 'Foo'.
3875 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3876 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003877 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003878 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3879 if (PrevID != ID &&
3880 !PrevID->isThisDeclarationADefinition() &&
3881 !ID->isThisDeclarationADefinition())
3882 return CXChildVisit_Break;
3883 }
3884
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003885 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003886 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3887 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3888 // Check that when we have multiple declarators in the same line,
3889 // that later ones do not override the previous ones.
3890 // If we have:
3891 // int Foo, Bar;
3892 // source ranges for both start at 'int', so 'Bar' will end up overriding
3893 // 'Foo' even though the cursor location was at 'Foo'.
3894 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3895 return CXChildVisit_Break;
3896 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3897
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003898 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003899 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3900 (void)PropImp;
3901 // Check that when we have multiple @synthesize in the same line,
3902 // that later ones do not override the previous ones.
3903 // If we have:
3904 // @synthesize Foo, Bar;
3905 // source ranges for both start at '@', so 'Bar' will end up overriding
3906 // 'Foo' even though the cursor location was at 'Foo'.
3907 if (Data->VisitedObjCPropertyImplDecl)
3908 return CXChildVisit_Break;
3909 Data->VisitedObjCPropertyImplDecl = true;
3910 }
3911 }
3912
3913 if (clang_isExpression(cursor.kind) &&
3914 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003915 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003916 // Avoid having the cursor of an expression replace the declaration cursor
3917 // when the expression source range overlaps the declaration range.
3918 // This can happen for C++ constructor expressions whose range generally
3919 // include the variable declaration, e.g.:
3920 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3921 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3922 D->getLocation() == Data->TokenBeginLoc)
3923 return CXChildVisit_Break;
3924 }
3925 }
3926
3927 // If our current best cursor is the construction of a temporary object,
3928 // don't replace that cursor with a type reference, because we want
3929 // clang_getCursor() to point at the constructor.
3930 if (clang_isExpression(BestCursor->kind) &&
3931 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3932 cursor.kind == CXCursor_TypeRef) {
3933 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3934 // as having the actual point on the type reference.
3935 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3936 return CXChildVisit_Recurse;
3937 }
3938
3939 *BestCursor = cursor;
3940 return CXChildVisit_Recurse;
3941}
3942
3943CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3944 if (!TU)
3945 return clang_getNullCursor();
3946
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003947 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003948 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3949
3950 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3951 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3952
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003953 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003954 CXFile SearchFile;
3955 unsigned SearchLine, SearchColumn;
3956 CXFile ResultFile;
3957 unsigned ResultLine, ResultColumn;
3958 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3959 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3960 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3961
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003962 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3963 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003964 &ResultColumn, 0);
3965 SearchFileName = clang_getFileName(SearchFile);
3966 ResultFileName = clang_getFileName(ResultFile);
3967 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3968 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003969 *Log << llvm::format("(%s:%d:%d) = %s",
3970 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3971 clang_getCString(KindSpelling))
3972 << llvm::format("(%s:%d:%d):%s%s",
3973 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3974 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003975 clang_disposeString(SearchFileName);
3976 clang_disposeString(ResultFileName);
3977 clang_disposeString(KindSpelling);
3978 clang_disposeString(USR);
3979
3980 CXCursor Definition = clang_getCursorDefinition(Result);
3981 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3982 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3983 CXString DefinitionKindSpelling
3984 = clang_getCursorKindSpelling(Definition.kind);
3985 CXFile DefinitionFile;
3986 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003987 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003988 &DefinitionLine, &DefinitionColumn, 0);
3989 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003990 *Log << llvm::format(" -> %s(%s:%d:%d)",
3991 clang_getCString(DefinitionKindSpelling),
3992 clang_getCString(DefinitionFileName),
3993 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003994 clang_disposeString(DefinitionFileName);
3995 clang_disposeString(DefinitionKindSpelling);
3996 }
3997 }
3998
3999 return Result;
4000}
4001
4002CXCursor clang_getNullCursor(void) {
4003 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4004}
4005
4006unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00004007 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4008 // can't set consistently. For example, when visiting a DeclStmt we will set
4009 // it but we don't set it on the result of clang_getCursorDefinition for
4010 // a reference of the same declaration.
4011 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4012 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4013 // to provide that kind of info.
4014 if (clang_isDeclaration(X.kind))
4015 X.data[1] = 0;
4016 if (clang_isDeclaration(Y.kind))
4017 Y.data[1] = 0;
4018
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004019 return X == Y;
4020}
4021
4022unsigned clang_hashCursor(CXCursor C) {
4023 unsigned Index = 0;
4024 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4025 Index = 1;
4026
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004027 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004028 std::make_pair(C.kind, C.data[Index]));
4029}
4030
4031unsigned clang_isInvalid(enum CXCursorKind K) {
4032 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4033}
4034
4035unsigned clang_isDeclaration(enum CXCursorKind K) {
4036 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4037 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4038}
4039
4040unsigned clang_isReference(enum CXCursorKind K) {
4041 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4042}
4043
4044unsigned clang_isExpression(enum CXCursorKind K) {
4045 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4046}
4047
4048unsigned clang_isStatement(enum CXCursorKind K) {
4049 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4050}
4051
4052unsigned clang_isAttribute(enum CXCursorKind K) {
4053 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4054}
4055
4056unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4057 return K == CXCursor_TranslationUnit;
4058}
4059
4060unsigned clang_isPreprocessing(enum CXCursorKind K) {
4061 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4062}
4063
4064unsigned clang_isUnexposed(enum CXCursorKind K) {
4065 switch (K) {
4066 case CXCursor_UnexposedDecl:
4067 case CXCursor_UnexposedExpr:
4068 case CXCursor_UnexposedStmt:
4069 case CXCursor_UnexposedAttr:
4070 return true;
4071 default:
4072 return false;
4073 }
4074}
4075
4076CXCursorKind clang_getCursorKind(CXCursor C) {
4077 return C.kind;
4078}
4079
4080CXSourceLocation clang_getCursorLocation(CXCursor C) {
4081 if (clang_isReference(C.kind)) {
4082 switch (C.kind) {
4083 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004084 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004085 = getCursorObjCSuperClassRef(C);
4086 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4087 }
4088
4089 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004090 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004091 = getCursorObjCProtocolRef(C);
4092 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4093 }
4094
4095 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004096 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004097 = getCursorObjCClassRef(C);
4098 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4099 }
4100
4101 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004102 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004103 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4104 }
4105
4106 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004107 std::pair<const TemplateDecl *, SourceLocation> P =
4108 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4110 }
4111
4112 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004113 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4115 }
4116
4117 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004118 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004119 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4120 }
4121
4122 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004123 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004124 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4125 }
4126
4127 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004128 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004129 if (!BaseSpec)
4130 return clang_getNullLocation();
4131
4132 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4133 return cxloc::translateSourceLocation(getCursorContext(C),
4134 TSInfo->getTypeLoc().getBeginLoc());
4135
4136 return cxloc::translateSourceLocation(getCursorContext(C),
4137 BaseSpec->getLocStart());
4138 }
4139
4140 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004141 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004142 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4143 }
4144
4145 case CXCursor_OverloadedDeclRef:
4146 return cxloc::translateSourceLocation(getCursorContext(C),
4147 getCursorOverloadedDeclRef(C).second);
4148
4149 default:
4150 // FIXME: Need a way to enumerate all non-reference cases.
4151 llvm_unreachable("Missed a reference kind");
4152 }
4153 }
4154
4155 if (clang_isExpression(C.kind))
4156 return cxloc::translateSourceLocation(getCursorContext(C),
4157 getLocationFromExpr(getCursorExpr(C)));
4158
4159 if (clang_isStatement(C.kind))
4160 return cxloc::translateSourceLocation(getCursorContext(C),
4161 getCursorStmt(C)->getLocStart());
4162
4163 if (C.kind == CXCursor_PreprocessingDirective) {
4164 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4165 return cxloc::translateSourceLocation(getCursorContext(C), L);
4166 }
4167
4168 if (C.kind == CXCursor_MacroExpansion) {
4169 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004170 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004171 return cxloc::translateSourceLocation(getCursorContext(C), L);
4172 }
4173
4174 if (C.kind == CXCursor_MacroDefinition) {
4175 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4176 return cxloc::translateSourceLocation(getCursorContext(C), L);
4177 }
4178
4179 if (C.kind == CXCursor_InclusionDirective) {
4180 SourceLocation L
4181 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4182 return cxloc::translateSourceLocation(getCursorContext(C), L);
4183 }
4184
Argyrios Kyrtzidis51337112013-09-25 00:14:38 +00004185 if (clang_isAttribute(C.kind)) {
4186 SourceLocation L
4187 = cxcursor::getCursorAttr(C)->getLocation();
4188 return cxloc::translateSourceLocation(getCursorContext(C), L);
4189 }
4190
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004191 if (!clang_isDeclaration(C.kind))
4192 return clang_getNullLocation();
4193
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004194 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004195 if (!D)
4196 return clang_getNullLocation();
4197
4198 SourceLocation Loc = D->getLocation();
4199 // FIXME: Multiple variables declared in a single declaration
4200 // currently lack the information needed to correctly determine their
4201 // ranges when accounting for the type-specifier. We use context
4202 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4203 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004204 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004205 if (!cxcursor::isFirstInDeclGroup(C))
4206 Loc = VD->getLocation();
4207 }
4208
4209 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004210 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004211 Loc = MD->getSelectorStartLoc();
4212
4213 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4214}
4215
4216} // end extern "C"
4217
4218CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4219 assert(TU);
4220
4221 // Guard against an invalid SourceLocation, or we may assert in one
4222 // of the following calls.
4223 if (SLoc.isInvalid())
4224 return clang_getNullCursor();
4225
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004226 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004227
4228 // Translate the given source location to make it point at the beginning of
4229 // the token under the cursor.
4230 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4231 CXXUnit->getASTContext().getLangOpts());
4232
4233 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4234 if (SLoc.isValid()) {
4235 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4236 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4237 /*VisitPreprocessorLast=*/true,
4238 /*VisitIncludedEntities=*/false,
4239 SourceLocation(SLoc));
4240 CursorVis.visitFileRegion();
4241 }
4242
4243 return Result;
4244}
4245
4246static SourceRange getRawCursorExtent(CXCursor C) {
4247 if (clang_isReference(C.kind)) {
4248 switch (C.kind) {
4249 case CXCursor_ObjCSuperClassRef:
4250 return getCursorObjCSuperClassRef(C).second;
4251
4252 case CXCursor_ObjCProtocolRef:
4253 return getCursorObjCProtocolRef(C).second;
4254
4255 case CXCursor_ObjCClassRef:
4256 return getCursorObjCClassRef(C).second;
4257
4258 case CXCursor_TypeRef:
4259 return getCursorTypeRef(C).second;
4260
4261 case CXCursor_TemplateRef:
4262 return getCursorTemplateRef(C).second;
4263
4264 case CXCursor_NamespaceRef:
4265 return getCursorNamespaceRef(C).second;
4266
4267 case CXCursor_MemberRef:
4268 return getCursorMemberRef(C).second;
4269
4270 case CXCursor_CXXBaseSpecifier:
4271 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4272
4273 case CXCursor_LabelRef:
4274 return getCursorLabelRef(C).second;
4275
4276 case CXCursor_OverloadedDeclRef:
4277 return getCursorOverloadedDeclRef(C).second;
4278
4279 case CXCursor_VariableRef:
4280 return getCursorVariableRef(C).second;
4281
4282 default:
4283 // FIXME: Need a way to enumerate all non-reference cases.
4284 llvm_unreachable("Missed a reference kind");
4285 }
4286 }
4287
4288 if (clang_isExpression(C.kind))
4289 return getCursorExpr(C)->getSourceRange();
4290
4291 if (clang_isStatement(C.kind))
4292 return getCursorStmt(C)->getSourceRange();
4293
4294 if (clang_isAttribute(C.kind))
4295 return getCursorAttr(C)->getRange();
4296
4297 if (C.kind == CXCursor_PreprocessingDirective)
4298 return cxcursor::getCursorPreprocessingDirective(C);
4299
4300 if (C.kind == CXCursor_MacroExpansion) {
4301 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004302 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004303 return TU->mapRangeFromPreamble(Range);
4304 }
4305
4306 if (C.kind == CXCursor_MacroDefinition) {
4307 ASTUnit *TU = getCursorASTUnit(C);
4308 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4309 return TU->mapRangeFromPreamble(Range);
4310 }
4311
4312 if (C.kind == CXCursor_InclusionDirective) {
4313 ASTUnit *TU = getCursorASTUnit(C);
4314 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4315 return TU->mapRangeFromPreamble(Range);
4316 }
4317
4318 if (C.kind == CXCursor_TranslationUnit) {
4319 ASTUnit *TU = getCursorASTUnit(C);
4320 FileID MainID = TU->getSourceManager().getMainFileID();
4321 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4322 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4323 return SourceRange(Start, End);
4324 }
4325
4326 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004327 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004328 if (!D)
4329 return SourceRange();
4330
4331 SourceRange R = D->getSourceRange();
4332 // FIXME: Multiple variables declared in a single declaration
4333 // currently lack the information needed to correctly determine their
4334 // ranges when accounting for the type-specifier. We use context
4335 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4336 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004337 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004338 if (!cxcursor::isFirstInDeclGroup(C))
4339 R.setBegin(VD->getLocation());
4340 }
4341 return R;
4342 }
4343 return SourceRange();
4344}
4345
4346/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4347/// the decl-specifier-seq for declarations.
4348static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4349 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004350 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004351 if (!D)
4352 return SourceRange();
4353
4354 SourceRange R = D->getSourceRange();
4355
4356 // Adjust the start of the location for declarations preceded by
4357 // declaration specifiers.
4358 SourceLocation StartLoc;
4359 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4360 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4361 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004362 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004363 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4364 StartLoc = TI->getTypeLoc().getLocStart();
4365 }
4366
4367 if (StartLoc.isValid() && R.getBegin().isValid() &&
4368 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4369 R.setBegin(StartLoc);
4370
4371 // FIXME: Multiple variables declared in a single declaration
4372 // currently lack the information needed to correctly determine their
4373 // ranges when accounting for the type-specifier. We use context
4374 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4375 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004376 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004377 if (!cxcursor::isFirstInDeclGroup(C))
4378 R.setBegin(VD->getLocation());
4379 }
4380
4381 return R;
4382 }
4383
4384 return getRawCursorExtent(C);
4385}
4386
4387extern "C" {
4388
4389CXSourceRange clang_getCursorExtent(CXCursor C) {
4390 SourceRange R = getRawCursorExtent(C);
4391 if (R.isInvalid())
4392 return clang_getNullRange();
4393
4394 return cxloc::translateSourceRange(getCursorContext(C), R);
4395}
4396
4397CXCursor clang_getCursorReferenced(CXCursor C) {
4398 if (clang_isInvalid(C.kind))
4399 return clang_getNullCursor();
4400
4401 CXTranslationUnit tu = getCursorTU(C);
4402 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004403 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004404 if (!D)
4405 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004406 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004407 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004408 if (const ObjCPropertyImplDecl *PropImpl =
4409 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004410 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4411 return MakeCXCursor(Property, tu);
4412
4413 return C;
4414 }
4415
4416 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004417 const Expr *E = getCursorExpr(C);
4418 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004419 if (D) {
4420 CXCursor declCursor = MakeCXCursor(D, tu);
4421 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4422 declCursor);
4423 return declCursor;
4424 }
4425
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004426 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004427 return MakeCursorOverloadedDeclRef(Ovl, tu);
4428
4429 return clang_getNullCursor();
4430 }
4431
4432 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004433 const Stmt *S = getCursorStmt(C);
4434 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004435 if (LabelDecl *label = Goto->getLabel())
4436 if (LabelStmt *labelS = label->getStmt())
4437 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4438
4439 return clang_getNullCursor();
4440 }
4441
4442 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004443 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004444 return MakeMacroDefinitionCursor(Def, tu);
4445 }
4446
4447 if (!clang_isReference(C.kind))
4448 return clang_getNullCursor();
4449
4450 switch (C.kind) {
4451 case CXCursor_ObjCSuperClassRef:
4452 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4453
4454 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004455 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4456 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004457 return MakeCXCursor(Def, tu);
4458
4459 return MakeCXCursor(Prot, tu);
4460 }
4461
4462 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004463 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4464 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004465 return MakeCXCursor(Def, tu);
4466
4467 return MakeCXCursor(Class, tu);
4468 }
4469
4470 case CXCursor_TypeRef:
4471 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4472
4473 case CXCursor_TemplateRef:
4474 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4475
4476 case CXCursor_NamespaceRef:
4477 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4478
4479 case CXCursor_MemberRef:
4480 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4481
4482 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004483 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004484 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4485 tu ));
4486 }
4487
4488 case CXCursor_LabelRef:
4489 // FIXME: We end up faking the "parent" declaration here because we
4490 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004491 return MakeCXCursor(getCursorLabelRef(C).first,
4492 cxtu::getASTUnit(tu)->getASTContext()
4493 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004494 tu);
4495
4496 case CXCursor_OverloadedDeclRef:
4497 return C;
4498
4499 case CXCursor_VariableRef:
4500 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4501
4502 default:
4503 // We would prefer to enumerate all non-reference cursor kinds here.
4504 llvm_unreachable("Unhandled reference cursor kind");
4505 }
4506}
4507
4508CXCursor clang_getCursorDefinition(CXCursor C) {
4509 if (clang_isInvalid(C.kind))
4510 return clang_getNullCursor();
4511
4512 CXTranslationUnit TU = getCursorTU(C);
4513
4514 bool WasReference = false;
4515 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4516 C = clang_getCursorReferenced(C);
4517 WasReference = true;
4518 }
4519
4520 if (C.kind == CXCursor_MacroExpansion)
4521 return clang_getCursorReferenced(C);
4522
4523 if (!clang_isDeclaration(C.kind))
4524 return clang_getNullCursor();
4525
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004526 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004527 if (!D)
4528 return clang_getNullCursor();
4529
4530 switch (D->getKind()) {
4531 // Declaration kinds that don't really separate the notions of
4532 // declaration and definition.
4533 case Decl::Namespace:
4534 case Decl::Typedef:
4535 case Decl::TypeAlias:
4536 case Decl::TypeAliasTemplate:
4537 case Decl::TemplateTypeParm:
4538 case Decl::EnumConstant:
4539 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004540 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004541 case Decl::IndirectField:
4542 case Decl::ObjCIvar:
4543 case Decl::ObjCAtDefsField:
4544 case Decl::ImplicitParam:
4545 case Decl::ParmVar:
4546 case Decl::NonTypeTemplateParm:
4547 case Decl::TemplateTemplateParm:
4548 case Decl::ObjCCategoryImpl:
4549 case Decl::ObjCImplementation:
4550 case Decl::AccessSpec:
4551 case Decl::LinkageSpec:
4552 case Decl::ObjCPropertyImpl:
4553 case Decl::FileScopeAsm:
4554 case Decl::StaticAssert:
4555 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004556 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004557 case Decl::Label: // FIXME: Is this right??
4558 case Decl::ClassScopeFunctionSpecialization:
4559 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004560 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004561 return C;
4562
4563 // Declaration kinds that don't make any sense here, but are
4564 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004565 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004566 case Decl::TranslationUnit:
4567 break;
4568
4569 // Declaration kinds for which the definition is not resolvable.
4570 case Decl::UnresolvedUsingTypename:
4571 case Decl::UnresolvedUsingValue:
4572 break;
4573
4574 case Decl::UsingDirective:
4575 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4576 TU);
4577
4578 case Decl::NamespaceAlias:
4579 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4580
4581 case Decl::Enum:
4582 case Decl::Record:
4583 case Decl::CXXRecord:
4584 case Decl::ClassTemplateSpecialization:
4585 case Decl::ClassTemplatePartialSpecialization:
4586 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4587 return MakeCXCursor(Def, TU);
4588 return clang_getNullCursor();
4589
4590 case Decl::Function:
4591 case Decl::CXXMethod:
4592 case Decl::CXXConstructor:
4593 case Decl::CXXDestructor:
4594 case Decl::CXXConversion: {
4595 const FunctionDecl *Def = 0;
4596 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004597 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004598 return clang_getNullCursor();
4599 }
4600
Larisse Voufoef4579c2013-08-06 01:03:05 +00004601 case Decl::Var:
4602 case Decl::VarTemplateSpecialization:
4603 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004604 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004605 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004606 return MakeCXCursor(Def, TU);
4607 return clang_getNullCursor();
4608 }
4609
4610 case Decl::FunctionTemplate: {
4611 const FunctionDecl *Def = 0;
4612 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4613 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4614 return clang_getNullCursor();
4615 }
4616
4617 case Decl::ClassTemplate: {
4618 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4619 ->getDefinition())
4620 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4621 TU);
4622 return clang_getNullCursor();
4623 }
4624
Larisse Voufoef4579c2013-08-06 01:03:05 +00004625 case Decl::VarTemplate: {
4626 if (VarDecl *Def =
4627 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4628 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4629 return clang_getNullCursor();
4630 }
4631
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004632 case Decl::Using:
4633 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4634 D->getLocation(), TU);
4635
4636 case Decl::UsingShadow:
4637 return clang_getCursorDefinition(
4638 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4639 TU));
4640
4641 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004642 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004643 if (Method->isThisDeclarationADefinition())
4644 return C;
4645
4646 // Dig out the method definition in the associated
4647 // @implementation, if we have it.
4648 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004649 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004650 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4651 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4652 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4653 Method->isInstanceMethod()))
4654 if (Def->isThisDeclarationADefinition())
4655 return MakeCXCursor(Def, TU);
4656
4657 return clang_getNullCursor();
4658 }
4659
4660 case Decl::ObjCCategory:
4661 if (ObjCCategoryImplDecl *Impl
4662 = cast<ObjCCategoryDecl>(D)->getImplementation())
4663 return MakeCXCursor(Impl, TU);
4664 return clang_getNullCursor();
4665
4666 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004667 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004668 return MakeCXCursor(Def, TU);
4669 return clang_getNullCursor();
4670
4671 case Decl::ObjCInterface: {
4672 // There are two notions of a "definition" for an Objective-C
4673 // class: the interface and its implementation. When we resolved a
4674 // reference to an Objective-C class, produce the @interface as
4675 // the definition; when we were provided with the interface,
4676 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004677 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004678 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004679 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004680 return MakeCXCursor(Def, TU);
4681 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4682 return MakeCXCursor(Impl, TU);
4683 return clang_getNullCursor();
4684 }
4685
4686 case Decl::ObjCProperty:
4687 // FIXME: We don't really know where to find the
4688 // ObjCPropertyImplDecls that implement this property.
4689 return clang_getNullCursor();
4690
4691 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004692 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004693 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004694 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004695 return MakeCXCursor(Def, TU);
4696
4697 return clang_getNullCursor();
4698
4699 case Decl::Friend:
4700 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4701 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4702 return clang_getNullCursor();
4703
4704 case Decl::FriendTemplate:
4705 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4706 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4707 return clang_getNullCursor();
4708 }
4709
4710 return clang_getNullCursor();
4711}
4712
4713unsigned clang_isCursorDefinition(CXCursor C) {
4714 if (!clang_isDeclaration(C.kind))
4715 return 0;
4716
4717 return clang_getCursorDefinition(C) == C;
4718}
4719
4720CXCursor clang_getCanonicalCursor(CXCursor C) {
4721 if (!clang_isDeclaration(C.kind))
4722 return C;
4723
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004724 if (const Decl *D = getCursorDecl(C)) {
4725 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004726 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4727 return MakeCXCursor(CatD, getCursorTU(C));
4728
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004729 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4730 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004731 return MakeCXCursor(IFD, getCursorTU(C));
4732
4733 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4734 }
4735
4736 return C;
4737}
4738
4739int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4740 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4741}
4742
4743unsigned clang_getNumOverloadedDecls(CXCursor C) {
4744 if (C.kind != CXCursor_OverloadedDeclRef)
4745 return 0;
4746
4747 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004748 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004749 return E->getNumDecls();
4750
4751 if (OverloadedTemplateStorage *S
4752 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4753 return S->size();
4754
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004755 const Decl *D = Storage.get<const Decl *>();
4756 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004757 return Using->shadow_size();
4758
4759 return 0;
4760}
4761
4762CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4763 if (cursor.kind != CXCursor_OverloadedDeclRef)
4764 return clang_getNullCursor();
4765
4766 if (index >= clang_getNumOverloadedDecls(cursor))
4767 return clang_getNullCursor();
4768
4769 CXTranslationUnit TU = getCursorTU(cursor);
4770 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004771 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004772 return MakeCXCursor(E->decls_begin()[index], TU);
4773
4774 if (OverloadedTemplateStorage *S
4775 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4776 return MakeCXCursor(S->begin()[index], TU);
4777
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004778 const Decl *D = Storage.get<const Decl *>();
4779 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004780 // FIXME: This is, unfortunately, linear time.
4781 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4782 std::advance(Pos, index);
4783 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4784 }
4785
4786 return clang_getNullCursor();
4787}
4788
4789void clang_getDefinitionSpellingAndExtent(CXCursor C,
4790 const char **startBuf,
4791 const char **endBuf,
4792 unsigned *startLine,
4793 unsigned *startColumn,
4794 unsigned *endLine,
4795 unsigned *endColumn) {
4796 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004797 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004798 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4799
4800 SourceManager &SM = FD->getASTContext().getSourceManager();
4801 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4802 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4803 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4804 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4805 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4806 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4807}
4808
4809
4810CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4811 unsigned PieceIndex) {
4812 RefNamePieces Pieces;
4813
4814 switch (C.kind) {
4815 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004816 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004817 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4818 E->getQualifierLoc().getSourceRange());
4819 break;
4820
4821 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004822 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004823 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4824 E->getQualifierLoc().getSourceRange(),
4825 E->getOptionalExplicitTemplateArgs());
4826 break;
4827
4828 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004829 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004830 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004831 const Expr *Callee = OCE->getCallee();
4832 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004833 Callee = ICE->getSubExpr();
4834
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004835 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004836 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4837 DRE->getQualifierLoc().getSourceRange());
4838 }
4839 break;
4840
4841 default:
4842 break;
4843 }
4844
4845 if (Pieces.empty()) {
4846 if (PieceIndex == 0)
4847 return clang_getCursorExtent(C);
4848 } else if (PieceIndex < Pieces.size()) {
4849 SourceRange R = Pieces[PieceIndex];
4850 if (R.isValid())
4851 return cxloc::translateSourceRange(getCursorContext(C), R);
4852 }
4853
4854 return clang_getNullRange();
4855}
4856
4857void clang_enableStackTraces(void) {
4858 llvm::sys::PrintStackTraceOnErrorSignal();
4859}
4860
4861void clang_executeOnThread(void (*fn)(void*), void *user_data,
4862 unsigned stack_size) {
4863 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4864}
4865
4866} // end: extern "C"
4867
4868//===----------------------------------------------------------------------===//
4869// Token-based Operations.
4870//===----------------------------------------------------------------------===//
4871
4872/* CXToken layout:
4873 * int_data[0]: a CXTokenKind
4874 * int_data[1]: starting token location
4875 * int_data[2]: token length
4876 * int_data[3]: reserved
4877 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4878 * otherwise unused.
4879 */
4880extern "C" {
4881
4882CXTokenKind clang_getTokenKind(CXToken CXTok) {
4883 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4884}
4885
4886CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4887 switch (clang_getTokenKind(CXTok)) {
4888 case CXToken_Identifier:
4889 case CXToken_Keyword:
4890 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004891 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004892 ->getNameStart());
4893
4894 case CXToken_Literal: {
4895 // We have stashed the starting pointer in the ptr_data field. Use it.
4896 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004897 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004898 }
4899
4900 case CXToken_Punctuation:
4901 case CXToken_Comment:
4902 break;
4903 }
4904
4905 // We have to find the starting buffer pointer the hard way, by
4906 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004907 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004908 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004909 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004910
4911 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4912 std::pair<FileID, unsigned> LocInfo
4913 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4914 bool Invalid = false;
4915 StringRef Buffer
4916 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4917 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004918 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004919
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004920 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004921}
4922
4923CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004925 if (!CXXUnit)
4926 return clang_getNullLocation();
4927
4928 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4929 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4930}
4931
4932CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004933 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004934 if (!CXXUnit)
4935 return clang_getNullRange();
4936
4937 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4938 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4939}
4940
4941static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4942 SmallVectorImpl<CXToken> &CXTokens) {
4943 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4944 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004945 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004946 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004947 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004948
4949 // Cannot tokenize across files.
4950 if (BeginLocInfo.first != EndLocInfo.first)
4951 return;
4952
4953 // Create a lexer
4954 bool Invalid = false;
4955 StringRef Buffer
4956 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4957 if (Invalid)
4958 return;
4959
4960 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4961 CXXUnit->getASTContext().getLangOpts(),
4962 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4963 Lex.SetCommentRetentionState(true);
4964
4965 // Lex tokens until we hit the end of the range.
4966 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4967 Token Tok;
4968 bool previousWasAt = false;
4969 do {
4970 // Lex the next token
4971 Lex.LexFromRawLexer(Tok);
4972 if (Tok.is(tok::eof))
4973 break;
4974
4975 // Initialize the CXToken.
4976 CXToken CXTok;
4977
4978 // - Common fields
4979 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4980 CXTok.int_data[2] = Tok.getLength();
4981 CXTok.int_data[3] = 0;
4982
4983 // - Kind-specific fields
4984 if (Tok.isLiteral()) {
4985 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004986 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004987 } else if (Tok.is(tok::raw_identifier)) {
4988 // Lookup the identifier to determine whether we have a keyword.
4989 IdentifierInfo *II
4990 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4991
4992 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4993 CXTok.int_data[0] = CXToken_Keyword;
4994 }
4995 else {
4996 CXTok.int_data[0] = Tok.is(tok::identifier)
4997 ? CXToken_Identifier
4998 : CXToken_Keyword;
4999 }
5000 CXTok.ptr_data = II;
5001 } else if (Tok.is(tok::comment)) {
5002 CXTok.int_data[0] = CXToken_Comment;
5003 CXTok.ptr_data = 0;
5004 } else {
5005 CXTok.int_data[0] = CXToken_Punctuation;
5006 CXTok.ptr_data = 0;
5007 }
5008 CXTokens.push_back(CXTok);
5009 previousWasAt = Tok.is(tok::at);
5010 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5011}
5012
5013void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5014 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005015 LOG_FUNC_SECTION {
5016 *Log << TU << ' ' << Range;
5017 }
5018
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005019 if (Tokens)
5020 *Tokens = 0;
5021 if (NumTokens)
5022 *NumTokens = 0;
5023
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005024 if (!TU)
5025 return;
5026
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005027 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005028 if (!CXXUnit || !Tokens || !NumTokens)
5029 return;
5030
5031 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5032
5033 SourceRange R = cxloc::translateCXSourceRange(Range);
5034 if (R.isInvalid())
5035 return;
5036
5037 SmallVector<CXToken, 32> CXTokens;
5038 getTokens(CXXUnit, R, CXTokens);
5039
5040 if (CXTokens.empty())
5041 return;
5042
5043 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5044 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5045 *NumTokens = CXTokens.size();
5046}
5047
5048void clang_disposeTokens(CXTranslationUnit TU,
5049 CXToken *Tokens, unsigned NumTokens) {
5050 free(Tokens);
5051}
5052
5053} // end: extern "C"
5054
5055//===----------------------------------------------------------------------===//
5056// Token annotation APIs.
5057//===----------------------------------------------------------------------===//
5058
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005059static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5060 CXCursor parent,
5061 CXClientData client_data);
5062static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5063 CXClientData client_data);
5064
5065namespace {
5066class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005067 CXToken *Tokens;
5068 CXCursor *Cursors;
5069 unsigned NumTokens;
5070 unsigned TokIdx;
5071 unsigned PreprocessingTokIdx;
5072 CursorVisitor AnnotateVis;
5073 SourceManager &SrcMgr;
5074 bool HasContextSensitiveKeywords;
5075
5076 struct PostChildrenInfo {
5077 CXCursor Cursor;
5078 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005079 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005080 unsigned BeforeChildrenTokenIdx;
5081 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005082 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005083
5084 bool MoreTokens() const { return TokIdx < NumTokens; }
5085 unsigned NextToken() const { return TokIdx; }
5086 void AdvanceToken() { ++TokIdx; }
5087 SourceLocation GetTokenLoc(unsigned tokI) {
5088 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5089 }
5090 bool isFunctionMacroToken(unsigned tokI) const {
5091 return Tokens[tokI].int_data[3] != 0;
5092 }
5093 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5094 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5095 }
5096
5097 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005098 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005099 SourceRange);
5100
5101public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005102 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005103 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005104 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005105 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005106 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005107 AnnotateTokensVisitor, this,
5108 /*VisitPreprocessorLast=*/true,
5109 /*VisitIncludedEntities=*/false,
5110 RegionOfInterest,
5111 /*VisitDeclsOnly=*/false,
5112 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005113 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005114 HasContextSensitiveKeywords(false) { }
5115
5116 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5117 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5118 bool postVisitChildren(CXCursor cursor);
5119 void AnnotateTokens();
5120
5121 /// \brief Determine whether the annotator saw any cursors that have
5122 /// context-sensitive keywords.
5123 bool hasContextSensitiveKeywords() const {
5124 return HasContextSensitiveKeywords;
5125 }
5126
5127 ~AnnotateTokensWorker() {
5128 assert(PostChildrenInfos.empty());
5129 }
5130};
5131}
5132
5133void AnnotateTokensWorker::AnnotateTokens() {
5134 // Walk the AST within the region of interest, annotating tokens
5135 // along the way.
5136 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005137}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005138
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005139static inline void updateCursorAnnotation(CXCursor &Cursor,
5140 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005141 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005142 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005143 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005144}
5145
5146/// \brief It annotates and advances tokens with a cursor until the comparison
5147//// between the cursor location and the source range is the same as
5148/// \arg compResult.
5149///
5150/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5151/// Pass RangeOverlap to annotate tokens inside a range.
5152void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5153 RangeComparisonResult compResult,
5154 SourceRange range) {
5155 while (MoreTokens()) {
5156 const unsigned I = NextToken();
5157 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005158 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5159 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005160
5161 SourceLocation TokLoc = GetTokenLoc(I);
5162 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005163 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005164 AdvanceToken();
5165 continue;
5166 }
5167 break;
5168 }
5169}
5170
5171/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005172/// \returns true if it advanced beyond all macro tokens, false otherwise.
5173bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005174 CXCursor updateC,
5175 RangeComparisonResult compResult,
5176 SourceRange range) {
5177 assert(MoreTokens());
5178 assert(isFunctionMacroToken(NextToken()) &&
5179 "Should be called only for macro arg tokens");
5180
5181 // This works differently than annotateAndAdvanceTokens; because expanded
5182 // macro arguments can have arbitrary translation-unit source order, we do not
5183 // advance the token index one by one until a token fails the range test.
5184 // We only advance once past all of the macro arg tokens if all of them
5185 // pass the range test. If one of them fails we keep the token index pointing
5186 // at the start of the macro arg tokens so that the failing token will be
5187 // annotated by a subsequent annotation try.
5188
5189 bool atLeastOneCompFail = false;
5190
5191 unsigned I = NextToken();
5192 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5193 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5194 if (TokLoc.isFileID())
5195 continue; // not macro arg token, it's parens or comma.
5196 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5197 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5198 Cursors[I] = updateC;
5199 } else
5200 atLeastOneCompFail = true;
5201 }
5202
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005203 if (atLeastOneCompFail)
5204 return false;
5205
5206 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5207 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005208}
5209
5210enum CXChildVisitResult
5211AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005212 SourceRange cursorRange = getRawCursorExtent(cursor);
5213 if (cursorRange.isInvalid())
5214 return CXChildVisit_Recurse;
5215
5216 if (!HasContextSensitiveKeywords) {
5217 // Objective-C properties can have context-sensitive keywords.
5218 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005219 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005220 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5221 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5222 }
5223 // Objective-C methods can have context-sensitive keywords.
5224 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5225 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005226 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005227 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5228 if (Method->getObjCDeclQualifier())
5229 HasContextSensitiveKeywords = true;
5230 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005231 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5232 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005233 P != PEnd; ++P) {
5234 if ((*P)->getObjCDeclQualifier()) {
5235 HasContextSensitiveKeywords = true;
5236 break;
5237 }
5238 }
5239 }
5240 }
5241 }
5242 // C++ methods can have context-sensitive keywords.
5243 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005244 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005245 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5246 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5247 HasContextSensitiveKeywords = true;
5248 }
5249 }
5250 // C++ classes can have context-sensitive keywords.
5251 else if (cursor.kind == CXCursor_StructDecl ||
5252 cursor.kind == CXCursor_ClassDecl ||
5253 cursor.kind == CXCursor_ClassTemplate ||
5254 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005255 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005256 if (D->hasAttr<FinalAttr>())
5257 HasContextSensitiveKeywords = true;
5258 }
5259 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005260
5261 // Don't override a property annotation with its getter/setter method.
5262 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5263 parent.kind == CXCursor_ObjCPropertyDecl)
5264 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005265
5266 if (clang_isPreprocessing(cursor.kind)) {
5267 // Items in the preprocessing record are kept separate from items in
5268 // declarations, so we keep a separate token index.
5269 unsigned SavedTokIdx = TokIdx;
5270 TokIdx = PreprocessingTokIdx;
5271
5272 // Skip tokens up until we catch up to the beginning of the preprocessing
5273 // entry.
5274 while (MoreTokens()) {
5275 const unsigned I = NextToken();
5276 SourceLocation TokLoc = GetTokenLoc(I);
5277 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5278 case RangeBefore:
5279 AdvanceToken();
5280 continue;
5281 case RangeAfter:
5282 case RangeOverlap:
5283 break;
5284 }
5285 break;
5286 }
5287
5288 // Look at all of the tokens within this range.
5289 while (MoreTokens()) {
5290 const unsigned I = NextToken();
5291 SourceLocation TokLoc = GetTokenLoc(I);
5292 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5293 case RangeBefore:
5294 llvm_unreachable("Infeasible");
5295 case RangeAfter:
5296 break;
5297 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005298 // For macro expansions, just note where the beginning of the macro
5299 // expansion occurs.
5300 if (cursor.kind == CXCursor_MacroExpansion) {
5301 if (TokLoc == cursorRange.getBegin())
5302 Cursors[I] = cursor;
5303 AdvanceToken();
5304 break;
5305 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005306 // We may have already annotated macro names inside macro definitions.
5307 if (Cursors[I].kind != CXCursor_MacroExpansion)
5308 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005309 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005310 continue;
5311 }
5312 break;
5313 }
5314
5315 // Save the preprocessing token index; restore the non-preprocessing
5316 // token index.
5317 PreprocessingTokIdx = TokIdx;
5318 TokIdx = SavedTokIdx;
5319 return CXChildVisit_Recurse;
5320 }
5321
5322 if (cursorRange.isInvalid())
5323 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005324
5325 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005326 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005327 const enum CXCursorKind K = clang_getCursorKind(parent);
5328 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005329 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5330 // Attributes are annotated out-of-order, skip tokens until we reach it.
5331 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005332 ? clang_getNullCursor() : parent;
5333
5334 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5335
5336 // Avoid having the cursor of an expression "overwrite" the annotation of the
5337 // variable declaration that it belongs to.
5338 // This can happen for C++ constructor expressions whose range generally
5339 // include the variable declaration, e.g.:
5340 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5341 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005342 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005343 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005344 const unsigned I = NextToken();
5345 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5346 E->getLocStart() == D->getLocation() &&
5347 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005348 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005349 AdvanceToken();
5350 }
5351 }
5352 }
5353
5354 // Before recursing into the children keep some state that we are going
5355 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5356 // extra work after the child nodes are visited.
5357 // Note that we don't call VisitChildren here to avoid traversing statements
5358 // code-recursively which can blow the stack.
5359
5360 PostChildrenInfo Info;
5361 Info.Cursor = cursor;
5362 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005363 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005364 Info.BeforeChildrenTokenIdx = NextToken();
5365 PostChildrenInfos.push_back(Info);
5366
5367 return CXChildVisit_Recurse;
5368}
5369
5370bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5371 if (PostChildrenInfos.empty())
5372 return false;
5373 const PostChildrenInfo &Info = PostChildrenInfos.back();
5374 if (!clang_equalCursors(Info.Cursor, cursor))
5375 return false;
5376
5377 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5378 const unsigned AfterChildren = NextToken();
5379 SourceRange cursorRange = Info.CursorRange;
5380
5381 // Scan the tokens that are at the end of the cursor, but are not captured
5382 // but the child cursors.
5383 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5384
5385 // Scan the tokens that are at the beginning of the cursor, but are not
5386 // capture by the child cursors.
5387 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5388 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5389 break;
5390
5391 Cursors[I] = cursor;
5392 }
5393
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005394 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5395 // encountered the attribute cursor.
5396 if (clang_isAttribute(cursor.kind))
5397 TokIdx = Info.BeforeReachingCursorIdx;
5398
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005399 PostChildrenInfos.pop_back();
5400 return false;
5401}
5402
5403static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5404 CXCursor parent,
5405 CXClientData client_data) {
5406 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5407}
5408
5409static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5410 CXClientData client_data) {
5411 return static_cast<AnnotateTokensWorker*>(client_data)->
5412 postVisitChildren(cursor);
5413}
5414
5415namespace {
5416
5417/// \brief Uses the macro expansions in the preprocessing record to find
5418/// and mark tokens that are macro arguments. This info is used by the
5419/// AnnotateTokensWorker.
5420class MarkMacroArgTokensVisitor {
5421 SourceManager &SM;
5422 CXToken *Tokens;
5423 unsigned NumTokens;
5424 unsigned CurIdx;
5425
5426public:
5427 MarkMacroArgTokensVisitor(SourceManager &SM,
5428 CXToken *tokens, unsigned numTokens)
5429 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5430
5431 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5432 if (cursor.kind != CXCursor_MacroExpansion)
5433 return CXChildVisit_Continue;
5434
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005435 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005436 if (macroRange.getBegin() == macroRange.getEnd())
5437 return CXChildVisit_Continue; // it's not a function macro.
5438
5439 for (; CurIdx < NumTokens; ++CurIdx) {
5440 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5441 macroRange.getBegin()))
5442 break;
5443 }
5444
5445 if (CurIdx == NumTokens)
5446 return CXChildVisit_Break;
5447
5448 for (; CurIdx < NumTokens; ++CurIdx) {
5449 SourceLocation tokLoc = getTokenLoc(CurIdx);
5450 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5451 break;
5452
5453 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5454 }
5455
5456 if (CurIdx == NumTokens)
5457 return CXChildVisit_Break;
5458
5459 return CXChildVisit_Continue;
5460 }
5461
5462private:
5463 SourceLocation getTokenLoc(unsigned tokI) {
5464 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5465 }
5466
5467 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5468 // The third field is reserved and currently not used. Use it here
5469 // to mark macro arg expanded tokens with their expanded locations.
5470 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5471 }
5472};
5473
5474} // end anonymous namespace
5475
5476static CXChildVisitResult
5477MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5478 CXClientData client_data) {
5479 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5480 parent);
5481}
5482
5483namespace {
5484 struct clang_annotateTokens_Data {
5485 CXTranslationUnit TU;
5486 ASTUnit *CXXUnit;
5487 CXToken *Tokens;
5488 unsigned NumTokens;
5489 CXCursor *Cursors;
5490 };
5491}
5492
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005493/// \brief Used by \c annotatePreprocessorTokens.
5494/// \returns true if lexing was finished, false otherwise.
5495static bool lexNext(Lexer &Lex, Token &Tok,
5496 unsigned &NextIdx, unsigned NumTokens) {
5497 if (NextIdx >= NumTokens)
5498 return true;
5499
5500 ++NextIdx;
5501 Lex.LexFromRawLexer(Tok);
5502 if (Tok.is(tok::eof))
5503 return true;
5504
5505 return false;
5506}
5507
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005508static void annotatePreprocessorTokens(CXTranslationUnit TU,
5509 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005510 CXCursor *Cursors,
5511 CXToken *Tokens,
5512 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005513 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005514
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005515 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005516 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5517 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005518 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005519 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005520 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005521
5522 if (BeginLocInfo.first != EndLocInfo.first)
5523 return;
5524
5525 StringRef Buffer;
5526 bool Invalid = false;
5527 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5528 if (Buffer.empty() || Invalid)
5529 return;
5530
5531 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5532 CXXUnit->getASTContext().getLangOpts(),
5533 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5534 Buffer.end());
5535 Lex.SetCommentRetentionState(true);
5536
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005537 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005538 // Lex tokens in raw mode until we hit the end of the range, to avoid
5539 // entering #includes or expanding macros.
5540 while (true) {
5541 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005542 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5543 break;
5544 unsigned TokIdx = NextIdx-1;
5545 assert(Tok.getLocation() ==
5546 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005547
5548 reprocess:
5549 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005550 // We have found a preprocessing directive. Annotate the tokens
5551 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005552 //
5553 // FIXME: Some simple tests here could identify macro definitions and
5554 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005555
5556 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005557 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5558 break;
5559
5560 MacroInfo *MI = 0;
5561 if (Tok.is(tok::raw_identifier) &&
5562 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5563 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5564 break;
5565
5566 if (Tok.is(tok::raw_identifier)) {
5567 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5568 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5569 SourceLocation MappedTokLoc =
5570 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5571 MI = getMacroInfo(II, MappedTokLoc, TU);
5572 }
5573 }
5574
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005575 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005576 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005577 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5578 finished = true;
5579 break;
5580 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005581 // If we are in a macro definition, check if the token was ever a
5582 // macro name and annotate it if that's the case.
5583 if (MI) {
5584 SourceLocation SaveLoc = Tok.getLocation();
5585 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5586 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5587 Tok.setLocation(SaveLoc);
5588 if (MacroDef)
5589 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5590 Tok.getLocation(), TU);
5591 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005592 } while (!Tok.isAtStartOfLine());
5593
5594 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5595 assert(TokIdx <= LastIdx);
5596 SourceLocation EndLoc =
5597 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5598 CXCursor Cursor =
5599 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5600
5601 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005602 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005603
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005604 if (finished)
5605 break;
5606 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005607 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005608 }
5609}
5610
5611// This gets run a separate thread to avoid stack blowout.
5612static void clang_annotateTokensImpl(void *UserData) {
5613 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5614 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5615 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5616 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5617 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5618
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005619 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005620 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5621 setThreadBackgroundPriority();
5622
5623 // Determine the region of interest, which contains all of the tokens.
5624 SourceRange RegionOfInterest;
5625 RegionOfInterest.setBegin(
5626 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5627 RegionOfInterest.setEnd(
5628 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5629 Tokens[NumTokens-1])));
5630
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005631 // Relex the tokens within the source range to look for preprocessing
5632 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005633 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005634
5635 // If begin location points inside a macro argument, set it to the expansion
5636 // location so we can have the full context when annotating semantically.
5637 {
5638 SourceManager &SM = CXXUnit->getSourceManager();
5639 SourceLocation Loc =
5640 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5641 if (Loc.isMacroID())
5642 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5643 }
5644
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005645 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5646 // Search and mark tokens that are macro argument expansions.
5647 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5648 Tokens, NumTokens);
5649 CursorVisitor MacroArgMarker(TU,
5650 MarkMacroArgTokensVisitorDelegate, &Visitor,
5651 /*VisitPreprocessorLast=*/true,
5652 /*VisitIncludedEntities=*/false,
5653 RegionOfInterest);
5654 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5655 }
5656
5657 // Annotate all of the source locations in the region of interest that map to
5658 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005659 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005660
5661 // FIXME: We use a ridiculous stack size here because the data-recursion
5662 // algorithm uses a large stack frame than the non-data recursive version,
5663 // and AnnotationTokensWorker currently transforms the data-recursion
5664 // algorithm back into a traditional recursion by explicitly calling
5665 // VisitChildren(). We will need to remove this explicit recursive call.
5666 W.AnnotateTokens();
5667
5668 // If we ran into any entities that involve context-sensitive keywords,
5669 // take another pass through the tokens to mark them as such.
5670 if (W.hasContextSensitiveKeywords()) {
5671 for (unsigned I = 0; I != NumTokens; ++I) {
5672 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5673 continue;
5674
5675 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5676 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005677 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005678 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5679 if (Property->getPropertyAttributesAsWritten() != 0 &&
5680 llvm::StringSwitch<bool>(II->getName())
5681 .Case("readonly", true)
5682 .Case("assign", true)
5683 .Case("unsafe_unretained", true)
5684 .Case("readwrite", true)
5685 .Case("retain", true)
5686 .Case("copy", true)
5687 .Case("nonatomic", true)
5688 .Case("atomic", true)
5689 .Case("getter", true)
5690 .Case("setter", true)
5691 .Case("strong", true)
5692 .Case("weak", true)
5693 .Default(false))
5694 Tokens[I].int_data[0] = CXToken_Keyword;
5695 }
5696 continue;
5697 }
5698
5699 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5700 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5701 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5702 if (llvm::StringSwitch<bool>(II->getName())
5703 .Case("in", true)
5704 .Case("out", true)
5705 .Case("inout", true)
5706 .Case("oneway", true)
5707 .Case("bycopy", true)
5708 .Case("byref", true)
5709 .Default(false))
5710 Tokens[I].int_data[0] = CXToken_Keyword;
5711 continue;
5712 }
5713
5714 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5715 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5716 Tokens[I].int_data[0] = CXToken_Keyword;
5717 continue;
5718 }
5719 }
5720 }
5721}
5722
5723extern "C" {
5724
5725void clang_annotateTokens(CXTranslationUnit TU,
5726 CXToken *Tokens, unsigned NumTokens,
5727 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005728 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005729 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005730 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005731 }
5732
5733 LOG_FUNC_SECTION {
5734 *Log << TU << ' ';
5735 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5736 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5737 *Log << clang_getRange(bloc, eloc);
5738 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005739
5740 // Any token we don't specifically annotate will have a NULL cursor.
5741 CXCursor C = clang_getNullCursor();
5742 for (unsigned I = 0; I != NumTokens; ++I)
5743 Cursors[I] = C;
5744
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005745 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005746 if (!CXXUnit)
5747 return;
5748
5749 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5750
5751 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5752 llvm::CrashRecoveryContext CRC;
5753 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5754 GetSafetyThreadStackSize() * 2)) {
5755 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5756 }
5757}
5758
5759} // end: extern "C"
5760
5761//===----------------------------------------------------------------------===//
5762// Operations for querying linkage of a cursor.
5763//===----------------------------------------------------------------------===//
5764
5765extern "C" {
5766CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5767 if (!clang_isDeclaration(cursor.kind))
5768 return CXLinkage_Invalid;
5769
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005770 const Decl *D = cxcursor::getCursorDecl(cursor);
5771 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005772 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005773 case NoLinkage:
5774 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005775 case InternalLinkage: return CXLinkage_Internal;
5776 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5777 case ExternalLinkage: return CXLinkage_External;
5778 };
5779
5780 return CXLinkage_Invalid;
5781}
5782} // end: extern "C"
5783
5784//===----------------------------------------------------------------------===//
5785// Operations for querying language of a cursor.
5786//===----------------------------------------------------------------------===//
5787
5788static CXLanguageKind getDeclLanguage(const Decl *D) {
5789 if (!D)
5790 return CXLanguage_C;
5791
5792 switch (D->getKind()) {
5793 default:
5794 break;
5795 case Decl::ImplicitParam:
5796 case Decl::ObjCAtDefsField:
5797 case Decl::ObjCCategory:
5798 case Decl::ObjCCategoryImpl:
5799 case Decl::ObjCCompatibleAlias:
5800 case Decl::ObjCImplementation:
5801 case Decl::ObjCInterface:
5802 case Decl::ObjCIvar:
5803 case Decl::ObjCMethod:
5804 case Decl::ObjCProperty:
5805 case Decl::ObjCPropertyImpl:
5806 case Decl::ObjCProtocol:
5807 return CXLanguage_ObjC;
5808 case Decl::CXXConstructor:
5809 case Decl::CXXConversion:
5810 case Decl::CXXDestructor:
5811 case Decl::CXXMethod:
5812 case Decl::CXXRecord:
5813 case Decl::ClassTemplate:
5814 case Decl::ClassTemplatePartialSpecialization:
5815 case Decl::ClassTemplateSpecialization:
5816 case Decl::Friend:
5817 case Decl::FriendTemplate:
5818 case Decl::FunctionTemplate:
5819 case Decl::LinkageSpec:
5820 case Decl::Namespace:
5821 case Decl::NamespaceAlias:
5822 case Decl::NonTypeTemplateParm:
5823 case Decl::StaticAssert:
5824 case Decl::TemplateTemplateParm:
5825 case Decl::TemplateTypeParm:
5826 case Decl::UnresolvedUsingTypename:
5827 case Decl::UnresolvedUsingValue:
5828 case Decl::Using:
5829 case Decl::UsingDirective:
5830 case Decl::UsingShadow:
5831 return CXLanguage_CPlusPlus;
5832 }
5833
5834 return CXLanguage_C;
5835}
5836
5837extern "C" {
5838
5839enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5840 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005841 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005842 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5843 return CXAvailability_Available;
5844
5845 switch (D->getAvailability()) {
5846 case AR_Available:
5847 case AR_NotYetIntroduced:
5848 return CXAvailability_Available;
5849
5850 case AR_Deprecated:
5851 return CXAvailability_Deprecated;
5852
5853 case AR_Unavailable:
5854 return CXAvailability_NotAvailable;
5855 }
5856 }
5857
5858 return CXAvailability_Available;
5859}
5860
5861static CXVersion convertVersion(VersionTuple In) {
5862 CXVersion Out = { -1, -1, -1 };
5863 if (In.empty())
5864 return Out;
5865
5866 Out.Major = In.getMajor();
5867
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005868 Optional<unsigned> Minor = In.getMinor();
5869 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005870 Out.Minor = *Minor;
5871 else
5872 return Out;
5873
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005874 Optional<unsigned> Subminor = In.getSubminor();
5875 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005876 Out.Subminor = *Subminor;
5877
5878 return Out;
5879}
5880
5881int clang_getCursorPlatformAvailability(CXCursor cursor,
5882 int *always_deprecated,
5883 CXString *deprecated_message,
5884 int *always_unavailable,
5885 CXString *unavailable_message,
5886 CXPlatformAvailability *availability,
5887 int availability_size) {
5888 if (always_deprecated)
5889 *always_deprecated = 0;
5890 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005891 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005892 if (always_unavailable)
5893 *always_unavailable = 0;
5894 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005895 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005896
5897 if (!clang_isDeclaration(cursor.kind))
5898 return 0;
5899
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005900 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005901 if (!D)
5902 return 0;
5903
5904 int N = 0;
5905 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5906 ++A) {
5907 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5908 if (always_deprecated)
5909 *always_deprecated = 1;
5910 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005911 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005912 continue;
5913 }
5914
5915 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5916 if (always_unavailable)
5917 *always_unavailable = 1;
5918 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005919 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005920 }
5921 continue;
5922 }
5923
5924 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5925 if (N < availability_size) {
5926 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005927 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005928 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5929 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5930 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5931 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005932 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005933 }
5934 ++N;
5935 }
5936 }
5937
5938 return N;
5939}
5940
5941void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5942 clang_disposeString(availability->Platform);
5943 clang_disposeString(availability->Message);
5944}
5945
5946CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5947 if (clang_isDeclaration(cursor.kind))
5948 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5949
5950 return CXLanguage_Invalid;
5951}
5952
5953 /// \brief If the given cursor is the "templated" declaration
5954 /// descibing a class or function template, return the class or
5955 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005956static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005957 if (!D)
5958 return 0;
5959
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005960 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005961 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5962 return FunTmpl;
5963
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005964 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005965 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5966 return ClassTmpl;
5967
5968 return D;
5969}
5970
5971CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5972 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005973 if (const Decl *D = getCursorDecl(cursor)) {
5974 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005975 if (!DC)
5976 return clang_getNullCursor();
5977
5978 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5979 getCursorTU(cursor));
5980 }
5981 }
5982
5983 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005984 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005985 return MakeCXCursor(D, getCursorTU(cursor));
5986 }
5987
5988 return clang_getNullCursor();
5989}
5990
5991CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5992 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005993 if (const Decl *D = getCursorDecl(cursor)) {
5994 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005995 if (!DC)
5996 return clang_getNullCursor();
5997
5998 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5999 getCursorTU(cursor));
6000 }
6001 }
6002
6003 // FIXME: Note that we can't easily compute the lexical context of a
6004 // statement or expression, so we return nothing.
6005 return clang_getNullCursor();
6006}
6007
6008CXFile clang_getIncludedFile(CXCursor cursor) {
6009 if (cursor.kind != CXCursor_InclusionDirective)
6010 return 0;
6011
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006012 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00006013 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006014}
6015
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00006016unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6017 if (C.kind != CXCursor_ObjCPropertyDecl)
6018 return CXObjCPropertyAttr_noattr;
6019
6020 unsigned Result = CXObjCPropertyAttr_noattr;
6021 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6022 ObjCPropertyDecl::PropertyAttributeKind Attr =
6023 PD->getPropertyAttributesAsWritten();
6024
6025#define SET_CXOBJCPROP_ATTR(A) \
6026 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6027 Result |= CXObjCPropertyAttr_##A
6028 SET_CXOBJCPROP_ATTR(readonly);
6029 SET_CXOBJCPROP_ATTR(getter);
6030 SET_CXOBJCPROP_ATTR(assign);
6031 SET_CXOBJCPROP_ATTR(readwrite);
6032 SET_CXOBJCPROP_ATTR(retain);
6033 SET_CXOBJCPROP_ATTR(copy);
6034 SET_CXOBJCPROP_ATTR(nonatomic);
6035 SET_CXOBJCPROP_ATTR(setter);
6036 SET_CXOBJCPROP_ATTR(atomic);
6037 SET_CXOBJCPROP_ATTR(weak);
6038 SET_CXOBJCPROP_ATTR(strong);
6039 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6040#undef SET_CXOBJCPROP_ATTR
6041
6042 return Result;
6043}
6044
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006045unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6046 if (!clang_isDeclaration(C.kind))
6047 return CXObjCDeclQualifier_None;
6048
6049 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6050 const Decl *D = getCursorDecl(C);
6051 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6052 QT = MD->getObjCDeclQualifier();
6053 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6054 QT = PD->getObjCDeclQualifier();
6055 if (QT == Decl::OBJC_TQ_None)
6056 return CXObjCDeclQualifier_None;
6057
6058 unsigned Result = CXObjCDeclQualifier_None;
6059 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6060 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6061 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6062 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6063 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6064 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6065
6066 return Result;
6067}
6068
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006069unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6070 if (!clang_isDeclaration(C.kind))
6071 return 0;
6072
6073 const Decl *D = getCursorDecl(C);
6074 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6075 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6076 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6077 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6078
6079 return 0;
6080}
6081
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006082unsigned clang_Cursor_isVariadic(CXCursor C) {
6083 if (!clang_isDeclaration(C.kind))
6084 return 0;
6085
6086 const Decl *D = getCursorDecl(C);
6087 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6088 return FD->isVariadic();
6089 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6090 return MD->isVariadic();
6091
6092 return 0;
6093}
6094
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006095CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6096 if (!clang_isDeclaration(C.kind))
6097 return clang_getNullRange();
6098
6099 const Decl *D = getCursorDecl(C);
6100 ASTContext &Context = getCursorContext(C);
6101 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6102 if (!RC)
6103 return clang_getNullRange();
6104
6105 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6106}
6107
6108CXString clang_Cursor_getRawCommentText(CXCursor C) {
6109 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006110 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006111
6112 const Decl *D = getCursorDecl(C);
6113 ASTContext &Context = getCursorContext(C);
6114 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6115 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6116 StringRef();
6117
6118 // Don't duplicate the string because RawText points directly into source
6119 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006120 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006121}
6122
6123CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6124 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006125 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006126
6127 const Decl *D = getCursorDecl(C);
6128 const ASTContext &Context = getCursorContext(C);
6129 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6130
6131 if (RC) {
6132 StringRef BriefText = RC->getBriefText(Context);
6133
6134 // Don't duplicate the string because RawComment ensures that this memory
6135 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006136 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006137 }
6138
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006139 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006140}
6141
6142CXComment clang_Cursor_getParsedComment(CXCursor C) {
6143 if (!clang_isDeclaration(C.kind))
6144 return cxcomment::createCXComment(NULL, NULL);
6145
6146 const Decl *D = getCursorDecl(C);
6147 const ASTContext &Context = getCursorContext(C);
6148 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6149
6150 return cxcomment::createCXComment(FC, getCursorTU(C));
6151}
6152
6153CXModule clang_Cursor_getModule(CXCursor C) {
6154 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006155 if (const ImportDecl *ImportD =
6156 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006157 return ImportD->getImportedModule();
6158 }
6159
6160 return 0;
6161}
6162
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006163CXFile clang_Module_getASTFile(CXModule CXMod) {
6164 if (!CXMod)
6165 return 0;
6166 Module *Mod = static_cast<Module*>(CXMod);
6167 return const_cast<FileEntry *>(Mod->getASTFile());
6168}
6169
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006170CXModule clang_Module_getParent(CXModule CXMod) {
6171 if (!CXMod)
6172 return 0;
6173 Module *Mod = static_cast<Module*>(CXMod);
6174 return Mod->Parent;
6175}
6176
6177CXString clang_Module_getName(CXModule CXMod) {
6178 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006179 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006180 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006181 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006182}
6183
6184CXString clang_Module_getFullName(CXModule CXMod) {
6185 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006186 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006187 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006188 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006189}
6190
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006191unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6192 CXModule CXMod) {
6193 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006194 return 0;
6195 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006196 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6197 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6198 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006199}
6200
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006201CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6202 CXModule CXMod, unsigned Index) {
6203 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006204 return 0;
6205 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006206 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006207
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006208 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6209 if (Index < TopHeaders.size())
6210 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006211
6212 return 0;
6213}
6214
6215} // end: extern "C"
6216
6217//===----------------------------------------------------------------------===//
6218// C++ AST instrospection.
6219//===----------------------------------------------------------------------===//
6220
6221extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006222unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6223 if (!clang_isDeclaration(C.kind))
6224 return 0;
6225
6226 const CXXMethodDecl *Method = 0;
6227 const Decl *D = cxcursor::getCursorDecl(C);
6228 if (const FunctionTemplateDecl *FunTmpl =
6229 dyn_cast_or_null<FunctionTemplateDecl>(D))
6230 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6231 else
6232 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6233 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6234}
6235
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006236unsigned clang_CXXMethod_isStatic(CXCursor C) {
6237 if (!clang_isDeclaration(C.kind))
6238 return 0;
6239
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006240 const CXXMethodDecl *Method = 0;
6241 const Decl *D = cxcursor::getCursorDecl(C);
6242 if (const FunctionTemplateDecl *FunTmpl =
6243 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006244 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6245 else
6246 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6247 return (Method && Method->isStatic()) ? 1 : 0;
6248}
6249
6250unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6251 if (!clang_isDeclaration(C.kind))
6252 return 0;
6253
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006254 const CXXMethodDecl *Method = 0;
6255 const Decl *D = cxcursor::getCursorDecl(C);
6256 if (const FunctionTemplateDecl *FunTmpl =
6257 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006258 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6259 else
6260 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6261 return (Method && Method->isVirtual()) ? 1 : 0;
6262}
6263} // end: extern "C"
6264
6265//===----------------------------------------------------------------------===//
6266// Attribute introspection.
6267//===----------------------------------------------------------------------===//
6268
6269extern "C" {
6270CXType clang_getIBOutletCollectionType(CXCursor C) {
6271 if (C.kind != CXCursor_IBOutletCollectionAttr)
6272 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6273
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006274 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006275 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6276
6277 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6278}
6279} // end: extern "C"
6280
6281//===----------------------------------------------------------------------===//
6282// Inspecting memory usage.
6283//===----------------------------------------------------------------------===//
6284
6285typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6286
6287static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6288 enum CXTUResourceUsageKind k,
6289 unsigned long amount) {
6290 CXTUResourceUsageEntry entry = { k, amount };
6291 entries.push_back(entry);
6292}
6293
6294extern "C" {
6295
6296const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6297 const char *str = "";
6298 switch (kind) {
6299 case CXTUResourceUsage_AST:
6300 str = "ASTContext: expressions, declarations, and types";
6301 break;
6302 case CXTUResourceUsage_Identifiers:
6303 str = "ASTContext: identifiers";
6304 break;
6305 case CXTUResourceUsage_Selectors:
6306 str = "ASTContext: selectors";
6307 break;
6308 case CXTUResourceUsage_GlobalCompletionResults:
6309 str = "Code completion: cached global results";
6310 break;
6311 case CXTUResourceUsage_SourceManagerContentCache:
6312 str = "SourceManager: content cache allocator";
6313 break;
6314 case CXTUResourceUsage_AST_SideTables:
6315 str = "ASTContext: side tables";
6316 break;
6317 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6318 str = "SourceManager: malloc'ed memory buffers";
6319 break;
6320 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6321 str = "SourceManager: mmap'ed memory buffers";
6322 break;
6323 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6324 str = "ExternalASTSource: malloc'ed memory buffers";
6325 break;
6326 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6327 str = "ExternalASTSource: mmap'ed memory buffers";
6328 break;
6329 case CXTUResourceUsage_Preprocessor:
6330 str = "Preprocessor: malloc'ed memory";
6331 break;
6332 case CXTUResourceUsage_PreprocessingRecord:
6333 str = "Preprocessor: PreprocessingRecord";
6334 break;
6335 case CXTUResourceUsage_SourceManager_DataStructures:
6336 str = "SourceManager: data structures and tables";
6337 break;
6338 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6339 str = "Preprocessor: header search tables";
6340 break;
6341 }
6342 return str;
6343}
6344
6345CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6346 if (!TU) {
6347 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6348 return usage;
6349 }
6350
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006351 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006352 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6353 ASTContext &astContext = astUnit->getASTContext();
6354
6355 // How much memory is used by AST nodes and types?
6356 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6357 (unsigned long) astContext.getASTAllocatedMemory());
6358
6359 // How much memory is used by identifiers?
6360 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6361 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6362
6363 // How much memory is used for selectors?
6364 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6365 (unsigned long) astContext.Selectors.getTotalMemory());
6366
6367 // How much memory is used by ASTContext's side tables?
6368 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6369 (unsigned long) astContext.getSideTableAllocatedMemory());
6370
6371 // How much memory is used for caching global code completion results?
6372 unsigned long completionBytes = 0;
6373 if (GlobalCodeCompletionAllocator *completionAllocator =
6374 astUnit->getCachedCompletionAllocator().getPtr()) {
6375 completionBytes = completionAllocator->getTotalMemory();
6376 }
6377 createCXTUResourceUsageEntry(*entries,
6378 CXTUResourceUsage_GlobalCompletionResults,
6379 completionBytes);
6380
6381 // How much memory is being used by SourceManager's content cache?
6382 createCXTUResourceUsageEntry(*entries,
6383 CXTUResourceUsage_SourceManagerContentCache,
6384 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6385
6386 // How much memory is being used by the MemoryBuffer's in SourceManager?
6387 const SourceManager::MemoryBufferSizes &srcBufs =
6388 astUnit->getSourceManager().getMemoryBufferSizes();
6389
6390 createCXTUResourceUsageEntry(*entries,
6391 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6392 (unsigned long) srcBufs.malloc_bytes);
6393 createCXTUResourceUsageEntry(*entries,
6394 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6395 (unsigned long) srcBufs.mmap_bytes);
6396 createCXTUResourceUsageEntry(*entries,
6397 CXTUResourceUsage_SourceManager_DataStructures,
6398 (unsigned long) astContext.getSourceManager()
6399 .getDataStructureSizes());
6400
6401 // How much memory is being used by the ExternalASTSource?
6402 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6403 const ExternalASTSource::MemoryBufferSizes &sizes =
6404 esrc->getMemoryBufferSizes();
6405
6406 createCXTUResourceUsageEntry(*entries,
6407 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6408 (unsigned long) sizes.malloc_bytes);
6409 createCXTUResourceUsageEntry(*entries,
6410 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6411 (unsigned long) sizes.mmap_bytes);
6412 }
6413
6414 // How much memory is being used by the Preprocessor?
6415 Preprocessor &pp = astUnit->getPreprocessor();
6416 createCXTUResourceUsageEntry(*entries,
6417 CXTUResourceUsage_Preprocessor,
6418 pp.getTotalMemory());
6419
6420 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6421 createCXTUResourceUsageEntry(*entries,
6422 CXTUResourceUsage_PreprocessingRecord,
6423 pRec->getTotalMemory());
6424 }
6425
6426 createCXTUResourceUsageEntry(*entries,
6427 CXTUResourceUsage_Preprocessor_HeaderSearch,
6428 pp.getHeaderSearchInfo().getTotalMemory());
6429
6430 CXTUResourceUsage usage = { (void*) entries.get(),
6431 (unsigned) entries->size(),
6432 entries->size() ? &(*entries)[0] : 0 };
6433 entries.take();
6434 return usage;
6435}
6436
6437void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6438 if (usage.data)
6439 delete (MemUsageEntries*) usage.data;
6440}
6441
6442} // end extern "C"
6443
6444void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6445 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6446 for (unsigned I = 0; I != Usage.numEntries; ++I)
6447 fprintf(stderr, " %s: %lu\n",
6448 clang_getTUResourceUsageName(Usage.entries[I].kind),
6449 Usage.entries[I].amount);
6450
6451 clang_disposeCXTUResourceUsage(Usage);
6452}
6453
6454//===----------------------------------------------------------------------===//
6455// Misc. utility functions.
6456//===----------------------------------------------------------------------===//
6457
6458/// Default to using an 8 MB stack size on "safety" threads.
6459static unsigned SafetyStackThreadSize = 8 << 20;
6460
6461namespace clang {
6462
6463bool RunSafely(llvm::CrashRecoveryContext &CRC,
6464 void (*Fn)(void*), void *UserData,
6465 unsigned Size) {
6466 if (!Size)
6467 Size = GetSafetyThreadStackSize();
6468 if (Size)
6469 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6470 return CRC.RunSafely(Fn, UserData);
6471}
6472
6473unsigned GetSafetyThreadStackSize() {
6474 return SafetyStackThreadSize;
6475}
6476
6477void SetSafetyThreadStackSize(unsigned Value) {
6478 SafetyStackThreadSize = Value;
6479}
6480
6481}
6482
6483void clang::setThreadBackgroundPriority() {
6484 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6485 return;
6486
6487 // FIXME: Move to llvm/Support and make it cross-platform.
6488#ifdef __APPLE__
6489 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6490#endif
6491}
6492
6493void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6494 if (!Unit)
6495 return;
6496
6497 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6498 DEnd = Unit->stored_diag_end();
6499 D != DEnd; ++D) {
6500 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6501 CXString Msg = clang_formatDiagnostic(&Diag,
6502 clang_defaultDiagnosticDisplayOptions());
6503 fprintf(stderr, "%s\n", clang_getCString(Msg));
6504 clang_disposeString(Msg);
6505 }
6506#ifdef LLVM_ON_WIN32
6507 // On Windows, force a flush, since there may be multiple copies of
6508 // stderr and stdout in the file system, all with different buffers
6509 // but writing to the same device.
6510 fflush(stderr);
6511#endif
6512}
6513
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006514MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6515 SourceLocation MacroDefLoc,
6516 CXTranslationUnit TU){
6517 if (MacroDefLoc.isInvalid() || !TU)
6518 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006519 if (!II.hadMacroDefinition())
6520 return 0;
6521
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006522 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006523 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006524 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006525 if (MD) {
6526 for (MacroDirective::DefInfo
6527 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6528 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6529 return Def.getMacroInfo();
6530 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006531 }
6532
6533 return 0;
6534}
6535
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006536const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6537 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006538 if (!MacroDef || !TU)
6539 return 0;
6540 const IdentifierInfo *II = MacroDef->getName();
6541 if (!II)
6542 return 0;
6543
6544 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6545}
6546
6547MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6548 const Token &Tok,
6549 CXTranslationUnit TU) {
6550 if (!MI || !TU)
6551 return 0;
6552 if (Tok.isNot(tok::raw_identifier))
6553 return 0;
6554
6555 if (MI->getNumTokens() == 0)
6556 return 0;
6557 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6558 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006559 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006560
6561 // Check that the token is inside the definition and not its argument list.
6562 SourceManager &SM = Unit->getSourceManager();
6563 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6564 return 0;
6565 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6566 return 0;
6567
6568 Preprocessor &PP = Unit->getPreprocessor();
6569 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6570 if (!PPRec)
6571 return 0;
6572
6573 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6574 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6575 if (!II.hadMacroDefinition())
6576 return 0;
6577
6578 // Check that the identifier is not one of the macro arguments.
6579 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6580 return 0;
6581
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006582 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6583 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006584 return 0;
6585
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006586 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006587}
6588
6589MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6590 SourceLocation Loc,
6591 CXTranslationUnit TU) {
6592 if (Loc.isInvalid() || !MI || !TU)
6593 return 0;
6594
6595 if (MI->getNumTokens() == 0)
6596 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006597 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006598 Preprocessor &PP = Unit->getPreprocessor();
6599 if (!PP.getPreprocessingRecord())
6600 return 0;
6601 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6602 Token Tok;
6603 if (PP.getRawToken(Loc, Tok))
6604 return 0;
6605
6606 return checkForMacroInMacroDefinition(MI, Tok, TU);
6607}
6608
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006609extern "C" {
6610
6611CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006612 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006613}
6614
6615} // end: extern "C"
6616
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006617Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6618 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006619 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006620 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006621 if (Unit->isMainFileAST())
6622 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006623 return *this;
6624 }
6625 }
6626
6627 LogOS << "<NULL TU>";
6628 return *this;
6629}
6630
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006631Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6632 *this << FE->getName();
6633 return *this;
6634}
6635
6636Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6637 CXString cursorName = clang_getCursorDisplayName(cursor);
6638 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6639 clang_disposeString(cursorName);
6640 return *this;
6641}
6642
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006643Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6644 CXFile File;
6645 unsigned Line, Column;
6646 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6647 CXString FileName = clang_getFileName(File);
6648 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6649 clang_disposeString(FileName);
6650 return *this;
6651}
6652
6653Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6654 CXSourceLocation BLoc = clang_getRangeStart(range);
6655 CXSourceLocation ELoc = clang_getRangeEnd(range);
6656
6657 CXFile BFile;
6658 unsigned BLine, BColumn;
6659 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6660
6661 CXFile EFile;
6662 unsigned ELine, EColumn;
6663 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6664
6665 CXString BFileName = clang_getFileName(BFile);
6666 if (BFile == EFile) {
6667 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6668 BLine, BColumn, ELine, EColumn);
6669 } else {
6670 CXString EFileName = clang_getFileName(EFile);
6671 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6672 BLine, BColumn)
6673 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6674 ELine, EColumn);
6675 clang_disposeString(EFileName);
6676 }
6677 clang_disposeString(BFileName);
6678 return *this;
6679}
6680
6681Logger &cxindex::Logger::operator<<(CXString Str) {
6682 *this << clang_getCString(Str);
6683 return *this;
6684}
6685
6686Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6687 LogOS << Fmt;
6688 return *this;
6689}
6690
6691cxindex::Logger::~Logger() {
6692 LogOS.flush();
6693
6694 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6695
6696 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6697
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006698 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006699 OS << "[libclang:" << Name << ':';
6700
6701 // FIXME: Portability.
6702#if HAVE_PTHREAD_H && __APPLE__
6703 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6704 OS << tid << ':';
6705#endif
6706
6707 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6708 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6709 OS << Msg.str() << '\n';
6710
6711 if (Trace) {
6712 llvm::sys::PrintStackTrace(stderr);
6713 OS << "--------------------------------------------------\n";
6714 }
6715}