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