blob: 15e282882b9026df76a1377e385204e04c7cfd7e [file] [log] [blame]
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
Fariborz Jahanian88b95212012-12-18 23:02:59 +000025#include "SimpleFormatContext.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
28#include "clang/Basic/Version.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
31#include "clang/Frontend/FrontendDiagnostic.h"
32#include "clang/Lex/HeaderSearch.h"
33#include "clang/Lex/Lexer.h"
34#include "clang/Lex/PreprocessingRecord.h"
35#include "clang/Lex/Preprocessor.h"
36#include "llvm/ADT/Optional.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringSwitch.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000039#include "llvm/Config/config.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000040#include "llvm/Support/Compiler.h"
41#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000042#include "llvm/Support/Format.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000043#include "llvm/Support/MemoryBuffer.h"
44#include "llvm/Support/Mutex.h"
45#include "llvm/Support/PrettyStackTrace.h"
46#include "llvm/Support/Program.h"
47#include "llvm/Support/SaveAndRestore.h"
48#include "llvm/Support/Signals.h"
49#include "llvm/Support/Threading.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +000052
53#if HAVE_PTHREAD_H
54#include <pthread.h>
55#endif
Guy Benyei7f92f2d2012-12-18 14:30:41 +000056
57using namespace clang;
58using namespace clang::cxcursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000059using namespace clang::cxtu;
60using namespace clang::cxindex;
61
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000062CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
63 if (!AU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +000064 return 0;
65 CXTranslationUnit D = new CXTranslationUnitImpl();
66 D->CIdx = CIdx;
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000067 D->TheASTUnit = AU;
Dmitri Gribenkoaca3e562013-02-03 13:52:47 +000068 D->StringPool = new cxstring::CXStringPool();
Guy Benyei7f92f2d2012-12-18 14:30:41 +000069 D->Diagnostics = 0;
70 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Fariborz Jahanian88b95212012-12-18 23:02:59 +000071 D->FormatContext = 0;
72 D->FormatInMemoryUniqueId = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000073 return D;
74}
75
76cxtu::CXTUOwner::~CXTUOwner() {
77 if (TU)
78 clang_disposeTranslationUnit(TU);
79}
80
81/// \brief Compare two source ranges to determine their relative position in
82/// the translation unit.
83static RangeComparisonResult RangeCompare(SourceManager &SM,
84 SourceRange R1,
85 SourceRange R2) {
86 assert(R1.isValid() && "First range is invalid?");
87 assert(R2.isValid() && "Second range is invalid?");
88 if (R1.getEnd() != R2.getBegin() &&
89 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
90 return RangeBefore;
91 if (R2.getEnd() != R1.getBegin() &&
92 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
93 return RangeAfter;
94 return RangeOverlap;
95}
96
97/// \brief Determine if a source location falls within, before, or after a
98/// a given source range.
99static RangeComparisonResult LocationCompare(SourceManager &SM,
100 SourceLocation L, SourceRange R) {
101 assert(R.isValid() && "First range is invalid?");
102 assert(L.isValid() && "Second range is invalid?");
103 if (L == R.getBegin() || L == R.getEnd())
104 return RangeOverlap;
105 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
106 return RangeBefore;
107 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Translate a Clang source range into a CIndex source range.
113///
114/// Clang internally represents ranges where the end location points to the
115/// start of the token at the end. However, for external clients it is more
116/// useful to have a CXSourceRange be a proper half-open interval. This routine
117/// does the appropriate translation.
118CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
119 const LangOptions &LangOpts,
120 const CharSourceRange &R) {
121 // We want the last character in this location, so we will adjust the
122 // location accordingly.
123 SourceLocation EndLoc = R.getEnd();
124 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
125 EndLoc = SM.getExpansionRange(EndLoc).second;
126 if (R.isTokenRange() && !EndLoc.isInvalid()) {
127 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
128 SM, LangOpts);
129 EndLoc = EndLoc.getLocWithOffset(Length);
130 }
131
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000132 CXSourceRange Result = {
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +0000133 { &SM, &LangOpts },
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000134 R.getBegin().getRawEncoding(),
135 EndLoc.getRawEncoding()
136 };
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000137 return Result;
138}
139
140//===----------------------------------------------------------------------===//
141// Cursor visitor.
142//===----------------------------------------------------------------------===//
143
144static SourceRange getRawCursorExtent(CXCursor C);
145static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
146
147
148RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
149 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
150}
151
152/// \brief Visit the given cursor and, if requested by the visitor,
153/// its children.
154///
155/// \param Cursor the cursor to visit.
156///
157/// \param CheckedRegionOfInterest if true, then the caller already checked
158/// that this cursor is within the region of interest.
159///
160/// \returns true if the visitation should be aborted, false if it
161/// should continue.
162bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
163 if (clang_isInvalid(Cursor.kind))
164 return false;
165
166 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000167 const Decl *D = getCursorDecl(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000168 if (!D) {
169 assert(0 && "Invalid declaration cursor");
170 return true; // abort.
171 }
172
173 // Ignore implicit declarations, unless it's an objc method because
174 // currently we should report implicit methods for properties when indexing.
175 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
176 return false;
177 }
178
179 // If we have a range of interest, and this cursor doesn't intersect with it,
180 // we're done.
181 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
182 SourceRange Range = getRawCursorExtent(Cursor);
183 if (Range.isInvalid() || CompareRegionOfInterest(Range))
184 return false;
185 }
186
187 switch (Visitor(Cursor, Parent, ClientData)) {
188 case CXChildVisit_Break:
189 return true;
190
191 case CXChildVisit_Continue:
192 return false;
193
194 case CXChildVisit_Recurse: {
195 bool ret = VisitChildren(Cursor);
196 if (PostChildrenVisitor)
197 if (PostChildrenVisitor(Cursor, ClientData))
198 return true;
199 return ret;
200 }
201 }
202
203 llvm_unreachable("Invalid CXChildVisitResult!");
204}
205
206static bool visitPreprocessedEntitiesInRange(SourceRange R,
207 PreprocessingRecord &PPRec,
208 CursorVisitor &Visitor) {
209 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
210 FileID FID;
211
212 if (!Visitor.shouldVisitIncludedEntities()) {
213 // If the begin/end of the range lie in the same FileID, do the optimization
214 // where we skip preprocessed entities that do not come from the same FileID.
215 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
216 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
217 FID = FileID();
218 }
219
220 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
221 Entities = PPRec.getPreprocessedEntitiesInRange(R);
222 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
223 PPRec, FID);
224}
225
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000226bool CursorVisitor::visitFileRegion() {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000227 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000228 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000229
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000230 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000231 SourceManager &SM = Unit->getSourceManager();
232
233 std::pair<FileID, unsigned>
234 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
235 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
236
237 if (End.first != Begin.first) {
238 // If the end does not reside in the same file, try to recover by
239 // picking the end of the file of begin location.
240 End.first = Begin.first;
241 End.second = SM.getFileIDSize(Begin.first);
242 }
243
244 assert(Begin.first == End.first);
245 if (Begin.second > End.second)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000246 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000247
248 FileID File = Begin.first;
249 unsigned Offset = Begin.second;
250 unsigned Length = End.second - Begin.second;
251
252 if (!VisitDeclsOnly && !VisitPreprocessorLast)
253 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000254 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000255
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000256 if (visitDeclsFromFileRegion(File, Offset, Length))
257 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000258
259 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000260 return visitPreprocessedEntitiesInRegion();
261
262 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000263}
264
265static bool isInLexicalContext(Decl *D, DeclContext *DC) {
266 if (!DC)
267 return false;
268
269 for (DeclContext *DeclDC = D->getLexicalDeclContext();
270 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
271 if (DeclDC == DC)
272 return true;
273 }
274 return false;
275}
276
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000277bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000278 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000279 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000280 SourceManager &SM = Unit->getSourceManager();
281 SourceRange Range = RegionOfInterest;
282
283 SmallVector<Decl *, 16> Decls;
284 Unit->findFileRegionDecls(File, Offset, Length, Decls);
285
286 // If we didn't find any file level decls for the file, try looking at the
287 // file that it was included from.
288 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
289 bool Invalid = false;
290 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
291 if (Invalid)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000292 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000293
294 SourceLocation Outer;
295 if (SLEntry.isFile())
296 Outer = SLEntry.getFile().getIncludeLoc();
297 else
298 Outer = SLEntry.getExpansion().getExpansionLocStart();
299 if (Outer.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000300 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000301
302 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
303 Length = 0;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305 }
306
307 assert(!Decls.empty());
308
309 bool VisitedAtLeastOnce = false;
310 DeclContext *CurDC = 0;
Craig Topper09d19ef2013-07-04 03:08:24 +0000311 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
312 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000313 Decl *D = *DIt;
314 if (D->getSourceRange().isInvalid())
315 continue;
316
317 if (isInLexicalContext(D, CurDC))
318 continue;
319
320 CurDC = dyn_cast<DeclContext>(D);
321
322 if (TagDecl *TD = dyn_cast<TagDecl>(D))
323 if (!TD->isFreeStanding())
324 continue;
325
326 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
327 if (CompRes == RangeBefore)
328 continue;
329 if (CompRes == RangeAfter)
330 break;
331
332 assert(CompRes == RangeOverlap);
333 VisitedAtLeastOnce = true;
334
335 if (isa<ObjCContainerDecl>(D)) {
336 FileDI_current = &DIt;
337 FileDE_current = DE;
338 } else {
339 FileDI_current = 0;
340 }
341
342 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000343 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000344 }
345
346 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000347 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000348
349 // No Decls overlapped with the range. Move up the lexical context until there
350 // is a context that contains the range or we reach the translation unit
351 // level.
352 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
353 : (*(DIt-1))->getLexicalDeclContext();
354
355 while (DC && !DC->isTranslationUnit()) {
356 Decl *D = cast<Decl>(DC);
357 SourceRange CurDeclRange = D->getSourceRange();
358 if (CurDeclRange.isInvalid())
359 break;
360
361 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
363 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000364 }
365
366 DC = D->getLexicalDeclContext();
367 }
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000368
369 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000370}
371
372bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
373 if (!AU->getPreprocessor().getPreprocessingRecord())
374 return false;
375
376 PreprocessingRecord &PPRec
377 = *AU->getPreprocessor().getPreprocessingRecord();
378 SourceManager &SM = AU->getSourceManager();
379
380 if (RegionOfInterest.isValid()) {
381 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
382 SourceLocation B = MappedRange.getBegin();
383 SourceLocation E = MappedRange.getEnd();
384
385 if (AU->isInPreambleFileID(B)) {
386 if (SM.isLoadedSourceLocation(E))
387 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
388 PPRec, *this);
389
390 // Beginning of range lies in the preamble but it also extends beyond
391 // it into the main file. Split the range into 2 parts, one covering
392 // the preamble and another covering the main file. This allows subsequent
393 // calls to visitPreprocessedEntitiesInRange to accept a source range that
394 // lies in the same FileID, allowing it to skip preprocessed entities that
395 // do not come from the same FileID.
396 bool breaked =
397 visitPreprocessedEntitiesInRange(
398 SourceRange(B, AU->getEndOfPreambleFileID()),
399 PPRec, *this);
400 if (breaked) return true;
401 return visitPreprocessedEntitiesInRange(
402 SourceRange(AU->getStartOfMainFileID(), E),
403 PPRec, *this);
404 }
405
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
407 }
408
409 bool OnlyLocalDecls
410 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
411
412 if (OnlyLocalDecls)
413 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
414 PPRec);
415
416 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
417}
418
419template<typename InputIterator>
420bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
421 InputIterator Last,
422 PreprocessingRecord &PPRec,
423 FileID FID) {
424 for (; First != Last; ++First) {
425 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
426 continue;
427
428 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis333e44c2013-05-07 20:37:17 +0000429 if (!PPE)
430 continue;
431
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000432 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
433 if (Visit(MakeMacroExpansionCursor(ME, TU)))
434 return true;
435
436 continue;
437 }
438
439 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
440 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
441 return true;
442
443 continue;
444 }
445
446 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
447 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
448 return true;
449
450 continue;
451 }
452 }
453
454 return false;
455}
456
457/// \brief Visit the children of the given cursor.
458///
459/// \returns true if the visitation should be aborted, false if it
460/// should continue.
461bool CursorVisitor::VisitChildren(CXCursor Cursor) {
462 if (clang_isReference(Cursor.kind) &&
463 Cursor.kind != CXCursor_CXXBaseSpecifier) {
464 // By definition, references have no children.
465 return false;
466 }
467
468 // Set the Parent field to Cursor, then back to its old value once we're
469 // done.
470 SetParentRAII SetParent(Parent, StmtParent, Cursor);
471
472 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000473 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000474 if (!D)
475 return false;
476
477 return VisitAttributes(D) || Visit(D);
478 }
479
480 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000481 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000482 return Visit(S);
483
484 return false;
485 }
486
487 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000488 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000489 return Visit(E);
490
491 return false;
492 }
493
494 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000495 CXTranslationUnit TU = getCursorTU(Cursor);
496 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000497
498 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
499 for (unsigned I = 0; I != 2; ++I) {
500 if (VisitOrder[I]) {
501 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
502 RegionOfInterest.isInvalid()) {
503 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
504 TLEnd = CXXUnit->top_level_end();
505 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000506 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000507 return true;
508 }
509 } else if (VisitDeclContext(
510 CXXUnit->getASTContext().getTranslationUnitDecl()))
511 return true;
512 continue;
513 }
514
515 // Walk the preprocessing record.
516 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
517 visitPreprocessedEntitiesInRegion();
518 }
519
520 return false;
521 }
522
523 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000524 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000525 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
526 return Visit(BaseTSInfo->getTypeLoc());
527 }
528 }
529 }
530
531 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000532 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000533 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
534 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
535 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
536 A->getInterfaceLoc(), TU));
537 }
538
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000539 // If pointing inside a macro definition, check if the token is an identifier
540 // that was ever defined as a macro. In such a case, create a "pseudo" macro
541 // expansion cursor for that token.
542 SourceLocation BeginLoc = RegionOfInterest.getBegin();
543 if (Cursor.kind == CXCursor_MacroDefinition &&
544 BeginLoc == RegionOfInterest.getEnd()) {
545 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000546 const MacroInfo *MI =
547 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000548 if (MacroDefinition *MacroDef =
549 checkForMacroInMacroDefinition(MI, Loc, TU))
550 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
551 }
552
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000553 // Nothing to visit at the moment.
554 return false;
555}
556
557bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
558 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
559 if (Visit(TSInfo->getTypeLoc()))
560 return true;
561
562 if (Stmt *Body = B->getBody())
563 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
564
565 return false;
566}
567
Ted Kremenek943f9092013-02-21 01:29:01 +0000568Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000569 if (RegionOfInterest.isValid()) {
570 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
571 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000572 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000573
574 switch (CompareRegionOfInterest(Range)) {
575 case RangeBefore:
576 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000577 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000578
579 case RangeAfter:
580 // This declaration comes after the region of interest; we're done.
581 return false;
582
583 case RangeOverlap:
584 // This declaration overlaps the region of interest; visit it.
585 break;
586 }
587 }
588 return true;
589}
590
591bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
592 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
593
594 // FIXME: Eventually remove. This part of a hack to support proper
595 // iteration over all Decls contained lexically within an ObjC container.
596 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
597 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
598
599 for ( ; I != E; ++I) {
600 Decl *D = *I;
601 if (D->getLexicalDeclContext() != DC)
602 continue;
603 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
604
605 // Ignore synthesized ivars here, otherwise if we have something like:
606 // @synthesize prop = _prop;
607 // and '_prop' is not declared, we will encounter a '_prop' ivar before
608 // encountering the 'prop' synthesize declaration and we will think that
609 // we passed the region-of-interest.
610 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
611 if (ivarD->getSynthesize())
612 continue;
613 }
614
615 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
616 // declarations is a mismatch with the compiler semantics.
617 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
618 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
619 if (!ID->isThisDeclarationADefinition())
620 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
621
622 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
623 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
624 if (!PD->isThisDeclarationADefinition())
625 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
626 }
627
Ted Kremenek943f9092013-02-21 01:29:01 +0000628 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000629 if (!V.hasValue())
630 continue;
631 if (!V.getValue())
632 return false;
633 if (Visit(Cursor, true))
634 return true;
635 }
636 return false;
637}
638
639bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
640 llvm_unreachable("Translation units are visited directly by Visit()");
641}
642
643bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
644 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
645 return Visit(TSInfo->getTypeLoc());
646
647 return false;
648}
649
650bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
651 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
652 return Visit(TSInfo->getTypeLoc());
653
654 return false;
655}
656
657bool CursorVisitor::VisitTagDecl(TagDecl *D) {
658 return VisitDeclContext(D);
659}
660
661bool CursorVisitor::VisitClassTemplateSpecializationDecl(
662 ClassTemplateSpecializationDecl *D) {
663 bool ShouldVisitBody = false;
664 switch (D->getSpecializationKind()) {
665 case TSK_Undeclared:
666 case TSK_ImplicitInstantiation:
667 // Nothing to visit
668 return false;
669
670 case TSK_ExplicitInstantiationDeclaration:
671 case TSK_ExplicitInstantiationDefinition:
672 break;
673
674 case TSK_ExplicitSpecialization:
675 ShouldVisitBody = true;
676 break;
677 }
678
679 // Visit the template arguments used in the specialization.
680 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
681 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000682 if (TemplateSpecializationTypeLoc TSTLoc =
683 TL.getAs<TemplateSpecializationTypeLoc>()) {
684 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
685 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000686 return true;
687 }
688 }
689
690 if (ShouldVisitBody && VisitCXXRecordDecl(D))
691 return true;
692
693 return false;
694}
695
696bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
697 ClassTemplatePartialSpecializationDecl *D) {
698 // FIXME: Visit the "outer" template parameter lists on the TagDecl
699 // before visiting these template parameters.
700 if (VisitTemplateParameters(D->getTemplateParameters()))
701 return true;
702
703 // Visit the partial specialization arguments.
Enea Zaffanellac1cef082013-08-10 07:24:53 +0000704 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
705 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
706 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000707 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
708 return true;
709
710 return VisitCXXRecordDecl(D);
711}
712
713bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
714 // Visit the default argument.
715 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
716 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
717 if (Visit(DefArg->getTypeLoc()))
718 return true;
719
720 return false;
721}
722
723bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
724 if (Expr *Init = D->getInitExpr())
725 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
726 return false;
727}
728
729bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000730 unsigned NumParamList = DD->getNumTemplateParameterLists();
731 for (unsigned i = 0; i < NumParamList; i++) {
732 TemplateParameterList* Params = DD->getTemplateParameterList(i);
733 if (VisitTemplateParameters(Params))
734 return true;
735 }
736
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000737 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
738 if (Visit(TSInfo->getTypeLoc()))
739 return true;
740
741 // Visit the nested-name-specifier, if present.
742 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
743 if (VisitNestedNameSpecifierLoc(QualifierLoc))
744 return true;
745
746 return false;
747}
748
749/// \brief Compare two base or member initializers based on their source order.
750static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
751 CXXCtorInitializer const * const *X
752 = static_cast<CXXCtorInitializer const * const *>(Xp);
753 CXXCtorInitializer const * const *Y
754 = static_cast<CXXCtorInitializer const * const *>(Yp);
755
756 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
757 return -1;
758 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
759 return 1;
760 else
761 return 0;
762}
763
764bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000765 unsigned NumParamList = ND->getNumTemplateParameterLists();
766 for (unsigned i = 0; i < NumParamList; i++) {
767 TemplateParameterList* Params = ND->getTemplateParameterList(i);
768 if (VisitTemplateParameters(Params))
769 return true;
770 }
771
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000772 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
773 // Visit the function declaration's syntactic components in the order
774 // written. This requires a bit of work.
775 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000776 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000777
778 // If we have a function declared directly (without the use of a typedef),
779 // visit just the return type. Otherwise, just visit the function's type
780 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000781 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000782 (!FTL && Visit(TL)))
783 return true;
784
785 // Visit the nested-name-specifier, if present.
786 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
787 if (VisitNestedNameSpecifierLoc(QualifierLoc))
788 return true;
789
790 // Visit the declaration name.
791 if (VisitDeclarationNameInfo(ND->getNameInfo()))
792 return true;
793
794 // FIXME: Visit explicitly-specified template arguments!
795
796 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000797 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000798 return true;
799
Bill Wendlingad017fa2012-12-20 19:22:21 +0000800 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000801 }
802
803 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
804 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
805 // Find the initializers that were written in the source.
806 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
807 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
808 IEnd = Constructor->init_end();
809 I != IEnd; ++I) {
810 if (!(*I)->isWritten())
811 continue;
812
813 WrittenInits.push_back(*I);
814 }
815
816 // Sort the initializers in source order
817 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
818 &CompareCXXCtorInitializers);
819
820 // Visit the initializers in source order
821 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
822 CXXCtorInitializer *Init = WrittenInits[I];
823 if (Init->isAnyMemberInitializer()) {
824 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
825 Init->getMemberLocation(), TU)))
826 return true;
827 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
828 if (Visit(TInfo->getTypeLoc()))
829 return true;
830 }
831
832 // Visit the initializer value.
833 if (Expr *Initializer = Init->getInit())
834 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
835 return true;
836 }
837 }
838
839 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
840 return true;
841 }
842
843 return false;
844}
845
846bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
847 if (VisitDeclaratorDecl(D))
848 return true;
849
850 if (Expr *BitWidth = D->getBitWidth())
851 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
852
853 return false;
854}
855
856bool CursorVisitor::VisitVarDecl(VarDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *Init = D->getInit())
861 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
871 if (Expr *DefArg = D->getDefaultArgument())
872 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
878 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
879 // before visiting these template parameters.
880 if (VisitTemplateParameters(D->getTemplateParameters()))
881 return true;
882
883 return VisitFunctionDecl(D->getTemplatedDecl());
884}
885
886bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
887 // FIXME: Visit the "outer" template parameter lists on the TagDecl
888 // before visiting these template parameters.
889 if (VisitTemplateParameters(D->getTemplateParameters()))
890 return true;
891
892 return VisitCXXRecordDecl(D->getTemplatedDecl());
893}
894
895bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
896 if (VisitTemplateParameters(D->getTemplateParameters()))
897 return true;
898
899 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
900 VisitTemplateArgumentLoc(D->getDefaultArgument()))
901 return true;
902
903 return false;
904}
905
906bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
907 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
908 if (Visit(TSInfo->getTypeLoc()))
909 return true;
910
911 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
912 PEnd = ND->param_end();
913 P != PEnd; ++P) {
914 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
915 return true;
916 }
917
918 if (ND->isThisDeclarationADefinition() &&
919 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
920 return true;
921
922 return false;
923}
924
925template <typename DeclIt>
926static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
927 SourceManager &SM, SourceLocation EndLoc,
928 SmallVectorImpl<Decl *> &Decls) {
929 DeclIt next = *DI_current;
930 while (++next != DE_current) {
931 Decl *D_next = *next;
932 if (!D_next)
933 break;
934 SourceLocation L = D_next->getLocStart();
935 if (!L.isValid())
936 break;
937 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
938 *DI_current = next;
939 Decls.push_back(D_next);
940 continue;
941 }
942 break;
943 }
944}
945
946namespace {
947 struct ContainerDeclsSort {
948 SourceManager &SM;
949 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
950 bool operator()(Decl *A, Decl *B) {
951 SourceLocation L_A = A->getLocStart();
952 SourceLocation L_B = B->getLocStart();
953 assert(L_A.isValid() && L_B.isValid());
954 return SM.isBeforeInTranslationUnit(L_A, L_B);
955 }
956 };
957}
958
959bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
960 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
961 // an @implementation can lexically contain Decls that are not properly
962 // nested in the AST. When we identify such cases, we need to retrofit
963 // this nesting here.
964 if (!DI_current && !FileDI_current)
965 return VisitDeclContext(D);
966
967 // Scan the Decls that immediately come after the container
968 // in the current DeclContext. If any fall within the
969 // container's lexical region, stash them into a vector
970 // for later processing.
971 SmallVector<Decl *, 24> DeclsInContainer;
972 SourceLocation EndLoc = D->getSourceRange().getEnd();
973 SourceManager &SM = AU->getSourceManager();
974 if (EndLoc.isValid()) {
975 if (DI_current) {
976 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
977 DeclsInContainer);
978 } else {
979 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
980 DeclsInContainer);
981 }
982 }
983
984 // The common case.
985 if (DeclsInContainer.empty())
986 return VisitDeclContext(D);
987
988 // Get all the Decls in the DeclContext, and sort them with the
989 // additional ones we've collected. Then visit them.
990 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
991 I!=E; ++I) {
992 Decl *subDecl = *I;
993 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
994 subDecl->getLocStart().isInvalid())
995 continue;
996 DeclsInContainer.push_back(subDecl);
997 }
998
999 // Now sort the Decls so that they appear in lexical order.
1000 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1001 ContainerDeclsSort(SM));
1002
1003 // Now visit the decls.
1004 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1005 E = DeclsInContainer.end(); I != E; ++I) {
1006 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +00001007 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001008 if (!V.hasValue())
1009 continue;
1010 if (!V.getValue())
1011 return false;
1012 if (Visit(Cursor, true))
1013 return true;
1014 }
1015 return false;
1016}
1017
1018bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1019 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1020 TU)))
1021 return true;
1022
1023 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1024 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1025 E = ND->protocol_end(); I != E; ++I, ++PL)
1026 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1027 return true;
1028
1029 return VisitObjCContainerDecl(ND);
1030}
1031
1032bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1033 if (!PID->isThisDeclarationADefinition())
1034 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1035
1036 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1037 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1038 E = PID->protocol_end(); I != E; ++I, ++PL)
1039 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1040 return true;
1041
1042 return VisitObjCContainerDecl(PID);
1043}
1044
1045bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1046 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1047 return true;
1048
1049 // FIXME: This implements a workaround with @property declarations also being
1050 // installed in the DeclContext for the @interface. Eventually this code
1051 // should be removed.
1052 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1053 if (!CDecl || !CDecl->IsClassExtension())
1054 return false;
1055
1056 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1057 if (!ID)
1058 return false;
1059
1060 IdentifierInfo *PropertyId = PD->getIdentifier();
1061 ObjCPropertyDecl *prevDecl =
1062 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1063
1064 if (!prevDecl)
1065 return false;
1066
1067 // Visit synthesized methods since they will be skipped when visiting
1068 // the @interface.
1069 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1070 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1071 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1072 return true;
1073
1074 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1075 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1076 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1077 return true;
1078
1079 return false;
1080}
1081
1082bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1083 if (!D->isThisDeclarationADefinition()) {
1084 // Forward declaration is treated like a reference.
1085 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1086 }
1087
1088 // Issue callbacks for super class.
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1091 D->getSuperClassLoc(),
1092 TU)))
1093 return true;
1094
1095 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1096 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1097 E = D->protocol_end(); I != E; ++I, ++PL)
1098 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1099 return true;
1100
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1105 return VisitObjCContainerDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1109 // 'ID' could be null when dealing with invalid code.
1110 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1111 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1112 return true;
1113
1114 return VisitObjCImplDecl(D);
1115}
1116
1117bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1118#if 0
1119 // Issue callbacks for super class.
1120 // FIXME: No source location information!
1121 if (D->getSuperClass() &&
1122 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1123 D->getSuperClassLoc(),
1124 TU)))
1125 return true;
1126#endif
1127
1128 return VisitObjCImplDecl(D);
1129}
1130
1131bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1132 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1133 if (PD->isIvarNameSpecified())
1134 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1135
1136 return false;
1137}
1138
1139bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1140 return VisitDeclContext(D);
1141}
1142
1143bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1144 // Visit nested-name-specifier.
1145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1147 return true;
1148
1149 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1150 D->getTargetNameLoc(), TU));
1151}
1152
1153bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1154 // Visit nested-name-specifier.
1155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1157 return true;
1158 }
1159
1160 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1161 return true;
1162
1163 return VisitDeclarationNameInfo(D->getNameInfo());
1164}
1165
1166bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1167 // Visit nested-name-specifier.
1168 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1169 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1170 return true;
1171
1172 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1173 D->getIdentLocation(), TU));
1174}
1175
1176bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1177 // Visit nested-name-specifier.
1178 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1179 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1180 return true;
1181 }
1182
1183 return VisitDeclarationNameInfo(D->getNameInfo());
1184}
1185
1186bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1187 UnresolvedUsingTypenameDecl *D) {
1188 // Visit nested-name-specifier.
1189 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1190 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1191 return true;
1192
1193 return false;
1194}
1195
1196bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1197 switch (Name.getName().getNameKind()) {
1198 case clang::DeclarationName::Identifier:
1199 case clang::DeclarationName::CXXLiteralOperatorName:
1200 case clang::DeclarationName::CXXOperatorName:
1201 case clang::DeclarationName::CXXUsingDirective:
1202 return false;
1203
1204 case clang::DeclarationName::CXXConstructorName:
1205 case clang::DeclarationName::CXXDestructorName:
1206 case clang::DeclarationName::CXXConversionFunctionName:
1207 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1208 return Visit(TSInfo->getTypeLoc());
1209 return false;
1210
1211 case clang::DeclarationName::ObjCZeroArgSelector:
1212 case clang::DeclarationName::ObjCOneArgSelector:
1213 case clang::DeclarationName::ObjCMultiArgSelector:
1214 // FIXME: Per-identifier location info?
1215 return false;
1216 }
1217
1218 llvm_unreachable("Invalid DeclarationName::Kind!");
1219}
1220
1221bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1222 SourceRange Range) {
1223 // FIXME: This whole routine is a hack to work around the lack of proper
1224 // source information in nested-name-specifiers (PR5791). Since we do have
1225 // a beginning source location, we can visit the first component of the
1226 // nested-name-specifier, if it's a single-token component.
1227 if (!NNS)
1228 return false;
1229
1230 // Get the first component in the nested-name-specifier.
1231 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1232 NNS = Prefix;
1233
1234 switch (NNS->getKind()) {
1235 case NestedNameSpecifier::Namespace:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1237 TU));
1238
1239 case NestedNameSpecifier::NamespaceAlias:
1240 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1241 Range.getBegin(), TU));
1242
1243 case NestedNameSpecifier::TypeSpec: {
1244 // If the type has a form where we know that the beginning of the source
1245 // range matches up with a reference cursor. Visit the appropriate reference
1246 // cursor.
1247 const Type *T = NNS->getAsType();
1248 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1249 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1250 if (const TagType *Tag = dyn_cast<TagType>(T))
1251 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1252 if (const TemplateSpecializationType *TST
1253 = dyn_cast<TemplateSpecializationType>(T))
1254 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1255 break;
1256 }
1257
1258 case NestedNameSpecifier::TypeSpecWithTemplate:
1259 case NestedNameSpecifier::Global:
1260 case NestedNameSpecifier::Identifier:
1261 break;
1262 }
1263
1264 return false;
1265}
1266
1267bool
1268CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1269 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1270 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1271 Qualifiers.push_back(Qualifier);
1272
1273 while (!Qualifiers.empty()) {
1274 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1275 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1276 switch (NNS->getKind()) {
1277 case NestedNameSpecifier::Namespace:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::NamespaceAlias:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::TypeSpec:
1294 case NestedNameSpecifier::TypeSpecWithTemplate:
1295 if (Visit(Q.getTypeLoc()))
1296 return true;
1297
1298 break;
1299
1300 case NestedNameSpecifier::Global:
1301 case NestedNameSpecifier::Identifier:
1302 break;
1303 }
1304 }
1305
1306 return false;
1307}
1308
1309bool CursorVisitor::VisitTemplateParameters(
1310 const TemplateParameterList *Params) {
1311 if (!Params)
1312 return false;
1313
1314 for (TemplateParameterList::const_iterator P = Params->begin(),
1315 PEnd = Params->end();
1316 P != PEnd; ++P) {
1317 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1318 return true;
1319 }
1320
1321 return false;
1322}
1323
1324bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1325 switch (Name.getKind()) {
1326 case TemplateName::Template:
1327 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1328
1329 case TemplateName::OverloadedTemplate:
1330 // Visit the overloaded template set.
1331 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1332 return true;
1333
1334 return false;
1335
1336 case TemplateName::DependentTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return false;
1339
1340 case TemplateName::QualifiedTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return Visit(MakeCursorTemplateRef(
1343 Name.getAsQualifiedTemplateName()->getDecl(),
1344 Loc, TU));
1345
1346 case TemplateName::SubstTemplateTemplateParm:
1347 return Visit(MakeCursorTemplateRef(
1348 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1349 Loc, TU));
1350
1351 case TemplateName::SubstTemplateTemplateParmPack:
1352 return Visit(MakeCursorTemplateRef(
1353 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1354 Loc, TU));
1355 }
1356
1357 llvm_unreachable("Invalid TemplateName::Kind!");
1358}
1359
1360bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1361 switch (TAL.getArgument().getKind()) {
1362 case TemplateArgument::Null:
1363 case TemplateArgument::Integral:
1364 case TemplateArgument::Pack:
1365 return false;
1366
1367 case TemplateArgument::Type:
1368 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1369 return Visit(TSInfo->getTypeLoc());
1370 return false;
1371
1372 case TemplateArgument::Declaration:
1373 if (Expr *E = TAL.getSourceDeclExpression())
1374 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1375 return false;
1376
1377 case TemplateArgument::NullPtr:
1378 if (Expr *E = TAL.getSourceNullPtrExpression())
1379 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1380 return false;
1381
1382 case TemplateArgument::Expression:
1383 if (Expr *E = TAL.getSourceExpression())
1384 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1385 return false;
1386
1387 case TemplateArgument::Template:
1388 case TemplateArgument::TemplateExpansion:
1389 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1390 return true;
1391
1392 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1393 TAL.getTemplateNameLoc());
1394 }
1395
1396 llvm_unreachable("Invalid TemplateArgument::Kind!");
1397}
1398
1399bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1400 return VisitDeclContext(D);
1401}
1402
1403bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1404 return Visit(TL.getUnqualifiedLoc());
1405}
1406
1407bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1408 ASTContext &Context = AU->getASTContext();
1409
1410 // Some builtin types (such as Objective-C's "id", "sel", and
1411 // "Class") have associated declarations. Create cursors for those.
1412 QualType VisitType;
1413 switch (TL.getTypePtr()->getKind()) {
1414
1415 case BuiltinType::Void:
1416 case BuiltinType::NullPtr:
1417 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001418 case BuiltinType::OCLImage1d:
1419 case BuiltinType::OCLImage1dArray:
1420 case BuiltinType::OCLImage1dBuffer:
1421 case BuiltinType::OCLImage2d:
1422 case BuiltinType::OCLImage2dArray:
1423 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001424 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001425 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001426#define BUILTIN_TYPE(Id, SingletonId)
1427#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#include "clang/AST/BuiltinTypes.def"
1432 break;
1433
1434 case BuiltinType::ObjCId:
1435 VisitType = Context.getObjCIdType();
1436 break;
1437
1438 case BuiltinType::ObjCClass:
1439 VisitType = Context.getObjCClassType();
1440 break;
1441
1442 case BuiltinType::ObjCSel:
1443 VisitType = Context.getObjCSelType();
1444 break;
1445 }
1446
1447 if (!VisitType.isNull()) {
1448 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1449 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1450 TU));
1451 }
1452
1453 return false;
1454}
1455
1456bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1465 if (TL.isDefinition())
1466 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1467
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1476 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1477 return true;
1478
1479 return false;
1480}
1481
1482bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1483 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1484 return true;
1485
1486 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1487 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1488 TU)))
1489 return true;
1490 }
1491
1492 return false;
1493}
1494
1495bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1500 return Visit(TL.getInnerLoc());
1501}
1502
1503bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1524 return Visit(TL.getModifiedLoc());
1525}
1526
1527bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1528 bool SkipResultType) {
1529 if (!SkipResultType && Visit(TL.getResultLoc()))
1530 return true;
1531
1532 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1533 if (Decl *D = TL.getArg(I))
1534 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1535 return true;
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1541 if (Visit(TL.getElementLoc()))
1542 return true;
1543
1544 if (Expr *Size = TL.getSizeExpr())
1545 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1546
1547 return false;
1548}
1549
Reid Kleckner12df2462013-06-24 17:51:48 +00001550bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001554bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1555 TemplateSpecializationTypeLoc TL) {
1556 // Visit the template name.
1557 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1558 TL.getTemplateNameLoc()))
1559 return true;
1560
1561 // Visit the template arguments.
1562 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1563 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1564 return true;
1565
1566 return false;
1567}
1568
1569bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1570 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1571}
1572
1573bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1574 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1575 return Visit(TSInfo->getTypeLoc());
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1595 DependentTemplateSpecializationTypeLoc TL) {
1596 // Visit the nested-name-specifier, if there is one.
1597 if (TL.getQualifierLoc() &&
1598 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1599 return true;
1600
1601 // Visit the template arguments.
1602 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1603 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1604 return true;
1605
1606 return false;
1607}
1608
1609bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1610 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 return Visit(TL.getNamedTypeLoc());
1614}
1615
1616bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1617 return Visit(TL.getPatternLoc());
1618}
1619
1620bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1621 if (Expr *E = TL.getUnderlyingExpr())
1622 return Visit(MakeCXCursor(E, StmtParent, TU));
1623
1624 return false;
1625}
1626
1627bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1628 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1629}
1630
1631bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1632 return Visit(TL.getValueLoc());
1633}
1634
1635#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1636bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1637 return Visit##PARENT##Loc(TL); \
1638}
1639
1640DEFAULT_TYPELOC_IMPL(Complex, Type)
1641DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1646DEFAULT_TYPELOC_IMPL(Vector, Type)
1647DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1648DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1649DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1650DEFAULT_TYPELOC_IMPL(Record, TagType)
1651DEFAULT_TYPELOC_IMPL(Enum, TagType)
1652DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1653DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1654DEFAULT_TYPELOC_IMPL(Auto, Type)
1655
1656bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1657 // Visit the nested-name-specifier, if present.
1658 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1659 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1660 return true;
1661
1662 if (D->isCompleteDefinition()) {
1663 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1664 E = D->bases_end(); I != E; ++I) {
1665 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1666 return true;
1667 }
1668 }
1669
1670 return VisitTagDecl(D);
1671}
1672
1673bool CursorVisitor::VisitAttributes(Decl *D) {
1674 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1675 i != e; ++i)
1676 if (Visit(MakeCXCursor(*i, D, TU)))
1677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001711 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
1847 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1848 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001860
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001861private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001862 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001863 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1864 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001865 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1866 void AddStmt(const Stmt *S);
1867 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001868 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001869 void EnqueueChildren(const Stmt *S);
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001870 void EnqueueChildren(const OMPClause *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001871};
1872} // end anonyous namespace
1873
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001874void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001875 // 'S' should always be non-null, since it comes from the
1876 // statement we are visiting.
1877 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1878}
1879
1880void
1881EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1882 if (Qualifier)
1883 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1884}
1885
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001886void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001887 if (S)
1888 WL.push_back(StmtVisit(S, Parent));
1889}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001890void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001891 if (D)
1892 WL.push_back(DeclVisit(D, Parent, isFirst));
1893}
1894void EnqueueVisitor::
1895 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1896 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001897 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001898}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001899void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 if (D)
1901 WL.push_back(MemberRefVisit(D, L, Parent));
1902}
1903void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1904 if (TI)
1905 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1906 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001907void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001908 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001909 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001910 AddStmt(*Child);
1911 }
1912 if (size == WL.size())
1913 return;
1914 // Now reverse the entries we just added. This will match the DFS
1915 // ordering performed by the worklist.
1916 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1917 std::reverse(I, E);
1918}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001919namespace {
1920class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1921 EnqueueVisitor *Visitor;
1922public:
1923 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1924#define OPENMP_CLAUSE(Name, Class) \
1925 void Visit##Class(const Class *C);
1926#include "clang/Basic/OpenMPKinds.def"
1927};
1928
1929void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
1930#define PROCESS_OMP_CLAUSE_LIST(Class, Node) \
1931 for (OMPVarList<Class>::varlist_const_iterator I = Node->varlist_begin(), \
1932 E = Node->varlist_end(); \
1933 I != E; ++I) \
1934 Visitor->AddStmt(*I);
1935
1936void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
1937 PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
1938}
Alexey Bataev0c018352013-09-06 18:03:48 +00001939void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
1940 PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
1941}
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00001942#undef PROCESS_OMP_CLAUSE_LIST
1943}
1944void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1945 unsigned size = WL.size();
1946 OMPClauseEnqueue Visitor(this);
1947 Visitor.Visit(S);
1948 if (size == WL.size())
1949 return;
1950 // Now reverse the entries we just added. This will match the DFS
1951 // ordering performed by the worklist.
1952 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1953 std::reverse(I, E);
1954}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001955void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001956 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1957}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001958void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001959 AddDecl(B->getBlockDecl());
1960}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001961void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001962 EnqueueChildren(E);
1963 AddTypeLoc(E->getTypeSourceInfo());
1964}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001965void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1966 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001967 E = S->body_rend(); I != E; ++I) {
1968 AddStmt(*I);
1969 }
1970}
1971void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001972VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001973 AddStmt(S->getSubStmt());
1974 AddDeclarationNameInfo(S);
1975 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1976 AddNestedNameSpecifierLoc(QualifierLoc);
1977}
1978
1979void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001980VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001981 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1982 AddDeclarationNameInfo(E);
1983 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1984 AddNestedNameSpecifierLoc(QualifierLoc);
1985 if (!E->isImplicitAccess())
1986 AddStmt(E->getBase());
1987}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001988void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001989 // Enqueue the initializer , if any.
1990 AddStmt(E->getInitializer());
1991 // Enqueue the array size, if any.
1992 AddStmt(E->getArraySize());
1993 // Enqueue the allocated type.
1994 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1995 // Enqueue the placement arguments.
1996 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1997 AddStmt(E->getPlacementArg(I-1));
1998}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002000 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2001 AddStmt(CE->getArg(I-1));
2002 AddStmt(CE->getCallee());
2003 AddStmt(CE->getArg(0));
2004}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2006 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002007 // Visit the name of the type being destroyed.
2008 AddTypeLoc(E->getDestroyedTypeInfo());
2009 // Visit the scope type that looks disturbingly like the nested-name-specifier
2010 // but isn't.
2011 AddTypeLoc(E->getScopeTypeInfo());
2012 // Visit the nested-name-specifier.
2013 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2014 AddNestedNameSpecifierLoc(QualifierLoc);
2015 // Visit base expression.
2016 AddStmt(E->getBase());
2017}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002018void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2019 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002020 AddTypeLoc(E->getTypeSourceInfo());
2021}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2023 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002024 EnqueueChildren(E);
2025 AddTypeLoc(E->getTypeSourceInfo());
2026}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002027void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002028 EnqueueChildren(E);
2029 if (E->isTypeOperand())
2030 AddTypeLoc(E->getTypeOperandSourceInfo());
2031}
2032
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002033void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2034 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002035 EnqueueChildren(E);
2036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002039 EnqueueChildren(E);
2040 if (E->isTypeOperand())
2041 AddTypeLoc(E->getTypeOperandSourceInfo());
2042}
2043
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002045 EnqueueChildren(S);
2046 AddDecl(S->getExceptionDecl());
2047}
2048
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002050 if (DR->hasExplicitTemplateArgs()) {
2051 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2052 }
2053 WL.push_back(DeclRefExprParts(DR, Parent));
2054}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2056 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002057 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2058 AddDeclarationNameInfo(E);
2059 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2060}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002062 unsigned size = WL.size();
2063 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002064 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002065 D != DEnd; ++D) {
2066 AddDecl(*D, isFirst);
2067 isFirst = false;
2068 }
2069 if (size == WL.size())
2070 return;
2071 // Now reverse the entries we just added. This will match the DFS
2072 // ordering performed by the worklist.
2073 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2074 std::reverse(I, E);
2075}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002077 AddStmt(E->getInit());
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002078 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002079 D = E->designators_rbegin(), DEnd = E->designators_rend();
2080 D != DEnd; ++D) {
2081 if (D->isFieldDesignator()) {
2082 if (FieldDecl *Field = D->getField())
2083 AddMemberRef(Field, D->getFieldLoc());
2084 continue;
2085 }
2086 if (D->isArrayDesignator()) {
2087 AddStmt(E->getArrayIndex(*D));
2088 continue;
2089 }
2090 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2091 AddStmt(E->getArrayRangeEnd(*D));
2092 AddStmt(E->getArrayRangeStart(*D));
2093 }
2094}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002095void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002096 EnqueueChildren(E);
2097 AddTypeLoc(E->getTypeInfoAsWritten());
2098}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002100 AddStmt(FS->getBody());
2101 AddStmt(FS->getInc());
2102 AddStmt(FS->getCond());
2103 AddDecl(FS->getConditionVariable());
2104 AddStmt(FS->getInit());
2105}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002107 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2108}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002110 AddStmt(If->getElse());
2111 AddStmt(If->getThen());
2112 AddStmt(If->getCond());
2113 AddDecl(If->getConditionVariable());
2114}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002116 // We care about the syntactic form of the initializer list, only.
2117 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2118 IE = Syntactic;
2119 EnqueueChildren(IE);
2120}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002122 WL.push_back(MemberExprParts(M, Parent));
2123
2124 // If the base of the member access expression is an implicit 'this', don't
2125 // visit it.
2126 // FIXME: If we ever want to show these implicit accesses, this will be
2127 // unfortunate. However, clang_getCursor() relies on this behavior.
2128 if (!M->isImplicitAccess())
2129 AddStmt(M->getBase());
2130}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002132 AddTypeLoc(E->getEncodedTypeSourceInfo());
2133}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002135 EnqueueChildren(M);
2136 AddTypeLoc(M->getClassReceiverTypeInfo());
2137}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002139 // Visit the components of the offsetof expression.
2140 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2141 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2142 const OffsetOfNode &Node = E->getComponent(I-1);
2143 switch (Node.getKind()) {
2144 case OffsetOfNode::Array:
2145 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2146 break;
2147 case OffsetOfNode::Field:
2148 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2149 break;
2150 case OffsetOfNode::Identifier:
2151 case OffsetOfNode::Base:
2152 continue;
2153 }
2154 }
2155 // Visit the type into which we're computing the offset.
2156 AddTypeLoc(E->getTypeSourceInfo());
2157}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002159 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2160 WL.push_back(OverloadExprParts(E, Parent));
2161}
2162void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002163 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002164 EnqueueChildren(E);
2165 if (E->isArgumentType())
2166 AddTypeLoc(E->getArgumentTypeInfo());
2167}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002169 EnqueueChildren(S);
2170}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002172 AddStmt(S->getBody());
2173 AddStmt(S->getCond());
2174 AddDecl(S->getConditionVariable());
2175}
2176
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002178 AddStmt(W->getBody());
2179 AddStmt(W->getCond());
2180 AddDecl(W->getConditionVariable());
2181}
2182
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002184 AddTypeLoc(E->getQueriedTypeSourceInfo());
2185}
2186
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002188 AddTypeLoc(E->getRhsTypeSourceInfo());
2189 AddTypeLoc(E->getLhsTypeSourceInfo());
2190}
2191
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002193 for (unsigned I = E->getNumArgs(); I > 0; --I)
2194 AddTypeLoc(E->getArg(I-1));
2195}
2196
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002198 AddTypeLoc(E->getQueriedTypeSourceInfo());
2199}
2200
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002202 EnqueueChildren(E);
2203}
2204
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002206 VisitOverloadExpr(U);
2207 if (!U->isImplicitAccess())
2208 AddStmt(U->getBase());
2209}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002210void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002211 AddStmt(E->getSubExpr());
2212 AddTypeLoc(E->getWrittenTypeInfo());
2213}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002215 WL.push_back(SizeOfPackExprParts(E, Parent));
2216}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002218 // If the opaque value has a source expression, just transparently
2219 // visit that. This is useful for (e.g.) pseudo-object expressions.
2220 if (Expr *SourceExpr = E->getSourceExpr())
2221 return Visit(SourceExpr);
2222}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002224 AddStmt(E->getBody());
2225 WL.push_back(LambdaExprParts(E, Parent));
2226}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002228 // Treat the expression like its syntactic form.
2229 Visit(E->getSyntacticForm());
2230}
2231
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00002232void EnqueueVisitor::VisitOMPExecutableDirective(
2233 const OMPExecutableDirective *D) {
2234 EnqueueChildren(D);
2235 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2236 E = D->clauses().end();
2237 I != E; ++I)
2238 EnqueueChildren(*I);
2239}
2240
2241void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2242 VisitOMPExecutableDirective(D);
2243}
2244
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002245void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002246 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2247}
2248
2249bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2250 if (RegionOfInterest.isValid()) {
2251 SourceRange Range = getRawCursorExtent(C);
2252 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2253 return false;
2254 }
2255 return true;
2256}
2257
2258bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2259 while (!WL.empty()) {
2260 // Dequeue the worklist item.
Robert Wilhelm344472e2013-08-23 16:11:15 +00002261 VisitorJob LI = WL.pop_back_val();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002262
2263 // Set the Parent field, then back to its old value once we're done.
2264 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2265
2266 switch (LI.getKind()) {
2267 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002268 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002269 if (!D)
2270 continue;
2271
2272 // For now, perform default visitation for Decls.
2273 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2274 cast<DeclVisit>(&LI)->isFirst())))
2275 return true;
2276
2277 continue;
2278 }
2279 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2280 const ASTTemplateArgumentListInfo *ArgList =
2281 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2282 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2283 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2284 Arg != ArgEnd; ++Arg) {
2285 if (VisitTemplateArgumentLoc(*Arg))
2286 return true;
2287 }
2288 continue;
2289 }
2290 case VisitorJob::TypeLocVisitKind: {
2291 // Perform default visitation for TypeLocs.
2292 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2293 return true;
2294 continue;
2295 }
2296 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002297 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002298 if (LabelStmt *stmt = LS->getStmt()) {
2299 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2300 TU))) {
2301 return true;
2302 }
2303 }
2304 continue;
2305 }
2306
2307 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2308 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2309 if (VisitNestedNameSpecifierLoc(V->get()))
2310 return true;
2311 continue;
2312 }
2313
2314 case VisitorJob::DeclarationNameInfoVisitKind: {
2315 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2316 ->get()))
2317 return true;
2318 continue;
2319 }
2320 case VisitorJob::MemberRefVisitKind: {
2321 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2322 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2323 return true;
2324 continue;
2325 }
2326 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002327 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002328 if (!S)
2329 continue;
2330
2331 // Update the current cursor.
2332 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2333 if (!IsInRegionOfInterest(Cursor))
2334 continue;
2335 switch (Visitor(Cursor, Parent, ClientData)) {
2336 case CXChildVisit_Break: return true;
2337 case CXChildVisit_Continue: break;
2338 case CXChildVisit_Recurse:
2339 if (PostChildrenVisitor)
2340 WL.push_back(PostChildrenVisit(0, Cursor));
2341 EnqueueWorkList(WL, S);
2342 break;
2343 }
2344 continue;
2345 }
2346 case VisitorJob::MemberExprPartsKind: {
2347 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002348 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002349
2350 // Visit the nested-name-specifier
2351 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2352 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2353 return true;
2354
2355 // Visit the declaration name.
2356 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2357 return true;
2358
2359 // Visit the explicitly-specified template arguments, if any.
2360 if (M->hasExplicitTemplateArgs()) {
2361 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2362 *ArgEnd = Arg + M->getNumTemplateArgs();
2363 Arg != ArgEnd; ++Arg) {
2364 if (VisitTemplateArgumentLoc(*Arg))
2365 return true;
2366 }
2367 }
2368 continue;
2369 }
2370 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002371 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002372 // Visit nested-name-specifier, if present.
2373 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2374 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2375 return true;
2376 // Visit declaration name.
2377 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2378 return true;
2379 continue;
2380 }
2381 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002382 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002383 // Visit the nested-name-specifier.
2384 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2385 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2386 return true;
2387 // Visit the declaration name.
2388 if (VisitDeclarationNameInfo(O->getNameInfo()))
2389 return true;
2390 // Visit the overloaded declaration reference.
2391 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2392 return true;
2393 continue;
2394 }
2395 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002396 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002397 NamedDecl *Pack = E->getPack();
2398 if (isa<TemplateTypeParmDecl>(Pack)) {
2399 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2400 E->getPackLoc(), TU)))
2401 return true;
2402
2403 continue;
2404 }
2405
2406 if (isa<TemplateTemplateParmDecl>(Pack)) {
2407 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2408 E->getPackLoc(), TU)))
2409 return true;
2410
2411 continue;
2412 }
2413
2414 // Non-type template parameter packs and function parameter packs are
2415 // treated like DeclRefExpr cursors.
2416 continue;
2417 }
2418
2419 case VisitorJob::LambdaExprPartsKind: {
2420 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002421 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002422 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2423 CEnd = E->explicit_capture_end();
2424 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002425 // FIXME: Lambda init-captures.
2426 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002427 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002428
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002429 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2430 C->getLocation(),
2431 TU)))
2432 return true;
2433 }
2434
2435 // Visit parameters and return type, if present.
2436 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2437 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2438 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2439 // Visit the whole type.
2440 if (Visit(TL))
2441 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002442 } else if (FunctionProtoTypeLoc Proto =
2443 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002444 if (E->hasExplicitParameters()) {
2445 // Visit parameters.
2446 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2447 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2448 return true;
2449 } else {
2450 // Visit result type.
2451 if (Visit(Proto.getResultLoc()))
2452 return true;
2453 }
2454 }
2455 }
2456 break;
2457 }
2458
2459 case VisitorJob::PostChildrenVisitKind:
2460 if (PostChildrenVisitor(Parent, ClientData))
2461 return true;
2462 break;
2463 }
2464 }
2465 return false;
2466}
2467
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002468bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002469 VisitorWorkList *WL = 0;
2470 if (!WorkListFreeList.empty()) {
2471 WL = WorkListFreeList.back();
2472 WL->clear();
2473 WorkListFreeList.pop_back();
2474 }
2475 else {
2476 WL = new VisitorWorkList();
2477 WorkListCache.push_back(WL);
2478 }
2479 EnqueueWorkList(*WL, S);
2480 bool result = RunVisitorWorkList(*WL);
2481 WorkListFreeList.push_back(WL);
2482 return result;
2483}
2484
2485namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002486typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002487RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2488 const DeclarationNameInfo &NI,
2489 const SourceRange &QLoc,
2490 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2491 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2492 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2493 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2494
2495 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2496
2497 RefNamePieces Pieces;
2498
2499 if (WantQualifier && QLoc.isValid())
2500 Pieces.push_back(QLoc);
2501
2502 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2503 Pieces.push_back(NI.getLoc());
2504
2505 if (WantTemplateArgs && TemplateArgs)
2506 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2507 TemplateArgs->RAngleLoc));
2508
2509 if (Kind == DeclarationName::CXXOperatorName) {
2510 Pieces.push_back(SourceLocation::getFromRawEncoding(
2511 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2512 Pieces.push_back(SourceLocation::getFromRawEncoding(
2513 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2514 }
2515
2516 if (WantSinglePiece) {
2517 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2518 Pieces.clear();
2519 Pieces.push_back(R);
2520 }
2521
2522 return Pieces;
2523}
2524}
2525
2526//===----------------------------------------------------------------------===//
2527// Misc. API hooks.
2528//===----------------------------------------------------------------------===//
2529
2530static llvm::sys::Mutex EnableMultithreadingMutex;
2531static bool EnabledMultithreading;
2532
Chad Rosier90836282013-03-27 18:28:23 +00002533static void fatal_error_handler(void *user_data, const std::string& reason,
2534 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002535 // Write the result out to stderr avoiding errs() because raw_ostreams can
2536 // call report_fatal_error.
2537 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2538 ::abort();
2539}
2540
2541extern "C" {
2542CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2543 int displayDiagnostics) {
2544 // Disable pretty stack trace functionality, which will otherwise be a very
2545 // poor citizen of the world and set up all sorts of signal handlers.
2546 llvm::DisablePrettyStackTrace = true;
2547
2548 // We use crash recovery to make some of our APIs more reliable, implicitly
2549 // enable it.
2550 llvm::CrashRecoveryContext::Enable();
2551
2552 // Enable support for multithreading in LLVM.
2553 {
2554 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2555 if (!EnabledMultithreading) {
2556 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2557 llvm::llvm_start_multithreaded();
2558 EnabledMultithreading = true;
2559 }
2560 }
2561
2562 CIndexer *CIdxr = new CIndexer();
2563 if (excludeDeclarationsFromPCH)
2564 CIdxr->setOnlyLocalDecls();
2565 if (displayDiagnostics)
2566 CIdxr->setDisplayDiagnostics();
2567
2568 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2569 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2570 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2571 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2572 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2573 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2574
2575 return CIdxr;
2576}
2577
2578void clang_disposeIndex(CXIndex CIdx) {
2579 if (CIdx)
2580 delete static_cast<CIndexer *>(CIdx);
2581}
2582
2583void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2584 if (CIdx)
2585 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2586}
2587
2588unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2589 if (CIdx)
2590 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2591 return 0;
2592}
2593
2594void clang_toggleCrashRecovery(unsigned isEnabled) {
2595 if (isEnabled)
2596 llvm::CrashRecoveryContext::Enable();
2597 else
2598 llvm::CrashRecoveryContext::Disable();
2599}
2600
2601CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2602 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002603 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002604 return 0;
2605
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002606 LOG_FUNC_SECTION {
2607 *Log << ast_filename;
2608 }
2609
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002610 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2611 FileSystemOptions FileSystemOpts;
2612
2613 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2614 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2615 CXXIdx->getOnlyLocalDecls(),
2616 0, 0,
2617 /*CaptureDiagnostics=*/true,
2618 /*AllowPCHWithCompilerErrors=*/true,
2619 /*UserFilesAreVolatile=*/true);
2620 return MakeCXTranslationUnit(CXXIdx, TU);
2621}
2622
2623unsigned clang_defaultEditingTranslationUnitOptions() {
2624 return CXTranslationUnit_PrecompiledPreamble |
2625 CXTranslationUnit_CacheCompletionResults;
2626}
2627
2628CXTranslationUnit
2629clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2630 const char *source_filename,
2631 int num_command_line_args,
2632 const char * const *command_line_args,
2633 unsigned num_unsaved_files,
2634 struct CXUnsavedFile *unsaved_files) {
2635 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2636 return clang_parseTranslationUnit(CIdx, source_filename,
2637 command_line_args, num_command_line_args,
2638 unsaved_files, num_unsaved_files,
2639 Options);
2640}
2641
2642struct ParseTranslationUnitInfo {
2643 CXIndex CIdx;
2644 const char *source_filename;
2645 const char *const *command_line_args;
2646 int num_command_line_args;
2647 struct CXUnsavedFile *unsaved_files;
2648 unsigned num_unsaved_files;
2649 unsigned options;
2650 CXTranslationUnit result;
2651};
2652static void clang_parseTranslationUnit_Impl(void *UserData) {
2653 ParseTranslationUnitInfo *PTUI =
2654 static_cast<ParseTranslationUnitInfo*>(UserData);
2655 CXIndex CIdx = PTUI->CIdx;
2656 const char *source_filename = PTUI->source_filename;
2657 const char * const *command_line_args = PTUI->command_line_args;
2658 int num_command_line_args = PTUI->num_command_line_args;
2659 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2660 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2661 unsigned options = PTUI->options;
2662 PTUI->result = 0;
2663
2664 if (!CIdx)
2665 return;
2666
2667 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2668
2669 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2670 setThreadBackgroundPriority();
2671
2672 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2673 // FIXME: Add a flag for modules.
2674 TranslationUnitKind TUKind
2675 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2676 bool CacheCodeCompetionResults
2677 = options & CXTranslationUnit_CacheCompletionResults;
2678 bool IncludeBriefCommentsInCodeCompletion
2679 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2680 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2681 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2682
2683 // Configure the diagnostics.
2684 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002685 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002686
2687 // Recover resources if we crash before exiting this function.
2688 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2689 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2690 DiagCleanup(Diags.getPtr());
2691
2692 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2693 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2694
2695 // Recover resources if we crash before exiting this function.
2696 llvm::CrashRecoveryContextCleanupRegistrar<
2697 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2698
2699 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2700 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2701 const llvm::MemoryBuffer *Buffer
2702 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2703 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2704 Buffer));
2705 }
2706
2707 OwningPtr<std::vector<const char *> >
2708 Args(new std::vector<const char*>());
2709
2710 // Recover resources if we crash before exiting this method.
2711 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2712 ArgsCleanup(Args.get());
2713
2714 // Since the Clang C library is primarily used by batch tools dealing with
2715 // (often very broken) source code, where spell-checking can have a
2716 // significant negative impact on performance (particularly when
2717 // precompiled headers are involved), we disable it by default.
2718 // Only do this if we haven't found a spell-checking-related argument.
2719 bool FoundSpellCheckingArgument = false;
2720 for (int I = 0; I != num_command_line_args; ++I) {
2721 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2722 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2723 FoundSpellCheckingArgument = true;
2724 break;
2725 }
2726 }
2727 if (!FoundSpellCheckingArgument)
2728 Args->push_back("-fno-spell-checking");
2729
2730 Args->insert(Args->end(), command_line_args,
2731 command_line_args + num_command_line_args);
2732
2733 // The 'source_filename' argument is optional. If the caller does not
2734 // specify it then it is assumed that the source file is specified
2735 // in the actual argument list.
2736 // Put the source file after command_line_args otherwise if '-x' flag is
2737 // present it will be unused.
2738 if (source_filename)
2739 Args->push_back(source_filename);
2740
2741 // Do we need the detailed preprocessing record?
2742 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2743 Args->push_back("-Xclang");
2744 Args->push_back("-detailed-preprocessing-record");
2745 }
2746
2747 unsigned NumErrors = Diags->getClient()->getNumErrors();
2748 OwningPtr<ASTUnit> ErrUnit;
2749 OwningPtr<ASTUnit> Unit(
2750 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2751 /* vector::data() not portable */,
2752 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2753 Diags,
2754 CXXIdx->getClangResourcesPath(),
2755 CXXIdx->getOnlyLocalDecls(),
2756 /*CaptureDiagnostics=*/true,
2757 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2758 RemappedFiles->size(),
2759 /*RemappedFilesKeepOriginalName=*/true,
2760 PrecompilePreamble,
2761 TUKind,
2762 CacheCodeCompetionResults,
2763 IncludeBriefCommentsInCodeCompletion,
2764 /*AllowPCHWithCompilerErrors=*/true,
2765 SkipFunctionBodies,
2766 /*UserFilesAreVolatile=*/true,
2767 ForSerialization,
2768 &ErrUnit));
2769
2770 if (NumErrors != Diags->getClient()->getNumErrors()) {
2771 // Make sure to check that 'Unit' is non-NULL.
2772 if (CXXIdx->getDisplayDiagnostics())
2773 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2774 }
2775
2776 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2777}
2778CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2779 const char *source_filename,
2780 const char * const *command_line_args,
2781 int num_command_line_args,
2782 struct CXUnsavedFile *unsaved_files,
2783 unsigned num_unsaved_files,
2784 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002785 LOG_FUNC_SECTION {
2786 *Log << source_filename << ": ";
2787 for (int i = 0; i != num_command_line_args; ++i)
2788 *Log << command_line_args[i] << " ";
2789 }
2790
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002791 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2792 num_command_line_args, unsaved_files,
2793 num_unsaved_files, options, 0 };
2794 llvm::CrashRecoveryContext CRC;
2795
2796 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2797 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2798 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2799 fprintf(stderr, " 'command_line_args' : [");
2800 for (int i = 0; i != num_command_line_args; ++i) {
2801 if (i)
2802 fprintf(stderr, ", ");
2803 fprintf(stderr, "'%s'", command_line_args[i]);
2804 }
2805 fprintf(stderr, "],\n");
2806 fprintf(stderr, " 'unsaved_files' : [");
2807 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2808 if (i)
2809 fprintf(stderr, ", ");
2810 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2811 unsaved_files[i].Length);
2812 }
2813 fprintf(stderr, "],\n");
2814 fprintf(stderr, " 'options' : %d,\n", options);
2815 fprintf(stderr, "}\n");
2816
2817 return 0;
2818 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2819 PrintLibclangResourceUsage(PTUI.result);
2820 }
2821
2822 return PTUI.result;
2823}
2824
2825unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2826 return CXSaveTranslationUnit_None;
2827}
2828
2829namespace {
2830
2831struct SaveTranslationUnitInfo {
2832 CXTranslationUnit TU;
2833 const char *FileName;
2834 unsigned options;
2835 CXSaveError result;
2836};
2837
2838}
2839
2840static void clang_saveTranslationUnit_Impl(void *UserData) {
2841 SaveTranslationUnitInfo *STUI =
2842 static_cast<SaveTranslationUnitInfo*>(UserData);
2843
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002844 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002845 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2846 setThreadBackgroundPriority();
2847
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002848 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002849 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2850}
2851
2852int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2853 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002854 LOG_FUNC_SECTION {
2855 *Log << TU << ' ' << FileName;
2856 }
2857
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002858 if (!TU)
2859 return CXSaveError_InvalidTU;
2860
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002861 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002862 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2863 if (!CXXUnit->hasSema())
2864 return CXSaveError_InvalidTU;
2865
2866 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2867
2868 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2869 getenv("LIBCLANG_NOTHREADS")) {
2870 clang_saveTranslationUnit_Impl(&STUI);
2871
2872 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2873 PrintLibclangResourceUsage(TU);
2874
2875 return STUI.result;
2876 }
2877
2878 // We have an AST that has invalid nodes due to compiler errors.
2879 // Use a crash recovery thread for protection.
2880
2881 llvm::CrashRecoveryContext CRC;
2882
2883 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2884 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2885 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2886 fprintf(stderr, " 'options' : %d,\n", options);
2887 fprintf(stderr, "}\n");
2888
2889 return CXSaveError_Unknown;
2890
2891 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2892 PrintLibclangResourceUsage(TU);
2893 }
2894
2895 return STUI.result;
2896}
2897
2898void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2899 if (CTUnit) {
2900 // If the translation unit has been marked as unsafe to free, just discard
2901 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002902 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002903 return;
2904
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002905 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002906 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002907 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2908 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002909 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002910 delete CTUnit;
2911 }
2912}
2913
2914unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2915 return CXReparse_None;
2916}
2917
2918struct ReparseTranslationUnitInfo {
2919 CXTranslationUnit TU;
2920 unsigned num_unsaved_files;
2921 struct CXUnsavedFile *unsaved_files;
2922 unsigned options;
2923 int result;
2924};
2925
2926static void clang_reparseTranslationUnit_Impl(void *UserData) {
2927 ReparseTranslationUnitInfo *RTUI =
2928 static_cast<ReparseTranslationUnitInfo*>(UserData);
2929 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002930 if (!TU)
2931 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002932
2933 // Reset the associated diagnostics.
2934 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2935 TU->Diagnostics = 0;
2936
2937 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2938 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2939 unsigned options = RTUI->options;
2940 (void) options;
2941 RTUI->result = 1;
2942
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002943 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002944 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2945 setThreadBackgroundPriority();
2946
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002947 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002948 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2949
2950 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2951 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2952
2953 // Recover resources if we crash before exiting this function.
2954 llvm::CrashRecoveryContextCleanupRegistrar<
2955 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2956
2957 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2958 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2959 const llvm::MemoryBuffer *Buffer
2960 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2961 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2962 Buffer));
2963 }
2964
2965 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2966 RemappedFiles->size()))
2967 RTUI->result = 0;
2968}
2969
2970int clang_reparseTranslationUnit(CXTranslationUnit TU,
2971 unsigned num_unsaved_files,
2972 struct CXUnsavedFile *unsaved_files,
2973 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002974 LOG_FUNC_SECTION {
2975 *Log << TU;
2976 }
2977
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002978 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2979 options, 0 };
2980
2981 if (getenv("LIBCLANG_NOTHREADS")) {
2982 clang_reparseTranslationUnit_Impl(&RTUI);
2983 return RTUI.result;
2984 }
2985
2986 llvm::CrashRecoveryContext CRC;
2987
2988 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2989 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002990 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002991 return 1;
2992 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2993 PrintLibclangResourceUsage(TU);
2994
2995 return RTUI.result;
2996}
2997
2998
2999CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3000 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003001 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003002
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003003 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003004 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003005}
3006
3007CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00003008 if (!TU)
3009 return clang_getNullCursor();
3010
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003011 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003012 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3013}
3014
3015} // end: extern "C"
3016
3017//===----------------------------------------------------------------------===//
3018// CXFile Operations.
3019//===----------------------------------------------------------------------===//
3020
3021extern "C" {
3022CXString clang_getFileName(CXFile SFile) {
3023 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00003024 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003025
3026 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003027 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003028}
3029
3030time_t clang_getFileTime(CXFile SFile) {
3031 if (!SFile)
3032 return 0;
3033
3034 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3035 return FEnt->getModificationTime();
3036}
3037
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003038CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3039 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003040 return 0;
3041
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003042 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003043
3044 FileManager &FMgr = CXXUnit->getFileManager();
3045 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3046}
3047
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003048unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
3049 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003050 return 0;
3051
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003053 FileEntry *FEnt = static_cast<FileEntry *>(file);
3054 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3055 .isFileMultipleIncludeGuarded(FEnt);
3056}
3057
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003058int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3059 if (!file || !outID)
3060 return 1;
3061
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003062 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindola0fda0f72013-08-01 21:42:11 +00003063 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3064 outID->data[0] = ID.getDevice();
3065 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003066 outID->data[2] = FEnt->getModificationTime();
3067 return 0;
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003068}
3069
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003070} // end: extern "C"
3071
3072//===----------------------------------------------------------------------===//
3073// CXCursor Operations.
3074//===----------------------------------------------------------------------===//
3075
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003076static const Decl *getDeclFromExpr(const Stmt *E) {
3077 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003078 return getDeclFromExpr(CE->getSubExpr());
3079
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003080 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003081 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003082 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003083 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003084 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003085 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003086 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003087 if (PRE->isExplicitProperty())
3088 return PRE->getExplicitProperty();
3089 // It could be messaging both getter and setter as in:
3090 // ++myobj.myprop;
3091 // in which case prefer to associate the setter since it is less obvious
3092 // from inspecting the source that the setter is going to get called.
3093 if (PRE->isMessagingSetter())
3094 return PRE->getImplicitPropertySetter();
3095 return PRE->getImplicitPropertyGetter();
3096 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003097 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003098 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003099 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003100 if (Expr *Src = OVE->getSourceExpr())
3101 return getDeclFromExpr(Src);
3102
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003103 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003104 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003105 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003106 if (!CE->isElidable())
3107 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003108 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003109 return OME->getMethodDecl();
3110
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003111 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003112 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003113 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003114 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3115 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003116 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003117 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3118 isa<ParmVarDecl>(SizeOfPack->getPack()))
3119 return SizeOfPack->getPack();
3120
3121 return 0;
3122}
3123
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003124static SourceLocation getLocationFromExpr(const Expr *E) {
3125 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003126 return getLocationFromExpr(CE->getSubExpr());
3127
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003128 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003129 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003130 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003131 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003132 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003133 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003134 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003135 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003136 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003137 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003138 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003139 return PropRef->getLocation();
3140
3141 return E->getLocStart();
3142}
3143
3144extern "C" {
3145
3146unsigned clang_visitChildren(CXCursor parent,
3147 CXCursorVisitor visitor,
3148 CXClientData client_data) {
3149 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3150 /*VisitPreprocessorLast=*/false);
3151 return CursorVis.VisitChildren(parent);
3152}
3153
3154#ifndef __has_feature
3155#define __has_feature(x) 0
3156#endif
3157#if __has_feature(blocks)
3158typedef enum CXChildVisitResult
3159 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3160
3161static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3162 CXClientData client_data) {
3163 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3164 return block(cursor, parent);
3165}
3166#else
3167// If we are compiled with a compiler that doesn't have native blocks support,
3168// define and call the block manually, so the
3169typedef struct _CXChildVisitResult
3170{
3171 void *isa;
3172 int flags;
3173 int reserved;
3174 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3175 CXCursor);
3176} *CXCursorVisitorBlock;
3177
3178static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3179 CXClientData client_data) {
3180 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3181 return block->invoke(block, cursor, parent);
3182}
3183#endif
3184
3185
3186unsigned clang_visitChildrenWithBlock(CXCursor parent,
3187 CXCursorVisitorBlock block) {
3188 return clang_visitChildren(parent, visitWithBlock, block);
3189}
3190
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003191static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003193 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003194
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003195 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003196 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003197 if (const ObjCPropertyImplDecl *PropImpl =
3198 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003200 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003201
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003202 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003204 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003205
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003206 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003207 }
3208
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003209 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003210 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003211
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003212 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003213 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3214 // and returns different names. NamedDecl returns the class name and
3215 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003216 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003217
3218 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003219 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003220
3221 SmallString<1024> S;
3222 llvm::raw_svector_ostream os(S);
3223 ND->printName(os);
3224
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003225 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003226}
3227
3228CXString clang_getCursorSpelling(CXCursor C) {
3229 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003230 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003231
3232 if (clang_isReference(C.kind)) {
3233 switch (C.kind) {
3234 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003235 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003236 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003237 }
3238 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003239 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003240 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003241 }
3242 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003243 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003244 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003245 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246 }
3247 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003248 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003249 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003250 }
3251 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003252 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003253 assert(Type && "Missing type decl");
3254
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003255 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003256 getAsString());
3257 }
3258 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003259 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003260 assert(Template && "Missing template decl");
3261
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003262 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003263 }
3264
3265 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003266 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003267 assert(NS && "Missing namespace decl");
3268
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003269 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003270 }
3271
3272 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003273 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003274 assert(Field && "Missing member decl");
3275
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003276 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003277 }
3278
3279 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003280 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003281 assert(Label && "Missing label");
3282
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003283 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003284 }
3285
3286 case CXCursor_OverloadedDeclRef: {
3287 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003288 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3289 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003290 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003291 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003292 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003293 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003294 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003295 OverloadedTemplateStorage *Ovl
3296 = Storage.get<OverloadedTemplateStorage*>();
3297 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003298 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003299 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003300 }
3301
3302 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003303 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003304 assert(Var && "Missing variable decl");
3305
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003306 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003307 }
3308
3309 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003310 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003311 }
3312 }
3313
3314 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003315 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003316 if (D)
3317 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003318 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003319 }
3320
3321 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003322 const Stmt *S = getCursorStmt(C);
3323 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003324 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003325
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003326 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003327 }
3328
3329 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003330 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003331 ->getNameStart());
3332
3333 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003334 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003335 ->getNameStart());
3336
3337 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003338 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003339
3340 if (clang_isDeclaration(C.kind))
3341 return getDeclSpelling(getCursorDecl(C));
3342
3343 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003344 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003345 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003346 }
3347
3348 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003349 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003350 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003351 }
3352
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003353 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003354}
3355
3356CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3357 unsigned pieceIndex,
3358 unsigned options) {
3359 if (clang_Cursor_isNull(C))
3360 return clang_getNullRange();
3361
3362 ASTContext &Ctx = getCursorContext(C);
3363
3364 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003365 const Stmt *S = getCursorStmt(C);
3366 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003367 if (pieceIndex > 0)
3368 return clang_getNullRange();
3369 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3370 }
3371
3372 return clang_getNullRange();
3373 }
3374
3375 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003376 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003377 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3378 if (pieceIndex >= ME->getNumSelectorLocs())
3379 return clang_getNullRange();
3380 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3381 }
3382 }
3383
3384 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3385 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003386 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003387 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3388 if (pieceIndex >= MD->getNumSelectorLocs())
3389 return clang_getNullRange();
3390 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3391 }
3392 }
3393
3394 if (C.kind == CXCursor_ObjCCategoryDecl ||
3395 C.kind == CXCursor_ObjCCategoryImplDecl) {
3396 if (pieceIndex > 0)
3397 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003398 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003399 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3400 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003401 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003402 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3403 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3404 }
3405
3406 if (C.kind == CXCursor_ModuleImportDecl) {
3407 if (pieceIndex > 0)
3408 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003409 if (const ImportDecl *ImportD =
3410 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003411 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3412 if (!Locs.empty())
3413 return cxloc::translateSourceRange(Ctx,
3414 SourceRange(Locs.front(), Locs.back()));
3415 }
3416 return clang_getNullRange();
3417 }
3418
3419 // FIXME: A CXCursor_InclusionDirective should give the location of the
3420 // filename, but we don't keep track of this.
3421
3422 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3423 // but we don't keep track of this.
3424
3425 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3426 // but we don't keep track of this.
3427
3428 // Default handling, give the location of the cursor.
3429
3430 if (pieceIndex > 0)
3431 return clang_getNullRange();
3432
3433 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3434 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3435 return cxloc::translateSourceRange(Ctx, Loc);
3436}
3437
3438CXString clang_getCursorDisplayName(CXCursor C) {
3439 if (!clang_isDeclaration(C.kind))
3440 return clang_getCursorSpelling(C);
3441
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003442 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003443 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003444 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003445
3446 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003447 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003448 D = FunTmpl->getTemplatedDecl();
3449
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003450 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451 SmallString<64> Str;
3452 llvm::raw_svector_ostream OS(Str);
3453 OS << *Function;
3454 if (Function->getPrimaryTemplate())
3455 OS << "<>";
3456 OS << "(";
3457 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3458 if (I)
3459 OS << ", ";
3460 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3461 }
3462
3463 if (Function->isVariadic()) {
3464 if (Function->getNumParams())
3465 OS << ", ";
3466 OS << "...";
3467 }
3468 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003469 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003470 }
3471
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003472 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 SmallString<64> Str;
3474 llvm::raw_svector_ostream OS(Str);
3475 OS << *ClassTemplate;
3476 OS << "<";
3477 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3478 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3479 if (I)
3480 OS << ", ";
3481
3482 NamedDecl *Param = Params->getParam(I);
3483 if (Param->getIdentifier()) {
3484 OS << Param->getIdentifier()->getName();
3485 continue;
3486 }
3487
3488 // There is no parameter name, which makes this tricky. Try to come up
3489 // with something useful that isn't too long.
3490 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3491 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3492 else if (NonTypeTemplateParmDecl *NTTP
3493 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3494 OS << NTTP->getType().getAsString(Policy);
3495 else
3496 OS << "template<...> class";
3497 }
3498
3499 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003500 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 }
3502
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003503 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003504 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3505 // If the type was explicitly written, use that.
3506 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003507 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003508
Benjamin Kramer5eada842013-02-22 15:46:01 +00003509 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003510 llvm::raw_svector_ostream OS(Str);
3511 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003512 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 ClassSpec->getTemplateArgs().data(),
3514 ClassSpec->getTemplateArgs().size(),
3515 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003516 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 }
3518
3519 return clang_getCursorSpelling(C);
3520}
3521
3522CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3523 switch (Kind) {
3524 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003525 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003526 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003527 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003528 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003529 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003530 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003531 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003532 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003533 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003534 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003535 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003536 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003537 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003538 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003539 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003540 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003541 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003542 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003543 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003544 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003545 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003546 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003547 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003548 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003549 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003550 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003551 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003552 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003553 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003554 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003555 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003556 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003557 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003558 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003559 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003560 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003561 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003562 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003563 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003564 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003565 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003566 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003567 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003568 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003569 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003570 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003571 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003572 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003573 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003574 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003575 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003576 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003577 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003578 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003579 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003580 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003581 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003582 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003583 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003584 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003585 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003586 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003587 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003588 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003589 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003590 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003591 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003592 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003593 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003594 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003595 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003596 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003597 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003598 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003599 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003600 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003601 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003602 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003603 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003604 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003605 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003606 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003607 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003608 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003609 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003610 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003611 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003612 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003613 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003614 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003615 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003616 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003617 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003618 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003619 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003620 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003621 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003622 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003623 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003624 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003625 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003626 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003627 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003628 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003629 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003630 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003631 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003632 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003633 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003634 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003635 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003636 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003637 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003638 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003639 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003640 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003641 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003642 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003643 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003644 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003645 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003646 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003647 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003648 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003650 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003652 case CXCursor_ObjCSelfExpr:
3653 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003654 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003656 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003658 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003660 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003662 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003663 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003664 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003665 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003666 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003667 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003668 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003669 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003670 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003671 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003672 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003673 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003674 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003675 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003676 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003677 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003678 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003680 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003681 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003682 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003683 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003684 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003685 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003686 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003687 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003688 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003689 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003690 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003691 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003692 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003693 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003694 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003695 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003696 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003697 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003698 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003699 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003700 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003701 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003702 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003703 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003704 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003705 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003706 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003707 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003708 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003709 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003710 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003711 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003712 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003713 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003714 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003715 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003716 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003718 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003720 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003722 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003724 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003726 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003728 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003730 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003732 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003734 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003736 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003737 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003738 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003739 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003740 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003741 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003742 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003743 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003744 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003745 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003746 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003747 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003748 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003749 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003750 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003751 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003752 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003753 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003754 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003755 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003756 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003757 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003758 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003759 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003760 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003761 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003762 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003763 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003764 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003765 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003766 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003767 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003768 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003769 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003770 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003771 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003772 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003773 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003774 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003775 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003776 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003777 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003778 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003779 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003780 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003781 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003782 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003783 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003784 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003786 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003788 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003790 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003791 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003792 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003793 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003794 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003795 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003796 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003797 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003798 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003799 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003801 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003802 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003803 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003804 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003805 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003806 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003807 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003808 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003809 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003810 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003812 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003814 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003815 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003816 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003817 return cxstring::createRef("ModuleImport");
Alexey Bataev4fa7eab2013-07-19 03:13:43 +00003818 case CXCursor_OMPParallelDirective:
3819 return cxstring::createRef("OMPParallelDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003820 }
3821
3822 llvm_unreachable("Unhandled CXCursorKind");
3823}
3824
3825struct GetCursorData {
3826 SourceLocation TokenBeginLoc;
3827 bool PointsAtMacroArgExpansion;
3828 bool VisitedObjCPropertyImplDecl;
3829 SourceLocation VisitedDeclaratorDeclStartLoc;
3830 CXCursor &BestCursor;
3831
3832 GetCursorData(SourceManager &SM,
3833 SourceLocation tokenBegin, CXCursor &outputCursor)
3834 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3835 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3836 VisitedObjCPropertyImplDecl = false;
3837 }
3838};
3839
3840static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3841 CXCursor parent,
3842 CXClientData client_data) {
3843 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3844 CXCursor *BestCursor = &Data->BestCursor;
3845
3846 // If we point inside a macro argument we should provide info of what the
3847 // token is so use the actual cursor, don't replace it with a macro expansion
3848 // cursor.
3849 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3850 return CXChildVisit_Recurse;
3851
3852 if (clang_isDeclaration(cursor.kind)) {
3853 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003854 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003855 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3856 if (MD->isImplicit())
3857 return CXChildVisit_Break;
3858
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003859 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003860 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3861 // Check that when we have multiple @class references in the same line,
3862 // that later ones do not override the previous ones.
3863 // If we have:
3864 // @class Foo, Bar;
3865 // source ranges for both start at '@', so 'Bar' will end up overriding
3866 // 'Foo' even though the cursor location was at 'Foo'.
3867 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3868 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003869 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003870 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3871 if (PrevID != ID &&
3872 !PrevID->isThisDeclarationADefinition() &&
3873 !ID->isThisDeclarationADefinition())
3874 return CXChildVisit_Break;
3875 }
3876
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003877 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003878 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3879 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3880 // Check that when we have multiple declarators in the same line,
3881 // that later ones do not override the previous ones.
3882 // If we have:
3883 // int Foo, Bar;
3884 // source ranges for both start at 'int', so 'Bar' will end up overriding
3885 // 'Foo' even though the cursor location was at 'Foo'.
3886 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3887 return CXChildVisit_Break;
3888 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3889
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003890 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003891 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3892 (void)PropImp;
3893 // Check that when we have multiple @synthesize in the same line,
3894 // that later ones do not override the previous ones.
3895 // If we have:
3896 // @synthesize Foo, Bar;
3897 // source ranges for both start at '@', so 'Bar' will end up overriding
3898 // 'Foo' even though the cursor location was at 'Foo'.
3899 if (Data->VisitedObjCPropertyImplDecl)
3900 return CXChildVisit_Break;
3901 Data->VisitedObjCPropertyImplDecl = true;
3902 }
3903 }
3904
3905 if (clang_isExpression(cursor.kind) &&
3906 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003907 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003908 // Avoid having the cursor of an expression replace the declaration cursor
3909 // when the expression source range overlaps the declaration range.
3910 // This can happen for C++ constructor expressions whose range generally
3911 // include the variable declaration, e.g.:
3912 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3913 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3914 D->getLocation() == Data->TokenBeginLoc)
3915 return CXChildVisit_Break;
3916 }
3917 }
3918
3919 // If our current best cursor is the construction of a temporary object,
3920 // don't replace that cursor with a type reference, because we want
3921 // clang_getCursor() to point at the constructor.
3922 if (clang_isExpression(BestCursor->kind) &&
3923 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3924 cursor.kind == CXCursor_TypeRef) {
3925 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3926 // as having the actual point on the type reference.
3927 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3928 return CXChildVisit_Recurse;
3929 }
3930
3931 *BestCursor = cursor;
3932 return CXChildVisit_Recurse;
3933}
3934
3935CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3936 if (!TU)
3937 return clang_getNullCursor();
3938
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003939 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003940 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3941
3942 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3943 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3944
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003945 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003946 CXFile SearchFile;
3947 unsigned SearchLine, SearchColumn;
3948 CXFile ResultFile;
3949 unsigned ResultLine, ResultColumn;
3950 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3951 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3952 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3953
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003954 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3955 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003956 &ResultColumn, 0);
3957 SearchFileName = clang_getFileName(SearchFile);
3958 ResultFileName = clang_getFileName(ResultFile);
3959 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3960 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003961 *Log << llvm::format("(%s:%d:%d) = %s",
3962 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3963 clang_getCString(KindSpelling))
3964 << llvm::format("(%s:%d:%d):%s%s",
3965 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3966 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003967 clang_disposeString(SearchFileName);
3968 clang_disposeString(ResultFileName);
3969 clang_disposeString(KindSpelling);
3970 clang_disposeString(USR);
3971
3972 CXCursor Definition = clang_getCursorDefinition(Result);
3973 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3974 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3975 CXString DefinitionKindSpelling
3976 = clang_getCursorKindSpelling(Definition.kind);
3977 CXFile DefinitionFile;
3978 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003979 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003980 &DefinitionLine, &DefinitionColumn, 0);
3981 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003982 *Log << llvm::format(" -> %s(%s:%d:%d)",
3983 clang_getCString(DefinitionKindSpelling),
3984 clang_getCString(DefinitionFileName),
3985 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003986 clang_disposeString(DefinitionFileName);
3987 clang_disposeString(DefinitionKindSpelling);
3988 }
3989 }
3990
3991 return Result;
3992}
3993
3994CXCursor clang_getNullCursor(void) {
3995 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3996}
3997
3998unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003999 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4000 // can't set consistently. For example, when visiting a DeclStmt we will set
4001 // it but we don't set it on the result of clang_getCursorDefinition for
4002 // a reference of the same declaration.
4003 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4004 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4005 // to provide that kind of info.
4006 if (clang_isDeclaration(X.kind))
4007 X.data[1] = 0;
4008 if (clang_isDeclaration(Y.kind))
4009 Y.data[1] = 0;
4010
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004011 return X == Y;
4012}
4013
4014unsigned clang_hashCursor(CXCursor C) {
4015 unsigned Index = 0;
4016 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4017 Index = 1;
4018
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004019 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004020 std::make_pair(C.kind, C.data[Index]));
4021}
4022
4023unsigned clang_isInvalid(enum CXCursorKind K) {
4024 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4025}
4026
4027unsigned clang_isDeclaration(enum CXCursorKind K) {
4028 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4029 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4030}
4031
4032unsigned clang_isReference(enum CXCursorKind K) {
4033 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4034}
4035
4036unsigned clang_isExpression(enum CXCursorKind K) {
4037 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4038}
4039
4040unsigned clang_isStatement(enum CXCursorKind K) {
4041 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4042}
4043
4044unsigned clang_isAttribute(enum CXCursorKind K) {
4045 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4046}
4047
4048unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4049 return K == CXCursor_TranslationUnit;
4050}
4051
4052unsigned clang_isPreprocessing(enum CXCursorKind K) {
4053 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4054}
4055
4056unsigned clang_isUnexposed(enum CXCursorKind K) {
4057 switch (K) {
4058 case CXCursor_UnexposedDecl:
4059 case CXCursor_UnexposedExpr:
4060 case CXCursor_UnexposedStmt:
4061 case CXCursor_UnexposedAttr:
4062 return true;
4063 default:
4064 return false;
4065 }
4066}
4067
4068CXCursorKind clang_getCursorKind(CXCursor C) {
4069 return C.kind;
4070}
4071
4072CXSourceLocation clang_getCursorLocation(CXCursor C) {
4073 if (clang_isReference(C.kind)) {
4074 switch (C.kind) {
4075 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004076 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004077 = getCursorObjCSuperClassRef(C);
4078 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4079 }
4080
4081 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004082 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004083 = getCursorObjCProtocolRef(C);
4084 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4085 }
4086
4087 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004088 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004089 = getCursorObjCClassRef(C);
4090 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4091 }
4092
4093 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004094 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004095 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4096 }
4097
4098 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004099 std::pair<const TemplateDecl *, SourceLocation> P =
4100 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004101 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4102 }
4103
4104 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004105 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004106 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4107 }
4108
4109 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004110 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004111 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4112 }
4113
4114 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004115 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004116 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4117 }
4118
4119 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004120 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004121 if (!BaseSpec)
4122 return clang_getNullLocation();
4123
4124 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4125 return cxloc::translateSourceLocation(getCursorContext(C),
4126 TSInfo->getTypeLoc().getBeginLoc());
4127
4128 return cxloc::translateSourceLocation(getCursorContext(C),
4129 BaseSpec->getLocStart());
4130 }
4131
4132 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004133 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004134 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4135 }
4136
4137 case CXCursor_OverloadedDeclRef:
4138 return cxloc::translateSourceLocation(getCursorContext(C),
4139 getCursorOverloadedDeclRef(C).second);
4140
4141 default:
4142 // FIXME: Need a way to enumerate all non-reference cases.
4143 llvm_unreachable("Missed a reference kind");
4144 }
4145 }
4146
4147 if (clang_isExpression(C.kind))
4148 return cxloc::translateSourceLocation(getCursorContext(C),
4149 getLocationFromExpr(getCursorExpr(C)));
4150
4151 if (clang_isStatement(C.kind))
4152 return cxloc::translateSourceLocation(getCursorContext(C),
4153 getCursorStmt(C)->getLocStart());
4154
4155 if (C.kind == CXCursor_PreprocessingDirective) {
4156 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4157 return cxloc::translateSourceLocation(getCursorContext(C), L);
4158 }
4159
4160 if (C.kind == CXCursor_MacroExpansion) {
4161 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004162 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004163 return cxloc::translateSourceLocation(getCursorContext(C), L);
4164 }
4165
4166 if (C.kind == CXCursor_MacroDefinition) {
4167 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4168 return cxloc::translateSourceLocation(getCursorContext(C), L);
4169 }
4170
4171 if (C.kind == CXCursor_InclusionDirective) {
4172 SourceLocation L
4173 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4174 return cxloc::translateSourceLocation(getCursorContext(C), L);
4175 }
4176
4177 if (!clang_isDeclaration(C.kind))
4178 return clang_getNullLocation();
4179
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004180 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004181 if (!D)
4182 return clang_getNullLocation();
4183
4184 SourceLocation Loc = D->getLocation();
4185 // FIXME: Multiple variables declared in a single declaration
4186 // currently lack the information needed to correctly determine their
4187 // ranges when accounting for the type-specifier. We use context
4188 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4189 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004190 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004191 if (!cxcursor::isFirstInDeclGroup(C))
4192 Loc = VD->getLocation();
4193 }
4194
4195 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004196 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004197 Loc = MD->getSelectorStartLoc();
4198
4199 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4200}
4201
4202} // end extern "C"
4203
4204CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4205 assert(TU);
4206
4207 // Guard against an invalid SourceLocation, or we may assert in one
4208 // of the following calls.
4209 if (SLoc.isInvalid())
4210 return clang_getNullCursor();
4211
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004212 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004213
4214 // Translate the given source location to make it point at the beginning of
4215 // the token under the cursor.
4216 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4217 CXXUnit->getASTContext().getLangOpts());
4218
4219 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4220 if (SLoc.isValid()) {
4221 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4222 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4223 /*VisitPreprocessorLast=*/true,
4224 /*VisitIncludedEntities=*/false,
4225 SourceLocation(SLoc));
4226 CursorVis.visitFileRegion();
4227 }
4228
4229 return Result;
4230}
4231
4232static SourceRange getRawCursorExtent(CXCursor C) {
4233 if (clang_isReference(C.kind)) {
4234 switch (C.kind) {
4235 case CXCursor_ObjCSuperClassRef:
4236 return getCursorObjCSuperClassRef(C).second;
4237
4238 case CXCursor_ObjCProtocolRef:
4239 return getCursorObjCProtocolRef(C).second;
4240
4241 case CXCursor_ObjCClassRef:
4242 return getCursorObjCClassRef(C).second;
4243
4244 case CXCursor_TypeRef:
4245 return getCursorTypeRef(C).second;
4246
4247 case CXCursor_TemplateRef:
4248 return getCursorTemplateRef(C).second;
4249
4250 case CXCursor_NamespaceRef:
4251 return getCursorNamespaceRef(C).second;
4252
4253 case CXCursor_MemberRef:
4254 return getCursorMemberRef(C).second;
4255
4256 case CXCursor_CXXBaseSpecifier:
4257 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4258
4259 case CXCursor_LabelRef:
4260 return getCursorLabelRef(C).second;
4261
4262 case CXCursor_OverloadedDeclRef:
4263 return getCursorOverloadedDeclRef(C).second;
4264
4265 case CXCursor_VariableRef:
4266 return getCursorVariableRef(C).second;
4267
4268 default:
4269 // FIXME: Need a way to enumerate all non-reference cases.
4270 llvm_unreachable("Missed a reference kind");
4271 }
4272 }
4273
4274 if (clang_isExpression(C.kind))
4275 return getCursorExpr(C)->getSourceRange();
4276
4277 if (clang_isStatement(C.kind))
4278 return getCursorStmt(C)->getSourceRange();
4279
4280 if (clang_isAttribute(C.kind))
4281 return getCursorAttr(C)->getRange();
4282
4283 if (C.kind == CXCursor_PreprocessingDirective)
4284 return cxcursor::getCursorPreprocessingDirective(C);
4285
4286 if (C.kind == CXCursor_MacroExpansion) {
4287 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004288 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004289 return TU->mapRangeFromPreamble(Range);
4290 }
4291
4292 if (C.kind == CXCursor_MacroDefinition) {
4293 ASTUnit *TU = getCursorASTUnit(C);
4294 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4295 return TU->mapRangeFromPreamble(Range);
4296 }
4297
4298 if (C.kind == CXCursor_InclusionDirective) {
4299 ASTUnit *TU = getCursorASTUnit(C);
4300 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4301 return TU->mapRangeFromPreamble(Range);
4302 }
4303
4304 if (C.kind == CXCursor_TranslationUnit) {
4305 ASTUnit *TU = getCursorASTUnit(C);
4306 FileID MainID = TU->getSourceManager().getMainFileID();
4307 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4308 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4309 return SourceRange(Start, End);
4310 }
4311
4312 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004313 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004314 if (!D)
4315 return SourceRange();
4316
4317 SourceRange R = D->getSourceRange();
4318 // FIXME: Multiple variables declared in a single declaration
4319 // currently lack the information needed to correctly determine their
4320 // ranges when accounting for the type-specifier. We use context
4321 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4322 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004323 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004324 if (!cxcursor::isFirstInDeclGroup(C))
4325 R.setBegin(VD->getLocation());
4326 }
4327 return R;
4328 }
4329 return SourceRange();
4330}
4331
4332/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4333/// the decl-specifier-seq for declarations.
4334static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4335 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004336 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004337 if (!D)
4338 return SourceRange();
4339
4340 SourceRange R = D->getSourceRange();
4341
4342 // Adjust the start of the location for declarations preceded by
4343 // declaration specifiers.
4344 SourceLocation StartLoc;
4345 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4346 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4347 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004348 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004349 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4350 StartLoc = TI->getTypeLoc().getLocStart();
4351 }
4352
4353 if (StartLoc.isValid() && R.getBegin().isValid() &&
4354 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4355 R.setBegin(StartLoc);
4356
4357 // FIXME: Multiple variables declared in a single declaration
4358 // currently lack the information needed to correctly determine their
4359 // ranges when accounting for the type-specifier. We use context
4360 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4361 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004362 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004363 if (!cxcursor::isFirstInDeclGroup(C))
4364 R.setBegin(VD->getLocation());
4365 }
4366
4367 return R;
4368 }
4369
4370 return getRawCursorExtent(C);
4371}
4372
4373extern "C" {
4374
4375CXSourceRange clang_getCursorExtent(CXCursor C) {
4376 SourceRange R = getRawCursorExtent(C);
4377 if (R.isInvalid())
4378 return clang_getNullRange();
4379
4380 return cxloc::translateSourceRange(getCursorContext(C), R);
4381}
4382
4383CXCursor clang_getCursorReferenced(CXCursor C) {
4384 if (clang_isInvalid(C.kind))
4385 return clang_getNullCursor();
4386
4387 CXTranslationUnit tu = getCursorTU(C);
4388 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004389 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004390 if (!D)
4391 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004392 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004393 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004394 if (const ObjCPropertyImplDecl *PropImpl =
4395 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004396 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4397 return MakeCXCursor(Property, tu);
4398
4399 return C;
4400 }
4401
4402 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004403 const Expr *E = getCursorExpr(C);
4404 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004405 if (D) {
4406 CXCursor declCursor = MakeCXCursor(D, tu);
4407 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4408 declCursor);
4409 return declCursor;
4410 }
4411
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004412 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004413 return MakeCursorOverloadedDeclRef(Ovl, tu);
4414
4415 return clang_getNullCursor();
4416 }
4417
4418 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004419 const Stmt *S = getCursorStmt(C);
4420 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004421 if (LabelDecl *label = Goto->getLabel())
4422 if (LabelStmt *labelS = label->getStmt())
4423 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4424
4425 return clang_getNullCursor();
4426 }
4427
4428 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004429 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004430 return MakeMacroDefinitionCursor(Def, tu);
4431 }
4432
4433 if (!clang_isReference(C.kind))
4434 return clang_getNullCursor();
4435
4436 switch (C.kind) {
4437 case CXCursor_ObjCSuperClassRef:
4438 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4439
4440 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004441 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4442 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004443 return MakeCXCursor(Def, tu);
4444
4445 return MakeCXCursor(Prot, tu);
4446 }
4447
4448 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004449 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4450 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004451 return MakeCXCursor(Def, tu);
4452
4453 return MakeCXCursor(Class, tu);
4454 }
4455
4456 case CXCursor_TypeRef:
4457 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4458
4459 case CXCursor_TemplateRef:
4460 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4461
4462 case CXCursor_NamespaceRef:
4463 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4464
4465 case CXCursor_MemberRef:
4466 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4467
4468 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004469 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004470 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4471 tu ));
4472 }
4473
4474 case CXCursor_LabelRef:
4475 // FIXME: We end up faking the "parent" declaration here because we
4476 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004477 return MakeCXCursor(getCursorLabelRef(C).first,
4478 cxtu::getASTUnit(tu)->getASTContext()
4479 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004480 tu);
4481
4482 case CXCursor_OverloadedDeclRef:
4483 return C;
4484
4485 case CXCursor_VariableRef:
4486 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4487
4488 default:
4489 // We would prefer to enumerate all non-reference cursor kinds here.
4490 llvm_unreachable("Unhandled reference cursor kind");
4491 }
4492}
4493
4494CXCursor clang_getCursorDefinition(CXCursor C) {
4495 if (clang_isInvalid(C.kind))
4496 return clang_getNullCursor();
4497
4498 CXTranslationUnit TU = getCursorTU(C);
4499
4500 bool WasReference = false;
4501 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4502 C = clang_getCursorReferenced(C);
4503 WasReference = true;
4504 }
4505
4506 if (C.kind == CXCursor_MacroExpansion)
4507 return clang_getCursorReferenced(C);
4508
4509 if (!clang_isDeclaration(C.kind))
4510 return clang_getNullCursor();
4511
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004512 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004513 if (!D)
4514 return clang_getNullCursor();
4515
4516 switch (D->getKind()) {
4517 // Declaration kinds that don't really separate the notions of
4518 // declaration and definition.
4519 case Decl::Namespace:
4520 case Decl::Typedef:
4521 case Decl::TypeAlias:
4522 case Decl::TypeAliasTemplate:
4523 case Decl::TemplateTypeParm:
4524 case Decl::EnumConstant:
4525 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004526 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004527 case Decl::IndirectField:
4528 case Decl::ObjCIvar:
4529 case Decl::ObjCAtDefsField:
4530 case Decl::ImplicitParam:
4531 case Decl::ParmVar:
4532 case Decl::NonTypeTemplateParm:
4533 case Decl::TemplateTemplateParm:
4534 case Decl::ObjCCategoryImpl:
4535 case Decl::ObjCImplementation:
4536 case Decl::AccessSpec:
4537 case Decl::LinkageSpec:
4538 case Decl::ObjCPropertyImpl:
4539 case Decl::FileScopeAsm:
4540 case Decl::StaticAssert:
4541 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004542 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004543 case Decl::Label: // FIXME: Is this right??
4544 case Decl::ClassScopeFunctionSpecialization:
4545 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004546 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004547 return C;
4548
4549 // Declaration kinds that don't make any sense here, but are
4550 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004551 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004552 case Decl::TranslationUnit:
4553 break;
4554
4555 // Declaration kinds for which the definition is not resolvable.
4556 case Decl::UnresolvedUsingTypename:
4557 case Decl::UnresolvedUsingValue:
4558 break;
4559
4560 case Decl::UsingDirective:
4561 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4562 TU);
4563
4564 case Decl::NamespaceAlias:
4565 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4566
4567 case Decl::Enum:
4568 case Decl::Record:
4569 case Decl::CXXRecord:
4570 case Decl::ClassTemplateSpecialization:
4571 case Decl::ClassTemplatePartialSpecialization:
4572 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4573 return MakeCXCursor(Def, TU);
4574 return clang_getNullCursor();
4575
4576 case Decl::Function:
4577 case Decl::CXXMethod:
4578 case Decl::CXXConstructor:
4579 case Decl::CXXDestructor:
4580 case Decl::CXXConversion: {
4581 const FunctionDecl *Def = 0;
4582 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004583 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004584 return clang_getNullCursor();
4585 }
4586
Larisse Voufoef4579c2013-08-06 01:03:05 +00004587 case Decl::Var:
4588 case Decl::VarTemplateSpecialization:
4589 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004590 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004591 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004592 return MakeCXCursor(Def, TU);
4593 return clang_getNullCursor();
4594 }
4595
4596 case Decl::FunctionTemplate: {
4597 const FunctionDecl *Def = 0;
4598 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4599 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4600 return clang_getNullCursor();
4601 }
4602
4603 case Decl::ClassTemplate: {
4604 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4605 ->getDefinition())
4606 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4607 TU);
4608 return clang_getNullCursor();
4609 }
4610
Larisse Voufoef4579c2013-08-06 01:03:05 +00004611 case Decl::VarTemplate: {
4612 if (VarDecl *Def =
4613 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4614 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4615 return clang_getNullCursor();
4616 }
4617
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004618 case Decl::Using:
4619 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4620 D->getLocation(), TU);
4621
4622 case Decl::UsingShadow:
4623 return clang_getCursorDefinition(
4624 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4625 TU));
4626
4627 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004628 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004629 if (Method->isThisDeclarationADefinition())
4630 return C;
4631
4632 // Dig out the method definition in the associated
4633 // @implementation, if we have it.
4634 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004635 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004636 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4637 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4638 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4639 Method->isInstanceMethod()))
4640 if (Def->isThisDeclarationADefinition())
4641 return MakeCXCursor(Def, TU);
4642
4643 return clang_getNullCursor();
4644 }
4645
4646 case Decl::ObjCCategory:
4647 if (ObjCCategoryImplDecl *Impl
4648 = cast<ObjCCategoryDecl>(D)->getImplementation())
4649 return MakeCXCursor(Impl, TU);
4650 return clang_getNullCursor();
4651
4652 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004653 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004654 return MakeCXCursor(Def, TU);
4655 return clang_getNullCursor();
4656
4657 case Decl::ObjCInterface: {
4658 // There are two notions of a "definition" for an Objective-C
4659 // class: the interface and its implementation. When we resolved a
4660 // reference to an Objective-C class, produce the @interface as
4661 // the definition; when we were provided with the interface,
4662 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004663 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004664 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004665 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004666 return MakeCXCursor(Def, TU);
4667 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4668 return MakeCXCursor(Impl, TU);
4669 return clang_getNullCursor();
4670 }
4671
4672 case Decl::ObjCProperty:
4673 // FIXME: We don't really know where to find the
4674 // ObjCPropertyImplDecls that implement this property.
4675 return clang_getNullCursor();
4676
4677 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004678 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004679 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004680 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004681 return MakeCXCursor(Def, TU);
4682
4683 return clang_getNullCursor();
4684
4685 case Decl::Friend:
4686 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4687 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4688 return clang_getNullCursor();
4689
4690 case Decl::FriendTemplate:
4691 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4692 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4693 return clang_getNullCursor();
4694 }
4695
4696 return clang_getNullCursor();
4697}
4698
4699unsigned clang_isCursorDefinition(CXCursor C) {
4700 if (!clang_isDeclaration(C.kind))
4701 return 0;
4702
4703 return clang_getCursorDefinition(C) == C;
4704}
4705
4706CXCursor clang_getCanonicalCursor(CXCursor C) {
4707 if (!clang_isDeclaration(C.kind))
4708 return C;
4709
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004710 if (const Decl *D = getCursorDecl(C)) {
4711 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004712 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4713 return MakeCXCursor(CatD, getCursorTU(C));
4714
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004715 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4716 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004717 return MakeCXCursor(IFD, getCursorTU(C));
4718
4719 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4720 }
4721
4722 return C;
4723}
4724
4725int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4726 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4727}
4728
4729unsigned clang_getNumOverloadedDecls(CXCursor C) {
4730 if (C.kind != CXCursor_OverloadedDeclRef)
4731 return 0;
4732
4733 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004734 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004735 return E->getNumDecls();
4736
4737 if (OverloadedTemplateStorage *S
4738 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4739 return S->size();
4740
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004741 const Decl *D = Storage.get<const Decl *>();
4742 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004743 return Using->shadow_size();
4744
4745 return 0;
4746}
4747
4748CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4749 if (cursor.kind != CXCursor_OverloadedDeclRef)
4750 return clang_getNullCursor();
4751
4752 if (index >= clang_getNumOverloadedDecls(cursor))
4753 return clang_getNullCursor();
4754
4755 CXTranslationUnit TU = getCursorTU(cursor);
4756 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004757 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004758 return MakeCXCursor(E->decls_begin()[index], TU);
4759
4760 if (OverloadedTemplateStorage *S
4761 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4762 return MakeCXCursor(S->begin()[index], TU);
4763
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004764 const Decl *D = Storage.get<const Decl *>();
4765 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004766 // FIXME: This is, unfortunately, linear time.
4767 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4768 std::advance(Pos, index);
4769 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4770 }
4771
4772 return clang_getNullCursor();
4773}
4774
4775void clang_getDefinitionSpellingAndExtent(CXCursor C,
4776 const char **startBuf,
4777 const char **endBuf,
4778 unsigned *startLine,
4779 unsigned *startColumn,
4780 unsigned *endLine,
4781 unsigned *endColumn) {
4782 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004783 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004784 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4785
4786 SourceManager &SM = FD->getASTContext().getSourceManager();
4787 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4788 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4789 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4790 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4791 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4792 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4793}
4794
4795
4796CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4797 unsigned PieceIndex) {
4798 RefNamePieces Pieces;
4799
4800 switch (C.kind) {
4801 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004802 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004803 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4804 E->getQualifierLoc().getSourceRange());
4805 break;
4806
4807 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004808 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004809 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4810 E->getQualifierLoc().getSourceRange(),
4811 E->getOptionalExplicitTemplateArgs());
4812 break;
4813
4814 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004815 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004816 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004817 const Expr *Callee = OCE->getCallee();
4818 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004819 Callee = ICE->getSubExpr();
4820
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004821 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004822 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4823 DRE->getQualifierLoc().getSourceRange());
4824 }
4825 break;
4826
4827 default:
4828 break;
4829 }
4830
4831 if (Pieces.empty()) {
4832 if (PieceIndex == 0)
4833 return clang_getCursorExtent(C);
4834 } else if (PieceIndex < Pieces.size()) {
4835 SourceRange R = Pieces[PieceIndex];
4836 if (R.isValid())
4837 return cxloc::translateSourceRange(getCursorContext(C), R);
4838 }
4839
4840 return clang_getNullRange();
4841}
4842
4843void clang_enableStackTraces(void) {
4844 llvm::sys::PrintStackTraceOnErrorSignal();
4845}
4846
4847void clang_executeOnThread(void (*fn)(void*), void *user_data,
4848 unsigned stack_size) {
4849 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4850}
4851
4852} // end: extern "C"
4853
4854//===----------------------------------------------------------------------===//
4855// Token-based Operations.
4856//===----------------------------------------------------------------------===//
4857
4858/* CXToken layout:
4859 * int_data[0]: a CXTokenKind
4860 * int_data[1]: starting token location
4861 * int_data[2]: token length
4862 * int_data[3]: reserved
4863 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4864 * otherwise unused.
4865 */
4866extern "C" {
4867
4868CXTokenKind clang_getTokenKind(CXToken CXTok) {
4869 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4870}
4871
4872CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4873 switch (clang_getTokenKind(CXTok)) {
4874 case CXToken_Identifier:
4875 case CXToken_Keyword:
4876 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004877 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004878 ->getNameStart());
4879
4880 case CXToken_Literal: {
4881 // We have stashed the starting pointer in the ptr_data field. Use it.
4882 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004883 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004884 }
4885
4886 case CXToken_Punctuation:
4887 case CXToken_Comment:
4888 break;
4889 }
4890
4891 // We have to find the starting buffer pointer the hard way, by
4892 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004893 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004894 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004895 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004896
4897 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4898 std::pair<FileID, unsigned> LocInfo
4899 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4900 bool Invalid = false;
4901 StringRef Buffer
4902 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4903 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004904 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004905
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004906 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004907}
4908
4909CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004910 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004911 if (!CXXUnit)
4912 return clang_getNullLocation();
4913
4914 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4915 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4916}
4917
4918CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004919 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004920 if (!CXXUnit)
4921 return clang_getNullRange();
4922
4923 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4924 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4925}
4926
4927static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4928 SmallVectorImpl<CXToken> &CXTokens) {
4929 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4930 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004931 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004932 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004933 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004934
4935 // Cannot tokenize across files.
4936 if (BeginLocInfo.first != EndLocInfo.first)
4937 return;
4938
4939 // Create a lexer
4940 bool Invalid = false;
4941 StringRef Buffer
4942 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4943 if (Invalid)
4944 return;
4945
4946 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4947 CXXUnit->getASTContext().getLangOpts(),
4948 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4949 Lex.SetCommentRetentionState(true);
4950
4951 // Lex tokens until we hit the end of the range.
4952 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4953 Token Tok;
4954 bool previousWasAt = false;
4955 do {
4956 // Lex the next token
4957 Lex.LexFromRawLexer(Tok);
4958 if (Tok.is(tok::eof))
4959 break;
4960
4961 // Initialize the CXToken.
4962 CXToken CXTok;
4963
4964 // - Common fields
4965 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4966 CXTok.int_data[2] = Tok.getLength();
4967 CXTok.int_data[3] = 0;
4968
4969 // - Kind-specific fields
4970 if (Tok.isLiteral()) {
4971 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004972 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004973 } else if (Tok.is(tok::raw_identifier)) {
4974 // Lookup the identifier to determine whether we have a keyword.
4975 IdentifierInfo *II
4976 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4977
4978 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4979 CXTok.int_data[0] = CXToken_Keyword;
4980 }
4981 else {
4982 CXTok.int_data[0] = Tok.is(tok::identifier)
4983 ? CXToken_Identifier
4984 : CXToken_Keyword;
4985 }
4986 CXTok.ptr_data = II;
4987 } else if (Tok.is(tok::comment)) {
4988 CXTok.int_data[0] = CXToken_Comment;
4989 CXTok.ptr_data = 0;
4990 } else {
4991 CXTok.int_data[0] = CXToken_Punctuation;
4992 CXTok.ptr_data = 0;
4993 }
4994 CXTokens.push_back(CXTok);
4995 previousWasAt = Tok.is(tok::at);
4996 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4997}
4998
4999void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5000 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005001 LOG_FUNC_SECTION {
5002 *Log << TU << ' ' << Range;
5003 }
5004
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005005 if (Tokens)
5006 *Tokens = 0;
5007 if (NumTokens)
5008 *NumTokens = 0;
5009
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005010 if (!TU)
5011 return;
5012
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005014 if (!CXXUnit || !Tokens || !NumTokens)
5015 return;
5016
5017 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5018
5019 SourceRange R = cxloc::translateCXSourceRange(Range);
5020 if (R.isInvalid())
5021 return;
5022
5023 SmallVector<CXToken, 32> CXTokens;
5024 getTokens(CXXUnit, R, CXTokens);
5025
5026 if (CXTokens.empty())
5027 return;
5028
5029 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5030 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5031 *NumTokens = CXTokens.size();
5032}
5033
5034void clang_disposeTokens(CXTranslationUnit TU,
5035 CXToken *Tokens, unsigned NumTokens) {
5036 free(Tokens);
5037}
5038
5039} // end: extern "C"
5040
5041//===----------------------------------------------------------------------===//
5042// Token annotation APIs.
5043//===----------------------------------------------------------------------===//
5044
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005045static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5046 CXCursor parent,
5047 CXClientData client_data);
5048static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5049 CXClientData client_data);
5050
5051namespace {
5052class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005053 CXToken *Tokens;
5054 CXCursor *Cursors;
5055 unsigned NumTokens;
5056 unsigned TokIdx;
5057 unsigned PreprocessingTokIdx;
5058 CursorVisitor AnnotateVis;
5059 SourceManager &SrcMgr;
5060 bool HasContextSensitiveKeywords;
5061
5062 struct PostChildrenInfo {
5063 CXCursor Cursor;
5064 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005065 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005066 unsigned BeforeChildrenTokenIdx;
5067 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005068 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005069
5070 bool MoreTokens() const { return TokIdx < NumTokens; }
5071 unsigned NextToken() const { return TokIdx; }
5072 void AdvanceToken() { ++TokIdx; }
5073 SourceLocation GetTokenLoc(unsigned tokI) {
5074 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5075 }
5076 bool isFunctionMacroToken(unsigned tokI) const {
5077 return Tokens[tokI].int_data[3] != 0;
5078 }
5079 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5080 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5081 }
5082
5083 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005084 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005085 SourceRange);
5086
5087public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005088 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005089 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005090 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005091 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005092 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005093 AnnotateTokensVisitor, this,
5094 /*VisitPreprocessorLast=*/true,
5095 /*VisitIncludedEntities=*/false,
5096 RegionOfInterest,
5097 /*VisitDeclsOnly=*/false,
5098 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005099 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005100 HasContextSensitiveKeywords(false) { }
5101
5102 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5103 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5104 bool postVisitChildren(CXCursor cursor);
5105 void AnnotateTokens();
5106
5107 /// \brief Determine whether the annotator saw any cursors that have
5108 /// context-sensitive keywords.
5109 bool hasContextSensitiveKeywords() const {
5110 return HasContextSensitiveKeywords;
5111 }
5112
5113 ~AnnotateTokensWorker() {
5114 assert(PostChildrenInfos.empty());
5115 }
5116};
5117}
5118
5119void AnnotateTokensWorker::AnnotateTokens() {
5120 // Walk the AST within the region of interest, annotating tokens
5121 // along the way.
5122 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005123}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005124
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005125static inline void updateCursorAnnotation(CXCursor &Cursor,
5126 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005127 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005128 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005129 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005130}
5131
5132/// \brief It annotates and advances tokens with a cursor until the comparison
5133//// between the cursor location and the source range is the same as
5134/// \arg compResult.
5135///
5136/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5137/// Pass RangeOverlap to annotate tokens inside a range.
5138void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5139 RangeComparisonResult compResult,
5140 SourceRange range) {
5141 while (MoreTokens()) {
5142 const unsigned I = NextToken();
5143 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005144 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5145 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005146
5147 SourceLocation TokLoc = GetTokenLoc(I);
5148 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005149 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005150 AdvanceToken();
5151 continue;
5152 }
5153 break;
5154 }
5155}
5156
5157/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005158/// \returns true if it advanced beyond all macro tokens, false otherwise.
5159bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005160 CXCursor updateC,
5161 RangeComparisonResult compResult,
5162 SourceRange range) {
5163 assert(MoreTokens());
5164 assert(isFunctionMacroToken(NextToken()) &&
5165 "Should be called only for macro arg tokens");
5166
5167 // This works differently than annotateAndAdvanceTokens; because expanded
5168 // macro arguments can have arbitrary translation-unit source order, we do not
5169 // advance the token index one by one until a token fails the range test.
5170 // We only advance once past all of the macro arg tokens if all of them
5171 // pass the range test. If one of them fails we keep the token index pointing
5172 // at the start of the macro arg tokens so that the failing token will be
5173 // annotated by a subsequent annotation try.
5174
5175 bool atLeastOneCompFail = false;
5176
5177 unsigned I = NextToken();
5178 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5179 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5180 if (TokLoc.isFileID())
5181 continue; // not macro arg token, it's parens or comma.
5182 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5183 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5184 Cursors[I] = updateC;
5185 } else
5186 atLeastOneCompFail = true;
5187 }
5188
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005189 if (atLeastOneCompFail)
5190 return false;
5191
5192 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5193 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005194}
5195
5196enum CXChildVisitResult
5197AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005198 SourceRange cursorRange = getRawCursorExtent(cursor);
5199 if (cursorRange.isInvalid())
5200 return CXChildVisit_Recurse;
5201
5202 if (!HasContextSensitiveKeywords) {
5203 // Objective-C properties can have context-sensitive keywords.
5204 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005205 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005206 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5207 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5208 }
5209 // Objective-C methods can have context-sensitive keywords.
5210 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5211 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005212 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005213 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5214 if (Method->getObjCDeclQualifier())
5215 HasContextSensitiveKeywords = true;
5216 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005217 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5218 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005219 P != PEnd; ++P) {
5220 if ((*P)->getObjCDeclQualifier()) {
5221 HasContextSensitiveKeywords = true;
5222 break;
5223 }
5224 }
5225 }
5226 }
5227 }
5228 // C++ methods can have context-sensitive keywords.
5229 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005230 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005231 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5232 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5233 HasContextSensitiveKeywords = true;
5234 }
5235 }
5236 // C++ classes can have context-sensitive keywords.
5237 else if (cursor.kind == CXCursor_StructDecl ||
5238 cursor.kind == CXCursor_ClassDecl ||
5239 cursor.kind == CXCursor_ClassTemplate ||
5240 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005241 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005242 if (D->hasAttr<FinalAttr>())
5243 HasContextSensitiveKeywords = true;
5244 }
5245 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005246
5247 // Don't override a property annotation with its getter/setter method.
5248 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5249 parent.kind == CXCursor_ObjCPropertyDecl)
5250 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005251
5252 if (clang_isPreprocessing(cursor.kind)) {
5253 // Items in the preprocessing record are kept separate from items in
5254 // declarations, so we keep a separate token index.
5255 unsigned SavedTokIdx = TokIdx;
5256 TokIdx = PreprocessingTokIdx;
5257
5258 // Skip tokens up until we catch up to the beginning of the preprocessing
5259 // entry.
5260 while (MoreTokens()) {
5261 const unsigned I = NextToken();
5262 SourceLocation TokLoc = GetTokenLoc(I);
5263 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5264 case RangeBefore:
5265 AdvanceToken();
5266 continue;
5267 case RangeAfter:
5268 case RangeOverlap:
5269 break;
5270 }
5271 break;
5272 }
5273
5274 // Look at all of the tokens within this range.
5275 while (MoreTokens()) {
5276 const unsigned I = NextToken();
5277 SourceLocation TokLoc = GetTokenLoc(I);
5278 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5279 case RangeBefore:
5280 llvm_unreachable("Infeasible");
5281 case RangeAfter:
5282 break;
5283 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005284 // For macro expansions, just note where the beginning of the macro
5285 // expansion occurs.
5286 if (cursor.kind == CXCursor_MacroExpansion) {
5287 if (TokLoc == cursorRange.getBegin())
5288 Cursors[I] = cursor;
5289 AdvanceToken();
5290 break;
5291 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005292 // We may have already annotated macro names inside macro definitions.
5293 if (Cursors[I].kind != CXCursor_MacroExpansion)
5294 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005295 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005296 continue;
5297 }
5298 break;
5299 }
5300
5301 // Save the preprocessing token index; restore the non-preprocessing
5302 // token index.
5303 PreprocessingTokIdx = TokIdx;
5304 TokIdx = SavedTokIdx;
5305 return CXChildVisit_Recurse;
5306 }
5307
5308 if (cursorRange.isInvalid())
5309 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005310
5311 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005312 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005313 const enum CXCursorKind K = clang_getCursorKind(parent);
5314 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005315 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5316 // Attributes are annotated out-of-order, skip tokens until we reach it.
5317 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005318 ? clang_getNullCursor() : parent;
5319
5320 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5321
5322 // Avoid having the cursor of an expression "overwrite" the annotation of the
5323 // variable declaration that it belongs to.
5324 // This can happen for C++ constructor expressions whose range generally
5325 // include the variable declaration, e.g.:
5326 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5327 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005328 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005329 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005330 const unsigned I = NextToken();
5331 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5332 E->getLocStart() == D->getLocation() &&
5333 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005334 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005335 AdvanceToken();
5336 }
5337 }
5338 }
5339
5340 // Before recursing into the children keep some state that we are going
5341 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5342 // extra work after the child nodes are visited.
5343 // Note that we don't call VisitChildren here to avoid traversing statements
5344 // code-recursively which can blow the stack.
5345
5346 PostChildrenInfo Info;
5347 Info.Cursor = cursor;
5348 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005349 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005350 Info.BeforeChildrenTokenIdx = NextToken();
5351 PostChildrenInfos.push_back(Info);
5352
5353 return CXChildVisit_Recurse;
5354}
5355
5356bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5357 if (PostChildrenInfos.empty())
5358 return false;
5359 const PostChildrenInfo &Info = PostChildrenInfos.back();
5360 if (!clang_equalCursors(Info.Cursor, cursor))
5361 return false;
5362
5363 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5364 const unsigned AfterChildren = NextToken();
5365 SourceRange cursorRange = Info.CursorRange;
5366
5367 // Scan the tokens that are at the end of the cursor, but are not captured
5368 // but the child cursors.
5369 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5370
5371 // Scan the tokens that are at the beginning of the cursor, but are not
5372 // capture by the child cursors.
5373 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5374 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5375 break;
5376
5377 Cursors[I] = cursor;
5378 }
5379
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005380 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5381 // encountered the attribute cursor.
5382 if (clang_isAttribute(cursor.kind))
5383 TokIdx = Info.BeforeReachingCursorIdx;
5384
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005385 PostChildrenInfos.pop_back();
5386 return false;
5387}
5388
5389static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5390 CXCursor parent,
5391 CXClientData client_data) {
5392 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5393}
5394
5395static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5396 CXClientData client_data) {
5397 return static_cast<AnnotateTokensWorker*>(client_data)->
5398 postVisitChildren(cursor);
5399}
5400
5401namespace {
5402
5403/// \brief Uses the macro expansions in the preprocessing record to find
5404/// and mark tokens that are macro arguments. This info is used by the
5405/// AnnotateTokensWorker.
5406class MarkMacroArgTokensVisitor {
5407 SourceManager &SM;
5408 CXToken *Tokens;
5409 unsigned NumTokens;
5410 unsigned CurIdx;
5411
5412public:
5413 MarkMacroArgTokensVisitor(SourceManager &SM,
5414 CXToken *tokens, unsigned numTokens)
5415 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5416
5417 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5418 if (cursor.kind != CXCursor_MacroExpansion)
5419 return CXChildVisit_Continue;
5420
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005421 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005422 if (macroRange.getBegin() == macroRange.getEnd())
5423 return CXChildVisit_Continue; // it's not a function macro.
5424
5425 for (; CurIdx < NumTokens; ++CurIdx) {
5426 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5427 macroRange.getBegin()))
5428 break;
5429 }
5430
5431 if (CurIdx == NumTokens)
5432 return CXChildVisit_Break;
5433
5434 for (; CurIdx < NumTokens; ++CurIdx) {
5435 SourceLocation tokLoc = getTokenLoc(CurIdx);
5436 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5437 break;
5438
5439 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5440 }
5441
5442 if (CurIdx == NumTokens)
5443 return CXChildVisit_Break;
5444
5445 return CXChildVisit_Continue;
5446 }
5447
5448private:
5449 SourceLocation getTokenLoc(unsigned tokI) {
5450 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5451 }
5452
5453 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5454 // The third field is reserved and currently not used. Use it here
5455 // to mark macro arg expanded tokens with their expanded locations.
5456 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5457 }
5458};
5459
5460} // end anonymous namespace
5461
5462static CXChildVisitResult
5463MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5464 CXClientData client_data) {
5465 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5466 parent);
5467}
5468
5469namespace {
5470 struct clang_annotateTokens_Data {
5471 CXTranslationUnit TU;
5472 ASTUnit *CXXUnit;
5473 CXToken *Tokens;
5474 unsigned NumTokens;
5475 CXCursor *Cursors;
5476 };
5477}
5478
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005479/// \brief Used by \c annotatePreprocessorTokens.
5480/// \returns true if lexing was finished, false otherwise.
5481static bool lexNext(Lexer &Lex, Token &Tok,
5482 unsigned &NextIdx, unsigned NumTokens) {
5483 if (NextIdx >= NumTokens)
5484 return true;
5485
5486 ++NextIdx;
5487 Lex.LexFromRawLexer(Tok);
5488 if (Tok.is(tok::eof))
5489 return true;
5490
5491 return false;
5492}
5493
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005494static void annotatePreprocessorTokens(CXTranslationUnit TU,
5495 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005496 CXCursor *Cursors,
5497 CXToken *Tokens,
5498 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005499 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005500
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005501 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005502 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5503 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005504 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005505 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005506 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005507
5508 if (BeginLocInfo.first != EndLocInfo.first)
5509 return;
5510
5511 StringRef Buffer;
5512 bool Invalid = false;
5513 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5514 if (Buffer.empty() || Invalid)
5515 return;
5516
5517 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5518 CXXUnit->getASTContext().getLangOpts(),
5519 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5520 Buffer.end());
5521 Lex.SetCommentRetentionState(true);
5522
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005523 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005524 // Lex tokens in raw mode until we hit the end of the range, to avoid
5525 // entering #includes or expanding macros.
5526 while (true) {
5527 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005528 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5529 break;
5530 unsigned TokIdx = NextIdx-1;
5531 assert(Tok.getLocation() ==
5532 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005533
5534 reprocess:
5535 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005536 // We have found a preprocessing directive. Annotate the tokens
5537 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005538 //
5539 // FIXME: Some simple tests here could identify macro definitions and
5540 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005541
5542 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005543 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5544 break;
5545
5546 MacroInfo *MI = 0;
5547 if (Tok.is(tok::raw_identifier) &&
5548 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5549 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5550 break;
5551
5552 if (Tok.is(tok::raw_identifier)) {
5553 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5554 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5555 SourceLocation MappedTokLoc =
5556 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5557 MI = getMacroInfo(II, MappedTokLoc, TU);
5558 }
5559 }
5560
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005561 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005562 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005563 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5564 finished = true;
5565 break;
5566 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005567 // If we are in a macro definition, check if the token was ever a
5568 // macro name and annotate it if that's the case.
5569 if (MI) {
5570 SourceLocation SaveLoc = Tok.getLocation();
5571 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5572 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5573 Tok.setLocation(SaveLoc);
5574 if (MacroDef)
5575 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5576 Tok.getLocation(), TU);
5577 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005578 } while (!Tok.isAtStartOfLine());
5579
5580 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5581 assert(TokIdx <= LastIdx);
5582 SourceLocation EndLoc =
5583 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5584 CXCursor Cursor =
5585 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5586
5587 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005588 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005589
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005590 if (finished)
5591 break;
5592 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005593 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005594 }
5595}
5596
5597// This gets run a separate thread to avoid stack blowout.
5598static void clang_annotateTokensImpl(void *UserData) {
5599 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5600 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5601 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5602 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5603 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5604
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005605 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005606 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5607 setThreadBackgroundPriority();
5608
5609 // Determine the region of interest, which contains all of the tokens.
5610 SourceRange RegionOfInterest;
5611 RegionOfInterest.setBegin(
5612 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5613 RegionOfInterest.setEnd(
5614 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5615 Tokens[NumTokens-1])));
5616
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005617 // Relex the tokens within the source range to look for preprocessing
5618 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005619 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005620
5621 // If begin location points inside a macro argument, set it to the expansion
5622 // location so we can have the full context when annotating semantically.
5623 {
5624 SourceManager &SM = CXXUnit->getSourceManager();
5625 SourceLocation Loc =
5626 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5627 if (Loc.isMacroID())
5628 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5629 }
5630
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005631 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5632 // Search and mark tokens that are macro argument expansions.
5633 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5634 Tokens, NumTokens);
5635 CursorVisitor MacroArgMarker(TU,
5636 MarkMacroArgTokensVisitorDelegate, &Visitor,
5637 /*VisitPreprocessorLast=*/true,
5638 /*VisitIncludedEntities=*/false,
5639 RegionOfInterest);
5640 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5641 }
5642
5643 // Annotate all of the source locations in the region of interest that map to
5644 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005645 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005646
5647 // FIXME: We use a ridiculous stack size here because the data-recursion
5648 // algorithm uses a large stack frame than the non-data recursive version,
5649 // and AnnotationTokensWorker currently transforms the data-recursion
5650 // algorithm back into a traditional recursion by explicitly calling
5651 // VisitChildren(). We will need to remove this explicit recursive call.
5652 W.AnnotateTokens();
5653
5654 // If we ran into any entities that involve context-sensitive keywords,
5655 // take another pass through the tokens to mark them as such.
5656 if (W.hasContextSensitiveKeywords()) {
5657 for (unsigned I = 0; I != NumTokens; ++I) {
5658 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5659 continue;
5660
5661 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5662 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005663 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005664 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5665 if (Property->getPropertyAttributesAsWritten() != 0 &&
5666 llvm::StringSwitch<bool>(II->getName())
5667 .Case("readonly", true)
5668 .Case("assign", true)
5669 .Case("unsafe_unretained", true)
5670 .Case("readwrite", true)
5671 .Case("retain", true)
5672 .Case("copy", true)
5673 .Case("nonatomic", true)
5674 .Case("atomic", true)
5675 .Case("getter", true)
5676 .Case("setter", true)
5677 .Case("strong", true)
5678 .Case("weak", true)
5679 .Default(false))
5680 Tokens[I].int_data[0] = CXToken_Keyword;
5681 }
5682 continue;
5683 }
5684
5685 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5686 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5687 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5688 if (llvm::StringSwitch<bool>(II->getName())
5689 .Case("in", true)
5690 .Case("out", true)
5691 .Case("inout", true)
5692 .Case("oneway", true)
5693 .Case("bycopy", true)
5694 .Case("byref", true)
5695 .Default(false))
5696 Tokens[I].int_data[0] = CXToken_Keyword;
5697 continue;
5698 }
5699
5700 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5701 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5702 Tokens[I].int_data[0] = CXToken_Keyword;
5703 continue;
5704 }
5705 }
5706 }
5707}
5708
5709extern "C" {
5710
5711void clang_annotateTokens(CXTranslationUnit TU,
5712 CXToken *Tokens, unsigned NumTokens,
5713 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005714 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005715 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005716 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005717 }
5718
5719 LOG_FUNC_SECTION {
5720 *Log << TU << ' ';
5721 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5722 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5723 *Log << clang_getRange(bloc, eloc);
5724 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005725
5726 // Any token we don't specifically annotate will have a NULL cursor.
5727 CXCursor C = clang_getNullCursor();
5728 for (unsigned I = 0; I != NumTokens; ++I)
5729 Cursors[I] = C;
5730
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005731 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005732 if (!CXXUnit)
5733 return;
5734
5735 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5736
5737 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5738 llvm::CrashRecoveryContext CRC;
5739 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5740 GetSafetyThreadStackSize() * 2)) {
5741 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5742 }
5743}
5744
5745} // end: extern "C"
5746
5747//===----------------------------------------------------------------------===//
5748// Operations for querying linkage of a cursor.
5749//===----------------------------------------------------------------------===//
5750
5751extern "C" {
5752CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5753 if (!clang_isDeclaration(cursor.kind))
5754 return CXLinkage_Invalid;
5755
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005756 const Decl *D = cxcursor::getCursorDecl(cursor);
5757 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005758 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005759 case NoLinkage:
5760 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005761 case InternalLinkage: return CXLinkage_Internal;
5762 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5763 case ExternalLinkage: return CXLinkage_External;
5764 };
5765
5766 return CXLinkage_Invalid;
5767}
5768} // end: extern "C"
5769
5770//===----------------------------------------------------------------------===//
5771// Operations for querying language of a cursor.
5772//===----------------------------------------------------------------------===//
5773
5774static CXLanguageKind getDeclLanguage(const Decl *D) {
5775 if (!D)
5776 return CXLanguage_C;
5777
5778 switch (D->getKind()) {
5779 default:
5780 break;
5781 case Decl::ImplicitParam:
5782 case Decl::ObjCAtDefsField:
5783 case Decl::ObjCCategory:
5784 case Decl::ObjCCategoryImpl:
5785 case Decl::ObjCCompatibleAlias:
5786 case Decl::ObjCImplementation:
5787 case Decl::ObjCInterface:
5788 case Decl::ObjCIvar:
5789 case Decl::ObjCMethod:
5790 case Decl::ObjCProperty:
5791 case Decl::ObjCPropertyImpl:
5792 case Decl::ObjCProtocol:
5793 return CXLanguage_ObjC;
5794 case Decl::CXXConstructor:
5795 case Decl::CXXConversion:
5796 case Decl::CXXDestructor:
5797 case Decl::CXXMethod:
5798 case Decl::CXXRecord:
5799 case Decl::ClassTemplate:
5800 case Decl::ClassTemplatePartialSpecialization:
5801 case Decl::ClassTemplateSpecialization:
5802 case Decl::Friend:
5803 case Decl::FriendTemplate:
5804 case Decl::FunctionTemplate:
5805 case Decl::LinkageSpec:
5806 case Decl::Namespace:
5807 case Decl::NamespaceAlias:
5808 case Decl::NonTypeTemplateParm:
5809 case Decl::StaticAssert:
5810 case Decl::TemplateTemplateParm:
5811 case Decl::TemplateTypeParm:
5812 case Decl::UnresolvedUsingTypename:
5813 case Decl::UnresolvedUsingValue:
5814 case Decl::Using:
5815 case Decl::UsingDirective:
5816 case Decl::UsingShadow:
5817 return CXLanguage_CPlusPlus;
5818 }
5819
5820 return CXLanguage_C;
5821}
5822
5823extern "C" {
5824
5825enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5826 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005827 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005828 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5829 return CXAvailability_Available;
5830
5831 switch (D->getAvailability()) {
5832 case AR_Available:
5833 case AR_NotYetIntroduced:
5834 return CXAvailability_Available;
5835
5836 case AR_Deprecated:
5837 return CXAvailability_Deprecated;
5838
5839 case AR_Unavailable:
5840 return CXAvailability_NotAvailable;
5841 }
5842 }
5843
5844 return CXAvailability_Available;
5845}
5846
5847static CXVersion convertVersion(VersionTuple In) {
5848 CXVersion Out = { -1, -1, -1 };
5849 if (In.empty())
5850 return Out;
5851
5852 Out.Major = In.getMajor();
5853
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005854 Optional<unsigned> Minor = In.getMinor();
5855 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005856 Out.Minor = *Minor;
5857 else
5858 return Out;
5859
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005860 Optional<unsigned> Subminor = In.getSubminor();
5861 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005862 Out.Subminor = *Subminor;
5863
5864 return Out;
5865}
5866
5867int clang_getCursorPlatformAvailability(CXCursor cursor,
5868 int *always_deprecated,
5869 CXString *deprecated_message,
5870 int *always_unavailable,
5871 CXString *unavailable_message,
5872 CXPlatformAvailability *availability,
5873 int availability_size) {
5874 if (always_deprecated)
5875 *always_deprecated = 0;
5876 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005877 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005878 if (always_unavailable)
5879 *always_unavailable = 0;
5880 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005881 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005882
5883 if (!clang_isDeclaration(cursor.kind))
5884 return 0;
5885
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005886 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005887 if (!D)
5888 return 0;
5889
5890 int N = 0;
5891 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5892 ++A) {
5893 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5894 if (always_deprecated)
5895 *always_deprecated = 1;
5896 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005897 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005898 continue;
5899 }
5900
5901 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5902 if (always_unavailable)
5903 *always_unavailable = 1;
5904 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005905 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005906 }
5907 continue;
5908 }
5909
5910 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5911 if (N < availability_size) {
5912 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005913 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005914 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5915 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5916 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5917 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005918 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005919 }
5920 ++N;
5921 }
5922 }
5923
5924 return N;
5925}
5926
5927void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5928 clang_disposeString(availability->Platform);
5929 clang_disposeString(availability->Message);
5930}
5931
5932CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5933 if (clang_isDeclaration(cursor.kind))
5934 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5935
5936 return CXLanguage_Invalid;
5937}
5938
5939 /// \brief If the given cursor is the "templated" declaration
5940 /// descibing a class or function template, return the class or
5941 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005942static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005943 if (!D)
5944 return 0;
5945
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005946 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005947 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5948 return FunTmpl;
5949
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005950 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005951 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5952 return ClassTmpl;
5953
5954 return D;
5955}
5956
5957CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5958 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005959 if (const Decl *D = getCursorDecl(cursor)) {
5960 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005961 if (!DC)
5962 return clang_getNullCursor();
5963
5964 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5965 getCursorTU(cursor));
5966 }
5967 }
5968
5969 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005970 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005971 return MakeCXCursor(D, getCursorTU(cursor));
5972 }
5973
5974 return clang_getNullCursor();
5975}
5976
5977CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5978 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005979 if (const Decl *D = getCursorDecl(cursor)) {
5980 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005981 if (!DC)
5982 return clang_getNullCursor();
5983
5984 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5985 getCursorTU(cursor));
5986 }
5987 }
5988
5989 // FIXME: Note that we can't easily compute the lexical context of a
5990 // statement or expression, so we return nothing.
5991 return clang_getNullCursor();
5992}
5993
5994CXFile clang_getIncludedFile(CXCursor cursor) {
5995 if (cursor.kind != CXCursor_InclusionDirective)
5996 return 0;
5997
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005998 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005999 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006000}
6001
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00006002unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6003 if (C.kind != CXCursor_ObjCPropertyDecl)
6004 return CXObjCPropertyAttr_noattr;
6005
6006 unsigned Result = CXObjCPropertyAttr_noattr;
6007 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6008 ObjCPropertyDecl::PropertyAttributeKind Attr =
6009 PD->getPropertyAttributesAsWritten();
6010
6011#define SET_CXOBJCPROP_ATTR(A) \
6012 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6013 Result |= CXObjCPropertyAttr_##A
6014 SET_CXOBJCPROP_ATTR(readonly);
6015 SET_CXOBJCPROP_ATTR(getter);
6016 SET_CXOBJCPROP_ATTR(assign);
6017 SET_CXOBJCPROP_ATTR(readwrite);
6018 SET_CXOBJCPROP_ATTR(retain);
6019 SET_CXOBJCPROP_ATTR(copy);
6020 SET_CXOBJCPROP_ATTR(nonatomic);
6021 SET_CXOBJCPROP_ATTR(setter);
6022 SET_CXOBJCPROP_ATTR(atomic);
6023 SET_CXOBJCPROP_ATTR(weak);
6024 SET_CXOBJCPROP_ATTR(strong);
6025 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6026#undef SET_CXOBJCPROP_ATTR
6027
6028 return Result;
6029}
6030
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00006031unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6032 if (!clang_isDeclaration(C.kind))
6033 return CXObjCDeclQualifier_None;
6034
6035 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6036 const Decl *D = getCursorDecl(C);
6037 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6038 QT = MD->getObjCDeclQualifier();
6039 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6040 QT = PD->getObjCDeclQualifier();
6041 if (QT == Decl::OBJC_TQ_None)
6042 return CXObjCDeclQualifier_None;
6043
6044 unsigned Result = CXObjCDeclQualifier_None;
6045 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6046 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6047 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6048 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6049 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6050 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6051
6052 return Result;
6053}
6054
Argyrios Kyrtzidis514afc72013-07-05 20:44:37 +00006055unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6056 if (!clang_isDeclaration(C.kind))
6057 return 0;
6058
6059 const Decl *D = getCursorDecl(C);
6060 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6061 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6062 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6063 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6064
6065 return 0;
6066}
6067
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00006068unsigned clang_Cursor_isVariadic(CXCursor C) {
6069 if (!clang_isDeclaration(C.kind))
6070 return 0;
6071
6072 const Decl *D = getCursorDecl(C);
6073 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6074 return FD->isVariadic();
6075 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6076 return MD->isVariadic();
6077
6078 return 0;
6079}
6080
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006081CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6082 if (!clang_isDeclaration(C.kind))
6083 return clang_getNullRange();
6084
6085 const Decl *D = getCursorDecl(C);
6086 ASTContext &Context = getCursorContext(C);
6087 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6088 if (!RC)
6089 return clang_getNullRange();
6090
6091 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6092}
6093
6094CXString clang_Cursor_getRawCommentText(CXCursor C) {
6095 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006096 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006097
6098 const Decl *D = getCursorDecl(C);
6099 ASTContext &Context = getCursorContext(C);
6100 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6101 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6102 StringRef();
6103
6104 // Don't duplicate the string because RawText points directly into source
6105 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006106 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006107}
6108
6109CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6110 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006111 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006112
6113 const Decl *D = getCursorDecl(C);
6114 const ASTContext &Context = getCursorContext(C);
6115 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6116
6117 if (RC) {
6118 StringRef BriefText = RC->getBriefText(Context);
6119
6120 // Don't duplicate the string because RawComment ensures that this memory
6121 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006122 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006123 }
6124
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006125 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006126}
6127
6128CXComment clang_Cursor_getParsedComment(CXCursor C) {
6129 if (!clang_isDeclaration(C.kind))
6130 return cxcomment::createCXComment(NULL, NULL);
6131
6132 const Decl *D = getCursorDecl(C);
6133 const ASTContext &Context = getCursorContext(C);
6134 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6135
6136 return cxcomment::createCXComment(FC, getCursorTU(C));
6137}
6138
6139CXModule clang_Cursor_getModule(CXCursor C) {
6140 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006141 if (const ImportDecl *ImportD =
6142 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006143 return ImportD->getImportedModule();
6144 }
6145
6146 return 0;
6147}
6148
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006149CXFile clang_Module_getASTFile(CXModule CXMod) {
6150 if (!CXMod)
6151 return 0;
6152 Module *Mod = static_cast<Module*>(CXMod);
6153 return const_cast<FileEntry *>(Mod->getASTFile());
6154}
6155
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006156CXModule clang_Module_getParent(CXModule CXMod) {
6157 if (!CXMod)
6158 return 0;
6159 Module *Mod = static_cast<Module*>(CXMod);
6160 return Mod->Parent;
6161}
6162
6163CXString clang_Module_getName(CXModule CXMod) {
6164 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006165 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006166 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006167 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006168}
6169
6170CXString clang_Module_getFullName(CXModule CXMod) {
6171 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006172 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006173 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006174 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006175}
6176
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006177unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6178 CXModule CXMod) {
6179 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006180 return 0;
6181 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006182 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6183 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6184 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006185}
6186
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006187CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6188 CXModule CXMod, unsigned Index) {
6189 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006190 return 0;
6191 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006192 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006193
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006194 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6195 if (Index < TopHeaders.size())
6196 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006197
6198 return 0;
6199}
6200
6201} // end: extern "C"
6202
6203//===----------------------------------------------------------------------===//
6204// C++ AST instrospection.
6205//===----------------------------------------------------------------------===//
6206
6207extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006208unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6209 if (!clang_isDeclaration(C.kind))
6210 return 0;
6211
6212 const CXXMethodDecl *Method = 0;
6213 const Decl *D = cxcursor::getCursorDecl(C);
6214 if (const FunctionTemplateDecl *FunTmpl =
6215 dyn_cast_or_null<FunctionTemplateDecl>(D))
6216 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6217 else
6218 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6219 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6220}
6221
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006222unsigned clang_CXXMethod_isStatic(CXCursor C) {
6223 if (!clang_isDeclaration(C.kind))
6224 return 0;
6225
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006226 const CXXMethodDecl *Method = 0;
6227 const Decl *D = cxcursor::getCursorDecl(C);
6228 if (const FunctionTemplateDecl *FunTmpl =
6229 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006230 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6231 else
6232 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6233 return (Method && Method->isStatic()) ? 1 : 0;
6234}
6235
6236unsigned clang_CXXMethod_isVirtual(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->isVirtual()) ? 1 : 0;
6248}
6249} // end: extern "C"
6250
6251//===----------------------------------------------------------------------===//
6252// Attribute introspection.
6253//===----------------------------------------------------------------------===//
6254
6255extern "C" {
6256CXType clang_getIBOutletCollectionType(CXCursor C) {
6257 if (C.kind != CXCursor_IBOutletCollectionAttr)
6258 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6259
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006260 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006261 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6262
6263 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6264}
6265} // end: extern "C"
6266
6267//===----------------------------------------------------------------------===//
6268// Inspecting memory usage.
6269//===----------------------------------------------------------------------===//
6270
6271typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6272
6273static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6274 enum CXTUResourceUsageKind k,
6275 unsigned long amount) {
6276 CXTUResourceUsageEntry entry = { k, amount };
6277 entries.push_back(entry);
6278}
6279
6280extern "C" {
6281
6282const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6283 const char *str = "";
6284 switch (kind) {
6285 case CXTUResourceUsage_AST:
6286 str = "ASTContext: expressions, declarations, and types";
6287 break;
6288 case CXTUResourceUsage_Identifiers:
6289 str = "ASTContext: identifiers";
6290 break;
6291 case CXTUResourceUsage_Selectors:
6292 str = "ASTContext: selectors";
6293 break;
6294 case CXTUResourceUsage_GlobalCompletionResults:
6295 str = "Code completion: cached global results";
6296 break;
6297 case CXTUResourceUsage_SourceManagerContentCache:
6298 str = "SourceManager: content cache allocator";
6299 break;
6300 case CXTUResourceUsage_AST_SideTables:
6301 str = "ASTContext: side tables";
6302 break;
6303 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6304 str = "SourceManager: malloc'ed memory buffers";
6305 break;
6306 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6307 str = "SourceManager: mmap'ed memory buffers";
6308 break;
6309 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6310 str = "ExternalASTSource: malloc'ed memory buffers";
6311 break;
6312 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6313 str = "ExternalASTSource: mmap'ed memory buffers";
6314 break;
6315 case CXTUResourceUsage_Preprocessor:
6316 str = "Preprocessor: malloc'ed memory";
6317 break;
6318 case CXTUResourceUsage_PreprocessingRecord:
6319 str = "Preprocessor: PreprocessingRecord";
6320 break;
6321 case CXTUResourceUsage_SourceManager_DataStructures:
6322 str = "SourceManager: data structures and tables";
6323 break;
6324 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6325 str = "Preprocessor: header search tables";
6326 break;
6327 }
6328 return str;
6329}
6330
6331CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6332 if (!TU) {
6333 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6334 return usage;
6335 }
6336
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006337 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006338 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6339 ASTContext &astContext = astUnit->getASTContext();
6340
6341 // How much memory is used by AST nodes and types?
6342 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6343 (unsigned long) astContext.getASTAllocatedMemory());
6344
6345 // How much memory is used by identifiers?
6346 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6347 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6348
6349 // How much memory is used for selectors?
6350 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6351 (unsigned long) astContext.Selectors.getTotalMemory());
6352
6353 // How much memory is used by ASTContext's side tables?
6354 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6355 (unsigned long) astContext.getSideTableAllocatedMemory());
6356
6357 // How much memory is used for caching global code completion results?
6358 unsigned long completionBytes = 0;
6359 if (GlobalCodeCompletionAllocator *completionAllocator =
6360 astUnit->getCachedCompletionAllocator().getPtr()) {
6361 completionBytes = completionAllocator->getTotalMemory();
6362 }
6363 createCXTUResourceUsageEntry(*entries,
6364 CXTUResourceUsage_GlobalCompletionResults,
6365 completionBytes);
6366
6367 // How much memory is being used by SourceManager's content cache?
6368 createCXTUResourceUsageEntry(*entries,
6369 CXTUResourceUsage_SourceManagerContentCache,
6370 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6371
6372 // How much memory is being used by the MemoryBuffer's in SourceManager?
6373 const SourceManager::MemoryBufferSizes &srcBufs =
6374 astUnit->getSourceManager().getMemoryBufferSizes();
6375
6376 createCXTUResourceUsageEntry(*entries,
6377 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6378 (unsigned long) srcBufs.malloc_bytes);
6379 createCXTUResourceUsageEntry(*entries,
6380 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6381 (unsigned long) srcBufs.mmap_bytes);
6382 createCXTUResourceUsageEntry(*entries,
6383 CXTUResourceUsage_SourceManager_DataStructures,
6384 (unsigned long) astContext.getSourceManager()
6385 .getDataStructureSizes());
6386
6387 // How much memory is being used by the ExternalASTSource?
6388 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6389 const ExternalASTSource::MemoryBufferSizes &sizes =
6390 esrc->getMemoryBufferSizes();
6391
6392 createCXTUResourceUsageEntry(*entries,
6393 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6394 (unsigned long) sizes.malloc_bytes);
6395 createCXTUResourceUsageEntry(*entries,
6396 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6397 (unsigned long) sizes.mmap_bytes);
6398 }
6399
6400 // How much memory is being used by the Preprocessor?
6401 Preprocessor &pp = astUnit->getPreprocessor();
6402 createCXTUResourceUsageEntry(*entries,
6403 CXTUResourceUsage_Preprocessor,
6404 pp.getTotalMemory());
6405
6406 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6407 createCXTUResourceUsageEntry(*entries,
6408 CXTUResourceUsage_PreprocessingRecord,
6409 pRec->getTotalMemory());
6410 }
6411
6412 createCXTUResourceUsageEntry(*entries,
6413 CXTUResourceUsage_Preprocessor_HeaderSearch,
6414 pp.getHeaderSearchInfo().getTotalMemory());
6415
6416 CXTUResourceUsage usage = { (void*) entries.get(),
6417 (unsigned) entries->size(),
6418 entries->size() ? &(*entries)[0] : 0 };
6419 entries.take();
6420 return usage;
6421}
6422
6423void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6424 if (usage.data)
6425 delete (MemUsageEntries*) usage.data;
6426}
6427
6428} // end extern "C"
6429
6430void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6431 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6432 for (unsigned I = 0; I != Usage.numEntries; ++I)
6433 fprintf(stderr, " %s: %lu\n",
6434 clang_getTUResourceUsageName(Usage.entries[I].kind),
6435 Usage.entries[I].amount);
6436
6437 clang_disposeCXTUResourceUsage(Usage);
6438}
6439
6440//===----------------------------------------------------------------------===//
6441// Misc. utility functions.
6442//===----------------------------------------------------------------------===//
6443
6444/// Default to using an 8 MB stack size on "safety" threads.
6445static unsigned SafetyStackThreadSize = 8 << 20;
6446
6447namespace clang {
6448
6449bool RunSafely(llvm::CrashRecoveryContext &CRC,
6450 void (*Fn)(void*), void *UserData,
6451 unsigned Size) {
6452 if (!Size)
6453 Size = GetSafetyThreadStackSize();
6454 if (Size)
6455 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6456 return CRC.RunSafely(Fn, UserData);
6457}
6458
6459unsigned GetSafetyThreadStackSize() {
6460 return SafetyStackThreadSize;
6461}
6462
6463void SetSafetyThreadStackSize(unsigned Value) {
6464 SafetyStackThreadSize = Value;
6465}
6466
6467}
6468
6469void clang::setThreadBackgroundPriority() {
6470 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6471 return;
6472
6473 // FIXME: Move to llvm/Support and make it cross-platform.
6474#ifdef __APPLE__
6475 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6476#endif
6477}
6478
6479void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6480 if (!Unit)
6481 return;
6482
6483 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6484 DEnd = Unit->stored_diag_end();
6485 D != DEnd; ++D) {
6486 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6487 CXString Msg = clang_formatDiagnostic(&Diag,
6488 clang_defaultDiagnosticDisplayOptions());
6489 fprintf(stderr, "%s\n", clang_getCString(Msg));
6490 clang_disposeString(Msg);
6491 }
6492#ifdef LLVM_ON_WIN32
6493 // On Windows, force a flush, since there may be multiple copies of
6494 // stderr and stdout in the file system, all with different buffers
6495 // but writing to the same device.
6496 fflush(stderr);
6497#endif
6498}
6499
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006500MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6501 SourceLocation MacroDefLoc,
6502 CXTranslationUnit TU){
6503 if (MacroDefLoc.isInvalid() || !TU)
6504 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006505 if (!II.hadMacroDefinition())
6506 return 0;
6507
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006508 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006509 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006510 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006511 if (MD) {
6512 for (MacroDirective::DefInfo
6513 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6514 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6515 return Def.getMacroInfo();
6516 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006517 }
6518
6519 return 0;
6520}
6521
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006522const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6523 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006524 if (!MacroDef || !TU)
6525 return 0;
6526 const IdentifierInfo *II = MacroDef->getName();
6527 if (!II)
6528 return 0;
6529
6530 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6531}
6532
6533MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6534 const Token &Tok,
6535 CXTranslationUnit TU) {
6536 if (!MI || !TU)
6537 return 0;
6538 if (Tok.isNot(tok::raw_identifier))
6539 return 0;
6540
6541 if (MI->getNumTokens() == 0)
6542 return 0;
6543 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6544 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006545 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006546
6547 // Check that the token is inside the definition and not its argument list.
6548 SourceManager &SM = Unit->getSourceManager();
6549 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6550 return 0;
6551 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6552 return 0;
6553
6554 Preprocessor &PP = Unit->getPreprocessor();
6555 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6556 if (!PPRec)
6557 return 0;
6558
6559 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6560 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6561 if (!II.hadMacroDefinition())
6562 return 0;
6563
6564 // Check that the identifier is not one of the macro arguments.
6565 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6566 return 0;
6567
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006568 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6569 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006570 return 0;
6571
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006572 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006573}
6574
6575MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6576 SourceLocation Loc,
6577 CXTranslationUnit TU) {
6578 if (Loc.isInvalid() || !MI || !TU)
6579 return 0;
6580
6581 if (MI->getNumTokens() == 0)
6582 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006583 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006584 Preprocessor &PP = Unit->getPreprocessor();
6585 if (!PP.getPreprocessingRecord())
6586 return 0;
6587 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6588 Token Tok;
6589 if (PP.getRawToken(Loc, Tok))
6590 return 0;
6591
6592 return checkForMacroInMacroDefinition(MI, Tok, TU);
6593}
6594
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006595extern "C" {
6596
6597CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006598 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006599}
6600
6601} // end: extern "C"
6602
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006603Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6604 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006605 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006606 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006607 if (Unit->isMainFileAST())
6608 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006609 return *this;
6610 }
6611 }
6612
6613 LogOS << "<NULL TU>";
6614 return *this;
6615}
6616
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006617Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6618 *this << FE->getName();
6619 return *this;
6620}
6621
6622Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6623 CXString cursorName = clang_getCursorDisplayName(cursor);
6624 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6625 clang_disposeString(cursorName);
6626 return *this;
6627}
6628
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006629Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6630 CXFile File;
6631 unsigned Line, Column;
6632 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6633 CXString FileName = clang_getFileName(File);
6634 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6635 clang_disposeString(FileName);
6636 return *this;
6637}
6638
6639Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6640 CXSourceLocation BLoc = clang_getRangeStart(range);
6641 CXSourceLocation ELoc = clang_getRangeEnd(range);
6642
6643 CXFile BFile;
6644 unsigned BLine, BColumn;
6645 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6646
6647 CXFile EFile;
6648 unsigned ELine, EColumn;
6649 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6650
6651 CXString BFileName = clang_getFileName(BFile);
6652 if (BFile == EFile) {
6653 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6654 BLine, BColumn, ELine, EColumn);
6655 } else {
6656 CXString EFileName = clang_getFileName(EFile);
6657 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6658 BLine, BColumn)
6659 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6660 ELine, EColumn);
6661 clang_disposeString(EFileName);
6662 }
6663 clang_disposeString(BFileName);
6664 return *this;
6665}
6666
6667Logger &cxindex::Logger::operator<<(CXString Str) {
6668 *this << clang_getCString(Str);
6669 return *this;
6670}
6671
6672Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6673 LogOS << Fmt;
6674 return *this;
6675}
6676
6677cxindex::Logger::~Logger() {
6678 LogOS.flush();
6679
6680 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6681
6682 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6683
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006684 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006685 OS << "[libclang:" << Name << ':';
6686
6687 // FIXME: Portability.
6688#if HAVE_PTHREAD_H && __APPLE__
6689 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6690 OS << tid << ':';
6691#endif
6692
6693 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6694 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6695 OS << Msg.str() << '\n';
6696
6697 if (Trace) {
6698 llvm::sys::PrintStackTrace(stderr);
6699 OS << "--------------------------------------------------\n";
6700 }
6701}