blob: fa106e990d9b08765f3fbd757bbd5ddc66f4364e [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
765/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000769}
770
771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
919 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
920 PEnd = ND->param_end();
921 P != PEnd; ++P) {
922 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
954namespace {
955 struct ContainerDeclsSort {
956 SourceManager &SM;
957 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
958 bool operator()(Decl *A, Decl *B) {
959 SourceLocation L_A = A->getLocStart();
960 SourceLocation L_B = B->getLocStart();
961 assert(L_A.isValid() && L_B.isValid());
962 return SM.isBeforeInTranslationUnit(L_A, L_B);
963 }
964 };
965}
966
967bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
968 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
969 // an @implementation can lexically contain Decls that are not properly
970 // nested in the AST. When we identify such cases, we need to retrofit
971 // this nesting here.
972 if (!DI_current && !FileDI_current)
973 return VisitDeclContext(D);
974
975 // Scan the Decls that immediately come after the container
976 // in the current DeclContext. If any fall within the
977 // container's lexical region, stash them into a vector
978 // for later processing.
979 SmallVector<Decl *, 24> DeclsInContainer;
980 SourceLocation EndLoc = D->getSourceRange().getEnd();
981 SourceManager &SM = AU->getSourceManager();
982 if (EndLoc.isValid()) {
983 if (DI_current) {
984 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
985 DeclsInContainer);
986 } else {
987 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
988 DeclsInContainer);
989 }
990 }
991
992 // The common case.
993 if (DeclsInContainer.empty())
994 return VisitDeclContext(D);
995
996 // Get all the Decls in the DeclContext, and sort them with the
997 // additional ones we've collected. Then visit them.
998 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
999 I!=E; ++I) {
1000 Decl *subDecl = *I;
1001 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
1002 subDecl->getLocStart().isInvalid())
1003 continue;
1004 DeclsInContainer.push_back(subDecl);
1005 }
1006
1007 // Now sort the Decls so that they appear in lexical order.
1008 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1009 ContainerDeclsSort(SM));
1010
1011 // Now visit the decls.
1012 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1013 E = DeclsInContainer.end(); I != E; ++I) {
1014 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001015 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001016 if (!V.hasValue())
1017 continue;
1018 if (!V.getValue())
1019 return false;
1020 if (Visit(Cursor, true))
1021 return true;
1022 }
1023 return false;
1024}
1025
1026bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1027 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1028 TU)))
1029 return true;
1030
1031 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1032 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1033 E = ND->protocol_end(); I != E; ++I, ++PL)
1034 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1035 return true;
1036
1037 return VisitObjCContainerDecl(ND);
1038}
1039
1040bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1041 if (!PID->isThisDeclarationADefinition())
1042 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1043
1044 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1045 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1046 E = PID->protocol_end(); I != E; ++I, ++PL)
1047 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1048 return true;
1049
1050 return VisitObjCContainerDecl(PID);
1051}
1052
1053bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1054 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1055 return true;
1056
1057 // FIXME: This implements a workaround with @property declarations also being
1058 // installed in the DeclContext for the @interface. Eventually this code
1059 // should be removed.
1060 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1061 if (!CDecl || !CDecl->IsClassExtension())
1062 return false;
1063
1064 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1065 if (!ID)
1066 return false;
1067
1068 IdentifierInfo *PropertyId = PD->getIdentifier();
1069 ObjCPropertyDecl *prevDecl =
1070 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1071
1072 if (!prevDecl)
1073 return false;
1074
1075 // Visit synthesized methods since they will be skipped when visiting
1076 // the @interface.
1077 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1078 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1079 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1080 return true;
1081
1082 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1083 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1084 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1085 return true;
1086
1087 return false;
1088}
1089
1090bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1091 if (!D->isThisDeclarationADefinition()) {
1092 // Forward declaration is treated like a reference.
1093 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1094 }
1095
1096 // Issue callbacks for super class.
1097 if (D->getSuperClass() &&
1098 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1099 D->getSuperClassLoc(),
1100 TU)))
1101 return true;
1102
1103 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1104 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1105 E = D->protocol_end(); I != E; ++I, ++PL)
1106 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1107 return true;
1108
1109 return VisitObjCContainerDecl(D);
1110}
1111
1112bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1113 return VisitObjCContainerDecl(D);
1114}
1115
1116bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1117 // 'ID' could be null when dealing with invalid code.
1118 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1119 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1120 return true;
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1126#if 0
1127 // Issue callbacks for super class.
1128 // FIXME: No source location information!
1129 if (D->getSuperClass() &&
1130 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1131 D->getSuperClassLoc(),
1132 TU)))
1133 return true;
1134#endif
1135
1136 return VisitObjCImplDecl(D);
1137}
1138
1139bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1140 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1141 if (PD->isIvarNameSpecified())
1142 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1143
1144 return false;
1145}
1146
1147bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1148 return VisitDeclContext(D);
1149}
1150
1151bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156
1157 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1158 D->getTargetNameLoc(), TU));
1159}
1160
1161bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1162 // Visit nested-name-specifier.
1163 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1164 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1165 return true;
1166 }
1167
1168 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1169 return true;
1170
1171 return VisitDeclarationNameInfo(D->getNameInfo());
1172}
1173
1174bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179
1180 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1181 D->getIdentLocation(), TU));
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1185 // Visit nested-name-specifier.
1186 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1187 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1188 return true;
1189 }
1190
1191 return VisitDeclarationNameInfo(D->getNameInfo());
1192}
1193
1194bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1195 UnresolvedUsingTypenameDecl *D) {
1196 // Visit nested-name-specifier.
1197 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1198 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1199 return true;
1200
1201 return false;
1202}
1203
1204bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1205 switch (Name.getName().getNameKind()) {
1206 case clang::DeclarationName::Identifier:
1207 case clang::DeclarationName::CXXLiteralOperatorName:
1208 case clang::DeclarationName::CXXOperatorName:
1209 case clang::DeclarationName::CXXUsingDirective:
1210 return false;
1211
1212 case clang::DeclarationName::CXXConstructorName:
1213 case clang::DeclarationName::CXXDestructorName:
1214 case clang::DeclarationName::CXXConversionFunctionName:
1215 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1216 return Visit(TSInfo->getTypeLoc());
1217 return false;
1218
1219 case clang::DeclarationName::ObjCZeroArgSelector:
1220 case clang::DeclarationName::ObjCOneArgSelector:
1221 case clang::DeclarationName::ObjCMultiArgSelector:
1222 // FIXME: Per-identifier location info?
1223 return false;
1224 }
1225
1226 llvm_unreachable("Invalid DeclarationName::Kind!");
1227}
1228
1229bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1230 SourceRange Range) {
1231 // FIXME: This whole routine is a hack to work around the lack of proper
1232 // source information in nested-name-specifiers (PR5791). Since we do have
1233 // a beginning source location, we can visit the first component of the
1234 // nested-name-specifier, if it's a single-token component.
1235 if (!NNS)
1236 return false;
1237
1238 // Get the first component in the nested-name-specifier.
1239 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1240 NNS = Prefix;
1241
1242 switch (NNS->getKind()) {
1243 case NestedNameSpecifier::Namespace:
1244 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1245 TU));
1246
1247 case NestedNameSpecifier::NamespaceAlias:
1248 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1249 Range.getBegin(), TU));
1250
1251 case NestedNameSpecifier::TypeSpec: {
1252 // If the type has a form where we know that the beginning of the source
1253 // range matches up with a reference cursor. Visit the appropriate reference
1254 // cursor.
1255 const Type *T = NNS->getAsType();
1256 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1257 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1258 if (const TagType *Tag = dyn_cast<TagType>(T))
1259 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1260 if (const TemplateSpecializationType *TST
1261 = dyn_cast<TemplateSpecializationType>(T))
1262 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1263 break;
1264 }
1265
1266 case NestedNameSpecifier::TypeSpecWithTemplate:
1267 case NestedNameSpecifier::Global:
1268 case NestedNameSpecifier::Identifier:
1269 break;
1270 }
1271
1272 return false;
1273}
1274
1275bool
1276CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1277 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1278 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1279 Qualifiers.push_back(Qualifier);
1280
1281 while (!Qualifiers.empty()) {
1282 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1283 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1284 switch (NNS->getKind()) {
1285 case NestedNameSpecifier::Namespace:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::NamespaceAlias:
1294 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1295 Q.getLocalBeginLoc(),
1296 TU)))
1297 return true;
1298
1299 break;
1300
1301 case NestedNameSpecifier::TypeSpec:
1302 case NestedNameSpecifier::TypeSpecWithTemplate:
1303 if (Visit(Q.getTypeLoc()))
1304 return true;
1305
1306 break;
1307
1308 case NestedNameSpecifier::Global:
1309 case NestedNameSpecifier::Identifier:
1310 break;
1311 }
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateParameters(
1318 const TemplateParameterList *Params) {
1319 if (!Params)
1320 return false;
1321
1322 for (TemplateParameterList::const_iterator P = Params->begin(),
1323 PEnd = Params->end();
1324 P != PEnd; ++P) {
1325 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1326 return true;
1327 }
1328
1329 return false;
1330}
1331
1332bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1333 switch (Name.getKind()) {
1334 case TemplateName::Template:
1335 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1336
1337 case TemplateName::OverloadedTemplate:
1338 // Visit the overloaded template set.
1339 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1340 return true;
1341
1342 return false;
1343
1344 case TemplateName::DependentTemplate:
1345 // FIXME: Visit nested-name-specifier.
1346 return false;
1347
1348 case TemplateName::QualifiedTemplate:
1349 // FIXME: Visit nested-name-specifier.
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsQualifiedTemplateName()->getDecl(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParm:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1357 Loc, TU));
1358
1359 case TemplateName::SubstTemplateTemplateParmPack:
1360 return Visit(MakeCursorTemplateRef(
1361 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1362 Loc, TU));
1363 }
1364
1365 llvm_unreachable("Invalid TemplateName::Kind!");
1366}
1367
1368bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1369 switch (TAL.getArgument().getKind()) {
1370 case TemplateArgument::Null:
1371 case TemplateArgument::Integral:
1372 case TemplateArgument::Pack:
1373 return false;
1374
1375 case TemplateArgument::Type:
1376 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1377 return Visit(TSInfo->getTypeLoc());
1378 return false;
1379
1380 case TemplateArgument::Declaration:
1381 if (Expr *E = TAL.getSourceDeclExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::NullPtr:
1386 if (Expr *E = TAL.getSourceNullPtrExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Expression:
1391 if (Expr *E = TAL.getSourceExpression())
1392 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1393 return false;
1394
1395 case TemplateArgument::Template:
1396 case TemplateArgument::TemplateExpansion:
1397 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1398 return true;
1399
1400 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1401 TAL.getTemplateNameLoc());
1402 }
1403
1404 llvm_unreachable("Invalid TemplateArgument::Kind!");
1405}
1406
1407bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1408 return VisitDeclContext(D);
1409}
1410
1411bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1412 return Visit(TL.getUnqualifiedLoc());
1413}
1414
1415bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1416 ASTContext &Context = AU->getASTContext();
1417
1418 // Some builtin types (such as Objective-C's "id", "sel", and
1419 // "Class") have associated declarations. Create cursors for those.
1420 QualType VisitType;
1421 switch (TL.getTypePtr()->getKind()) {
1422
1423 case BuiltinType::Void:
1424 case BuiltinType::NullPtr:
1425 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001426 case BuiltinType::OCLImage1d:
1427 case BuiltinType::OCLImage1dArray:
1428 case BuiltinType::OCLImage1dBuffer:
1429 case BuiltinType::OCLImage2d:
1430 case BuiltinType::OCLImage2dArray:
1431 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001432 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001433 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001434#define BUILTIN_TYPE(Id, SingletonId)
1435#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1436#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1437#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1438#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1439#include "clang/AST/BuiltinTypes.def"
1440 break;
1441
1442 case BuiltinType::ObjCId:
1443 VisitType = Context.getObjCIdType();
1444 break;
1445
1446 case BuiltinType::ObjCClass:
1447 VisitType = Context.getObjCClassType();
1448 break;
1449
1450 case BuiltinType::ObjCSel:
1451 VisitType = Context.getObjCSelType();
1452 break;
1453 }
1454
1455 if (!VisitType.isNull()) {
1456 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1457 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1458 TU));
1459 }
1460
1461 return false;
1462}
1463
1464bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1469 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1470}
1471
1472bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1473 if (TL.isDefinition())
1474 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1475
1476 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477}
1478
1479bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1480 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1481}
1482
1483bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1484 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1485 return true;
1486
1487 return false;
1488}
1489
1490bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1491 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1492 return true;
1493
1494 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1495 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1496 TU)))
1497 return true;
1498 }
1499
1500 return false;
1501}
1502
1503bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1508 return Visit(TL.getInnerLoc());
1509}
1510
1511bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1524 return Visit(TL.getPointeeLoc());
1525}
1526
1527bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1528 return Visit(TL.getPointeeLoc());
1529}
1530
1531bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1532 return Visit(TL.getModifiedLoc());
1533}
1534
1535bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1536 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001537 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 return true;
1539
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001540 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1541 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001542 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1543 return true;
1544
1545 return false;
1546}
1547
1548bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1549 if (Visit(TL.getElementLoc()))
1550 return true;
1551
1552 if (Expr *Size = TL.getSizeExpr())
1553 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1554
1555 return false;
1556}
1557
Reid Kleckner8a365022013-06-24 17:51:48 +00001558bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1559 return Visit(TL.getOriginalLoc());
1560}
1561
Reid Kleckner0503a872013-12-05 01:23:43 +00001562bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1563 return Visit(TL.getOriginalLoc());
1564}
1565
Guy Benyei11169dd2012-12-18 14:30:41 +00001566bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1567 TemplateSpecializationTypeLoc TL) {
1568 // Visit the template name.
1569 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1570 TL.getTemplateNameLoc()))
1571 return true;
1572
1573 // Visit the template arguments.
1574 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1575 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1576 return true;
1577
1578 return false;
1579}
1580
1581bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1582 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1583}
1584
1585bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1586 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1587 return Visit(TSInfo->getTypeLoc());
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1593 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1594 return Visit(TSInfo->getTypeLoc());
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1600 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 return false;
1604}
1605
1606bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1607 DependentTemplateSpecializationTypeLoc TL) {
1608 // Visit the nested-name-specifier, if there is one.
1609 if (TL.getQualifierLoc() &&
1610 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 // Visit the template arguments.
1614 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1615 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1616 return true;
1617
1618 return false;
1619}
1620
1621bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1622 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1623 return true;
1624
1625 return Visit(TL.getNamedTypeLoc());
1626}
1627
1628bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1629 return Visit(TL.getPatternLoc());
1630}
1631
1632bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1633 if (Expr *E = TL.getUnderlyingExpr())
1634 return Visit(MakeCXCursor(E, StmtParent, TU));
1635
1636 return false;
1637}
1638
1639bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1640 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1641}
1642
1643bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1644 return Visit(TL.getValueLoc());
1645}
1646
1647#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1648bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1649 return Visit##PARENT##Loc(TL); \
1650}
1651
1652DEFAULT_TYPELOC_IMPL(Complex, Type)
1653DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1654DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1655DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1656DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1657DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1658DEFAULT_TYPELOC_IMPL(Vector, Type)
1659DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1660DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1661DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1662DEFAULT_TYPELOC_IMPL(Record, TagType)
1663DEFAULT_TYPELOC_IMPL(Enum, TagType)
1664DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1665DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1666DEFAULT_TYPELOC_IMPL(Auto, Type)
1667
1668bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1669 // Visit the nested-name-specifier, if present.
1670 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1671 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1672 return true;
1673
1674 if (D->isCompleteDefinition()) {
1675 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1676 E = D->bases_end(); I != E; ++I) {
1677 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1678 return true;
1679 }
1680 }
1681
1682 return VisitTagDecl(D);
1683}
1684
1685bool CursorVisitor::VisitAttributes(Decl *D) {
1686 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1687 i != e; ++i)
1688 if (Visit(MakeCXCursor(*i, D, TU)))
1689 return true;
1690
1691 return false;
1692}
1693
1694//===----------------------------------------------------------------------===//
1695// Data-recursive visitor methods.
1696//===----------------------------------------------------------------------===//
1697
1698namespace {
1699#define DEF_JOB(NAME, DATA, KIND)\
1700class NAME : public VisitorJob {\
1701public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001702 NAME(const DATA *d, CXCursor parent) : \
1703 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001704 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001706};
1707
1708DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1709DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1710DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1711DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1712DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1713 ExplicitTemplateArgsVisitKind)
1714DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1715DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1716DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1717#undef DEF_JOB
1718
1719class DeclVisit : public VisitorJob {
1720public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001723 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == DeclVisitKind;
1726 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001727 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001728 bool isFirst() const { return data[1] ? true : false; }
1729};
1730class TypeLocVisit : public VisitorJob {
1731public:
1732 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1733 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1734 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == TypeLocVisitKind;
1738 }
1739
1740 TypeLoc get() const {
1741 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001742 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001743 }
1744};
1745
1746class LabelRefVisit : public VisitorJob {
1747public:
1748 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1750 labelLoc.getPtrEncoding()) {}
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1754 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001755 const LabelDecl *get() const {
1756 return static_cast<const LabelDecl *>(data[0]);
1757 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001758 SourceLocation getLoc() const {
1759 return SourceLocation::getFromPtrEncoding(data[1]); }
1760};
1761
1762class NestedNameSpecifierLocVisit : public VisitorJob {
1763public:
1764 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1765 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1766 Qualifier.getNestedNameSpecifier(),
1767 Qualifier.getOpaqueData()) { }
1768
1769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1771 }
1772
1773 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001774 return NestedNameSpecifierLoc(
1775 const_cast<NestedNameSpecifier *>(
1776 static_cast<const NestedNameSpecifier *>(data[0])),
1777 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 }
1779};
1780
1781class DeclarationNameInfoVisit : public VisitorJob {
1782public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001784 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001785 static bool classof(const VisitorJob *VJ) {
1786 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1787 }
1788 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001789 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001790 switch (S->getStmtClass()) {
1791 default:
1792 llvm_unreachable("Unhandled Stmt");
1793 case clang::Stmt::MSDependentExistsStmtClass:
1794 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1795 case Stmt::CXXDependentScopeMemberExprClass:
1796 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1797 case Stmt::DependentScopeDeclRefExprClass:
1798 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1799 }
1800 }
1801};
1802class MemberRefVisit : public VisitorJob {
1803public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001805 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1806 L.getPtrEncoding()) {}
1807 static bool classof(const VisitorJob *VJ) {
1808 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1809 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001810 const FieldDecl *get() const {
1811 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001812 }
1813 SourceLocation getLoc() const {
1814 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1815 }
1816};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001817class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001818 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001819 VisitorWorkList &WL;
1820 CXCursor Parent;
1821public:
1822 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1823 : WL(wl), Parent(parent) {}
1824
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001825 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1826 void VisitBlockExpr(const BlockExpr *B);
1827 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1828 void VisitCompoundStmt(const CompoundStmt *S);
1829 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1830 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1831 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1832 void VisitCXXNewExpr(const CXXNewExpr *E);
1833 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1834 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1835 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1836 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1837 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1838 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1839 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1840 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1841 void VisitDeclRefExpr(const DeclRefExpr *D);
1842 void VisitDeclStmt(const DeclStmt *S);
1843 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1844 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1845 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1846 void VisitForStmt(const ForStmt *FS);
1847 void VisitGotoStmt(const GotoStmt *GS);
1848 void VisitIfStmt(const IfStmt *If);
1849 void VisitInitListExpr(const InitListExpr *IE);
1850 void VisitMemberExpr(const MemberExpr *M);
1851 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1852 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1853 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1854 void VisitOverloadExpr(const OverloadExpr *E);
1855 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1856 void VisitStmt(const Stmt *S);
1857 void VisitSwitchStmt(const SwitchStmt *S);
1858 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1860 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1861 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1862 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1863 void VisitVAArgExpr(const VAArgExpr *E);
1864 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1865 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1866 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1867 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001868 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1869 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001870 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871
Guy Benyei11169dd2012-12-18 14:30:41 +00001872private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001874 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1875 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1877 void AddStmt(const Stmt *S);
1878 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001881 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001882};
1883} // end anonyous namespace
1884
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 // 'S' should always be non-null, since it comes from the
1887 // statement we are visiting.
1888 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1889}
1890
1891void
1892EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1893 if (Qualifier)
1894 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1895}
1896
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 if (S)
1899 WL.push_back(StmtVisit(S, Parent));
1900}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 if (D)
1903 WL.push_back(DeclVisit(D, Parent, isFirst));
1904}
1905void EnqueueVisitor::
1906 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1907 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001909}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 if (D)
1912 WL.push_back(MemberRefVisit(D, L, Parent));
1913}
1914void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1915 if (TI)
1916 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1917 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001921 AddStmt(*Child);
1922 }
1923 if (size == WL.size())
1924 return;
1925 // Now reverse the entries we just added. This will match the DFS
1926 // ordering performed by the worklist.
1927 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1928 std::reverse(I, E);
1929}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001930namespace {
1931class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1932 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001933 /// \brief Process clauses with list of variables.
1934 template <typename T>
1935 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001936public:
1937 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1938#define OPENMP_CLAUSE(Name, Class) \
1939 void Visit##Class(const Class *C);
1940#include "clang/Basic/OpenMPKinds.def"
1941};
1942
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001943void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1944 Visitor->AddStmt(C->getCondition());
1945}
1946
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001948
1949template<typename T>
1950void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1951 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1952 E = Node->varlist_end();
1953 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001955}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001956
1957void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001958 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001960void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1961 const OMPFirstprivateClause *C) {
1962 VisitOMPClauseList(C);
1963}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001964void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001965 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001966}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001967}
Alexey Bataev756c1962013-09-24 03:17:45 +00001968
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001969void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1970 unsigned size = WL.size();
1971 OMPClauseEnqueue Visitor(this);
1972 Visitor.Visit(S);
1973 if (size == WL.size())
1974 return;
1975 // Now reverse the entries we just added. This will match the DFS
1976 // ordering performed by the worklist.
1977 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1978 std::reverse(I, E);
1979}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001980void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001981 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1982}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 AddDecl(B->getBlockDecl());
1985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001987 EnqueueChildren(E);
1988 AddTypeLoc(E->getTypeSourceInfo());
1989}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1991 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 E = S->body_rend(); I != E; ++I) {
1993 AddStmt(*I);
1994 }
1995}
1996void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001997VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 AddStmt(S->getSubStmt());
1999 AddDeclarationNameInfo(S);
2000 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2001 AddNestedNameSpecifierLoc(QualifierLoc);
2002}
2003
2004void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2007 AddDeclarationNameInfo(E);
2008 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2009 AddNestedNameSpecifierLoc(QualifierLoc);
2010 if (!E->isImplicitAccess())
2011 AddStmt(E->getBase());
2012}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002013void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 // Enqueue the initializer , if any.
2015 AddStmt(E->getInitializer());
2016 // Enqueue the array size, if any.
2017 AddStmt(E->getArraySize());
2018 // Enqueue the allocated type.
2019 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2020 // Enqueue the placement arguments.
2021 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2022 AddStmt(E->getPlacementArg(I-1));
2023}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002024void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2026 AddStmt(CE->getArg(I-1));
2027 AddStmt(CE->getCallee());
2028 AddStmt(CE->getArg(0));
2029}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2031 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002032 // Visit the name of the type being destroyed.
2033 AddTypeLoc(E->getDestroyedTypeInfo());
2034 // Visit the scope type that looks disturbingly like the nested-name-specifier
2035 // but isn't.
2036 AddTypeLoc(E->getScopeTypeInfo());
2037 // Visit the nested-name-specifier.
2038 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2039 AddNestedNameSpecifierLoc(QualifierLoc);
2040 // Visit base expression.
2041 AddStmt(E->getBase());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2044 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 AddTypeLoc(E->getTypeSourceInfo());
2046}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2048 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 EnqueueChildren(E);
2050 AddTypeLoc(E->getTypeSourceInfo());
2051}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 EnqueueChildren(E);
2054 if (E->isTypeOperand())
2055 AddTypeLoc(E->getTypeOperandSourceInfo());
2056}
2057
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2059 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 EnqueueChildren(E);
2061 AddTypeLoc(E->getTypeSourceInfo());
2062}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 EnqueueChildren(E);
2065 if (E->isTypeOperand())
2066 AddTypeLoc(E->getTypeOperandSourceInfo());
2067}
2068
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(S);
2071 AddDecl(S->getExceptionDecl());
2072}
2073
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 if (DR->hasExplicitTemplateArgs()) {
2076 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2077 }
2078 WL.push_back(DeclRefExprParts(DR, Parent));
2079}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2081 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2083 AddDeclarationNameInfo(E);
2084 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 unsigned size = WL.size();
2088 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 D != DEnd; ++D) {
2091 AddDecl(*D, isFirst);
2092 isFirst = false;
2093 }
2094 if (size == WL.size())
2095 return;
2096 // Now reverse the entries we just added. This will match the DFS
2097 // ordering performed by the worklist.
2098 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2099 std::reverse(I, E);
2100}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002102 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 D = E->designators_rbegin(), DEnd = E->designators_rend();
2105 D != DEnd; ++D) {
2106 if (D->isFieldDesignator()) {
2107 if (FieldDecl *Field = D->getField())
2108 AddMemberRef(Field, D->getFieldLoc());
2109 continue;
2110 }
2111 if (D->isArrayDesignator()) {
2112 AddStmt(E->getArrayIndex(*D));
2113 continue;
2114 }
2115 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2116 AddStmt(E->getArrayRangeEnd(*D));
2117 AddStmt(E->getArrayRangeStart(*D));
2118 }
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 EnqueueChildren(E);
2122 AddTypeLoc(E->getTypeInfoAsWritten());
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 AddStmt(FS->getBody());
2126 AddStmt(FS->getInc());
2127 AddStmt(FS->getCond());
2128 AddDecl(FS->getConditionVariable());
2129 AddStmt(FS->getInit());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 AddStmt(If->getElse());
2136 AddStmt(If->getThen());
2137 AddStmt(If->getCond());
2138 AddDecl(If->getConditionVariable());
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002141 // We care about the syntactic form of the initializer list, only.
2142 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2143 IE = Syntactic;
2144 EnqueueChildren(IE);
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 WL.push_back(MemberExprParts(M, Parent));
2148
2149 // If the base of the member access expression is an implicit 'this', don't
2150 // visit it.
2151 // FIXME: If we ever want to show these implicit accesses, this will be
2152 // unfortunate. However, clang_getCursor() relies on this behavior.
2153 if (!M->isImplicitAccess())
2154 AddStmt(M->getBase());
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 AddTypeLoc(E->getEncodedTypeSourceInfo());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 EnqueueChildren(M);
2161 AddTypeLoc(M->getClassReceiverTypeInfo());
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 // Visit the components of the offsetof expression.
2165 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2166 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2167 const OffsetOfNode &Node = E->getComponent(I-1);
2168 switch (Node.getKind()) {
2169 case OffsetOfNode::Array:
2170 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2171 break;
2172 case OffsetOfNode::Field:
2173 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2174 break;
2175 case OffsetOfNode::Identifier:
2176 case OffsetOfNode::Base:
2177 continue;
2178 }
2179 }
2180 // Visit the type into which we're computing the offset.
2181 AddTypeLoc(E->getTypeSourceInfo());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2185 WL.push_back(OverloadExprParts(E, Parent));
2186}
2187void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(E);
2190 if (E->isArgumentType())
2191 AddTypeLoc(E->getArgumentTypeInfo());
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 EnqueueChildren(S);
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 AddStmt(S->getBody());
2198 AddStmt(S->getCond());
2199 AddDecl(S->getConditionVariable());
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 AddStmt(W->getBody());
2204 AddStmt(W->getCond());
2205 AddDecl(W->getConditionVariable());
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 for (unsigned I = E->getNumArgs(); I > 0; --I)
2210 AddTypeLoc(E->getArg(I-1));
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 AddTypeLoc(E->getQueriedTypeSourceInfo());
2215}
2216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 EnqueueChildren(E);
2219}
2220
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 VisitOverloadExpr(U);
2223 if (!U->isImplicitAccess())
2224 AddStmt(U->getBase());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 AddStmt(E->getSubExpr());
2228 AddTypeLoc(E->getWrittenTypeInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 WL.push_back(SizeOfPackExprParts(E, Parent));
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 // If the opaque value has a source expression, just transparently
2235 // visit that. This is useful for (e.g.) pseudo-object expressions.
2236 if (Expr *SourceExpr = E->getSourceExpr())
2237 return Visit(SourceExpr);
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 AddStmt(E->getBody());
2241 WL.push_back(LambdaExprParts(E, Parent));
2242}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 // Treat the expression like its syntactic form.
2245 Visit(E->getSyntacticForm());
2246}
2247
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002248void EnqueueVisitor::VisitOMPExecutableDirective(
2249 const OMPExecutableDirective *D) {
2250 EnqueueChildren(D);
2251 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2252 E = D->clauses().end();
2253 I != E; ++I)
2254 EnqueueChildren(*I);
2255}
2256
2257void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2258 VisitOMPExecutableDirective(D);
2259}
2260
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002261void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2262 VisitOMPExecutableDirective(D);
2263}
2264
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2267}
2268
2269bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2270 if (RegionOfInterest.isValid()) {
2271 SourceRange Range = getRawCursorExtent(C);
2272 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2273 return false;
2274 }
2275 return true;
2276}
2277
2278bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2279 while (!WL.empty()) {
2280 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002281 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002282
2283 // Set the Parent field, then back to its old value once we're done.
2284 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2285
2286 switch (LI.getKind()) {
2287 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 if (!D)
2290 continue;
2291
2292 // For now, perform default visitation for Decls.
2293 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2294 cast<DeclVisit>(&LI)->isFirst())))
2295 return true;
2296
2297 continue;
2298 }
2299 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2300 const ASTTemplateArgumentListInfo *ArgList =
2301 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2302 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2303 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2304 Arg != ArgEnd; ++Arg) {
2305 if (VisitTemplateArgumentLoc(*Arg))
2306 return true;
2307 }
2308 continue;
2309 }
2310 case VisitorJob::TypeLocVisitKind: {
2311 // Perform default visitation for TypeLocs.
2312 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2313 return true;
2314 continue;
2315 }
2316 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002318 if (LabelStmt *stmt = LS->getStmt()) {
2319 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2320 TU))) {
2321 return true;
2322 }
2323 }
2324 continue;
2325 }
2326
2327 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2328 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2329 if (VisitNestedNameSpecifierLoc(V->get()))
2330 return true;
2331 continue;
2332 }
2333
2334 case VisitorJob::DeclarationNameInfoVisitKind: {
2335 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2336 ->get()))
2337 return true;
2338 continue;
2339 }
2340 case VisitorJob::MemberRefVisitKind: {
2341 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2342 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2343 return true;
2344 continue;
2345 }
2346 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 if (!S)
2349 continue;
2350
2351 // Update the current cursor.
2352 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2353 if (!IsInRegionOfInterest(Cursor))
2354 continue;
2355 switch (Visitor(Cursor, Parent, ClientData)) {
2356 case CXChildVisit_Break: return true;
2357 case CXChildVisit_Continue: break;
2358 case CXChildVisit_Recurse:
2359 if (PostChildrenVisitor)
2360 WL.push_back(PostChildrenVisit(0, Cursor));
2361 EnqueueWorkList(WL, S);
2362 break;
2363 }
2364 continue;
2365 }
2366 case VisitorJob::MemberExprPartsKind: {
2367 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002369
2370 // Visit the nested-name-specifier
2371 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2372 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2373 return true;
2374
2375 // Visit the declaration name.
2376 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2377 return true;
2378
2379 // Visit the explicitly-specified template arguments, if any.
2380 if (M->hasExplicitTemplateArgs()) {
2381 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2382 *ArgEnd = Arg + M->getNumTemplateArgs();
2383 Arg != ArgEnd; ++Arg) {
2384 if (VisitTemplateArgumentLoc(*Arg))
2385 return true;
2386 }
2387 }
2388 continue;
2389 }
2390 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 // Visit nested-name-specifier, if present.
2393 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2394 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2395 return true;
2396 // Visit declaration name.
2397 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2398 return true;
2399 continue;
2400 }
2401 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002402 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002403 // Visit the nested-name-specifier.
2404 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2405 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2406 return true;
2407 // Visit the declaration name.
2408 if (VisitDeclarationNameInfo(O->getNameInfo()))
2409 return true;
2410 // Visit the overloaded declaration reference.
2411 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2412 return true;
2413 continue;
2414 }
2415 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 NamedDecl *Pack = E->getPack();
2418 if (isa<TemplateTypeParmDecl>(Pack)) {
2419 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2420 E->getPackLoc(), TU)))
2421 return true;
2422
2423 continue;
2424 }
2425
2426 if (isa<TemplateTemplateParmDecl>(Pack)) {
2427 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2428 E->getPackLoc(), TU)))
2429 return true;
2430
2431 continue;
2432 }
2433
2434 // Non-type template parameter packs and function parameter packs are
2435 // treated like DeclRefExpr cursors.
2436 continue;
2437 }
2438
2439 case VisitorJob::LambdaExprPartsKind: {
2440 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2443 CEnd = E->explicit_capture_end();
2444 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002445 // FIXME: Lambda init-captures.
2446 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002448
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2450 C->getLocation(),
2451 TU)))
2452 return true;
2453 }
2454
2455 // Visit parameters and return type, if present.
2456 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2457 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2458 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2459 // Visit the whole type.
2460 if (Visit(TL))
2461 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002462 } else if (FunctionProtoTypeLoc Proto =
2463 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 if (E->hasExplicitParameters()) {
2465 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002466 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2467 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 return true;
2469 } else {
2470 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002471 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 return true;
2473 }
2474 }
2475 }
2476 break;
2477 }
2478
2479 case VisitorJob::PostChildrenVisitKind:
2480 if (PostChildrenVisitor(Parent, ClientData))
2481 return true;
2482 break;
2483 }
2484 }
2485 return false;
2486}
2487
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002488bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002489 VisitorWorkList *WL = 0;
2490 if (!WorkListFreeList.empty()) {
2491 WL = WorkListFreeList.back();
2492 WL->clear();
2493 WorkListFreeList.pop_back();
2494 }
2495 else {
2496 WL = new VisitorWorkList();
2497 WorkListCache.push_back(WL);
2498 }
2499 EnqueueWorkList(*WL, S);
2500 bool result = RunVisitorWorkList(*WL);
2501 WorkListFreeList.push_back(WL);
2502 return result;
2503}
2504
2505namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002506typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002507RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2508 const DeclarationNameInfo &NI,
2509 const SourceRange &QLoc,
2510 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2511 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2512 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2513 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2514
2515 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2516
2517 RefNamePieces Pieces;
2518
2519 if (WantQualifier && QLoc.isValid())
2520 Pieces.push_back(QLoc);
2521
2522 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2523 Pieces.push_back(NI.getLoc());
2524
2525 if (WantTemplateArgs && TemplateArgs)
2526 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2527 TemplateArgs->RAngleLoc));
2528
2529 if (Kind == DeclarationName::CXXOperatorName) {
2530 Pieces.push_back(SourceLocation::getFromRawEncoding(
2531 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2532 Pieces.push_back(SourceLocation::getFromRawEncoding(
2533 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2534 }
2535
2536 if (WantSinglePiece) {
2537 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2538 Pieces.clear();
2539 Pieces.push_back(R);
2540 }
2541
2542 return Pieces;
2543}
2544}
2545
2546//===----------------------------------------------------------------------===//
2547// Misc. API hooks.
2548//===----------------------------------------------------------------------===//
2549
2550static llvm::sys::Mutex EnableMultithreadingMutex;
2551static bool EnabledMultithreading;
2552
Chad Rosier05c71aa2013-03-27 18:28:23 +00002553static void fatal_error_handler(void *user_data, const std::string& reason,
2554 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 // Write the result out to stderr avoiding errs() because raw_ostreams can
2556 // call report_fatal_error.
2557 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2558 ::abort();
2559}
2560
2561extern "C" {
2562CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2563 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002564 // We use crash recovery to make some of our APIs more reliable, implicitly
2565 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002566 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2567 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002568
2569 // Enable support for multithreading in LLVM.
2570 {
2571 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2572 if (!EnabledMultithreading) {
2573 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2574 llvm::llvm_start_multithreaded();
2575 EnabledMultithreading = true;
2576 }
2577 }
2578
2579 CIndexer *CIdxr = new CIndexer();
2580 if (excludeDeclarationsFromPCH)
2581 CIdxr->setOnlyLocalDecls();
2582 if (displayDiagnostics)
2583 CIdxr->setDisplayDiagnostics();
2584
2585 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2586 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2587 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2588 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2589 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2590 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2591
2592 return CIdxr;
2593}
2594
2595void clang_disposeIndex(CXIndex CIdx) {
2596 if (CIdx)
2597 delete static_cast<CIndexer *>(CIdx);
2598}
2599
2600void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2601 if (CIdx)
2602 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2603}
2604
2605unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2606 if (CIdx)
2607 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2608 return 0;
2609}
2610
2611void clang_toggleCrashRecovery(unsigned isEnabled) {
2612 if (isEnabled)
2613 llvm::CrashRecoveryContext::Enable();
2614 else
2615 llvm::CrashRecoveryContext::Disable();
2616}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002617
Guy Benyei11169dd2012-12-18 14:30:41 +00002618CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2619 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002620 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002621 enum CXErrorCode Result =
2622 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002623 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002624 assert((TU && Result == CXError_Success) ||
2625 (!TU && Result != CXError_Success));
2626 return TU;
2627}
2628
2629enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2630 const char *ast_filename,
2631 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002632 if (out_TU)
2633 *out_TU = NULL;
2634
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002635 if (!CIdx || !ast_filename || !out_TU)
2636 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002637
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002638 LOG_FUNC_SECTION {
2639 *Log << ast_filename;
2640 }
2641
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2643 FileSystemOptions FileSystemOpts;
2644
2645 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002646 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002647 CXXIdx->getOnlyLocalDecls(), None,
2648 /*CaptureDiagnostics=*/true,
2649 /*AllowPCHWithCompilerErrors=*/true,
2650 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2652 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002653}
2654
2655unsigned clang_defaultEditingTranslationUnitOptions() {
2656 return CXTranslationUnit_PrecompiledPreamble |
2657 CXTranslationUnit_CacheCompletionResults;
2658}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002659
Guy Benyei11169dd2012-12-18 14:30:41 +00002660CXTranslationUnit
2661clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2662 const char *source_filename,
2663 int num_command_line_args,
2664 const char * const *command_line_args,
2665 unsigned num_unsaved_files,
2666 struct CXUnsavedFile *unsaved_files) {
2667 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2668 return clang_parseTranslationUnit(CIdx, source_filename,
2669 command_line_args, num_command_line_args,
2670 unsaved_files, num_unsaved_files,
2671 Options);
2672}
2673
2674struct ParseTranslationUnitInfo {
2675 CXIndex CIdx;
2676 const char *source_filename;
2677 const char *const *command_line_args;
2678 int num_command_line_args;
2679 struct CXUnsavedFile *unsaved_files;
2680 unsigned num_unsaved_files;
2681 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002682 CXTranslationUnit *out_TU;
2683 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002684};
2685static void clang_parseTranslationUnit_Impl(void *UserData) {
2686 ParseTranslationUnitInfo *PTUI =
2687 static_cast<ParseTranslationUnitInfo*>(UserData);
2688 CXIndex CIdx = PTUI->CIdx;
2689 const char *source_filename = PTUI->source_filename;
2690 const char * const *command_line_args = PTUI->command_line_args;
2691 int num_command_line_args = PTUI->num_command_line_args;
2692 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2693 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2694 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002695 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002696
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002697 // Set up the initial return values.
2698 if (out_TU)
2699 *out_TU = NULL;
2700 PTUI->result = CXError_Failure;
2701
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002702 // Check arguments.
2703 if (!CIdx || !out_TU ||
2704 (unsaved_files == NULL && num_unsaved_files != 0)) {
2705 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002707 }
2708
Guy Benyei11169dd2012-12-18 14:30:41 +00002709 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2710
2711 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2712 setThreadBackgroundPriority();
2713
2714 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2715 // FIXME: Add a flag for modules.
2716 TranslationUnitKind TUKind
2717 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002718 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 = options & CXTranslationUnit_CacheCompletionResults;
2720 bool IncludeBriefCommentsInCodeCompletion
2721 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2722 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2723 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2724
2725 // Configure the diagnostics.
2726 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002727 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002728
2729 // Recover resources if we crash before exiting this function.
2730 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2731 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2732 DiagCleanup(Diags.getPtr());
2733
2734 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2735 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2736
2737 // Recover resources if we crash before exiting this function.
2738 llvm::CrashRecoveryContextCleanupRegistrar<
2739 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2740
2741 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2742 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2743 const llvm::MemoryBuffer *Buffer
2744 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2745 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2746 Buffer));
2747 }
2748
2749 OwningPtr<std::vector<const char *> >
2750 Args(new std::vector<const char*>());
2751
2752 // Recover resources if we crash before exiting this method.
2753 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2754 ArgsCleanup(Args.get());
2755
2756 // Since the Clang C library is primarily used by batch tools dealing with
2757 // (often very broken) source code, where spell-checking can have a
2758 // significant negative impact on performance (particularly when
2759 // precompiled headers are involved), we disable it by default.
2760 // Only do this if we haven't found a spell-checking-related argument.
2761 bool FoundSpellCheckingArgument = false;
2762 for (int I = 0; I != num_command_line_args; ++I) {
2763 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2764 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2765 FoundSpellCheckingArgument = true;
2766 break;
2767 }
2768 }
2769 if (!FoundSpellCheckingArgument)
2770 Args->push_back("-fno-spell-checking");
2771
2772 Args->insert(Args->end(), command_line_args,
2773 command_line_args + num_command_line_args);
2774
2775 // The 'source_filename' argument is optional. If the caller does not
2776 // specify it then it is assumed that the source file is specified
2777 // in the actual argument list.
2778 // Put the source file after command_line_args otherwise if '-x' flag is
2779 // present it will be unused.
2780 if (source_filename)
2781 Args->push_back(source_filename);
2782
2783 // Do we need the detailed preprocessing record?
2784 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2785 Args->push_back("-Xclang");
2786 Args->push_back("-detailed-preprocessing-record");
2787 }
2788
2789 unsigned NumErrors = Diags->getClient()->getNumErrors();
2790 OwningPtr<ASTUnit> ErrUnit;
2791 OwningPtr<ASTUnit> Unit(
2792 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2793 /* vector::data() not portable */,
2794 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2795 Diags,
2796 CXXIdx->getClangResourcesPath(),
2797 CXXIdx->getOnlyLocalDecls(),
2798 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002799 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002800 /*RemappedFilesKeepOriginalName=*/true,
2801 PrecompilePreamble,
2802 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002803 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002804 IncludeBriefCommentsInCodeCompletion,
2805 /*AllowPCHWithCompilerErrors=*/true,
2806 SkipFunctionBodies,
2807 /*UserFilesAreVolatile=*/true,
2808 ForSerialization,
2809 &ErrUnit));
2810
2811 if (NumErrors != Diags->getClient()->getNumErrors()) {
2812 // Make sure to check that 'Unit' is non-NULL.
2813 if (CXXIdx->getDisplayDiagnostics())
2814 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2815 }
2816
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002817 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2818 PTUI->result = CXError_ASTReadError;
2819 } else {
2820 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2821 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2822 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002823}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002824
2825CXTranslationUnit
2826clang_parseTranslationUnit(CXIndex CIdx,
2827 const char *source_filename,
2828 const char *const *command_line_args,
2829 int num_command_line_args,
2830 struct CXUnsavedFile *unsaved_files,
2831 unsigned num_unsaved_files,
2832 unsigned options) {
2833 CXTranslationUnit TU;
2834 enum CXErrorCode Result = clang_parseTranslationUnit2(
2835 CIdx, source_filename, command_line_args, num_command_line_args,
2836 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002837 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002838 assert((TU && Result == CXError_Success) ||
2839 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002840 return TU;
2841}
2842
2843enum CXErrorCode clang_parseTranslationUnit2(
2844 CXIndex CIdx,
2845 const char *source_filename,
2846 const char *const *command_line_args,
2847 int num_command_line_args,
2848 struct CXUnsavedFile *unsaved_files,
2849 unsigned num_unsaved_files,
2850 unsigned options,
2851 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002852 LOG_FUNC_SECTION {
2853 *Log << source_filename << ": ";
2854 for (int i = 0; i != num_command_line_args; ++i)
2855 *Log << command_line_args[i] << " ";
2856 }
2857
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2859 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002860 num_unsaved_files, options, out_TU,
2861 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002862 llvm::CrashRecoveryContext CRC;
2863
2864 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2865 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2866 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2867 fprintf(stderr, " 'command_line_args' : [");
2868 for (int i = 0; i != num_command_line_args; ++i) {
2869 if (i)
2870 fprintf(stderr, ", ");
2871 fprintf(stderr, "'%s'", command_line_args[i]);
2872 }
2873 fprintf(stderr, "],\n");
2874 fprintf(stderr, " 'unsaved_files' : [");
2875 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2876 if (i)
2877 fprintf(stderr, ", ");
2878 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2879 unsaved_files[i].Length);
2880 }
2881 fprintf(stderr, "],\n");
2882 fprintf(stderr, " 'options' : %d,\n", options);
2883 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002884
2885 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002886 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002887 if (CXTranslationUnit *TU = PTUI.out_TU)
2888 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 }
2890
2891 return PTUI.result;
2892}
2893
2894unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2895 return CXSaveTranslationUnit_None;
2896}
2897
2898namespace {
2899
2900struct SaveTranslationUnitInfo {
2901 CXTranslationUnit TU;
2902 const char *FileName;
2903 unsigned options;
2904 CXSaveError result;
2905};
2906
2907}
2908
2909static void clang_saveTranslationUnit_Impl(void *UserData) {
2910 SaveTranslationUnitInfo *STUI =
2911 static_cast<SaveTranslationUnitInfo*>(UserData);
2912
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002913 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002914 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2915 setThreadBackgroundPriority();
2916
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002917 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002918 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2919}
2920
2921int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2922 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002923 LOG_FUNC_SECTION {
2924 *Log << TU << ' ' << FileName;
2925 }
2926
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002927 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002928 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002930 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002931
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002932 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2934 if (!CXXUnit->hasSema())
2935 return CXSaveError_InvalidTU;
2936
2937 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2938
2939 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2940 getenv("LIBCLANG_NOTHREADS")) {
2941 clang_saveTranslationUnit_Impl(&STUI);
2942
2943 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2944 PrintLibclangResourceUsage(TU);
2945
2946 return STUI.result;
2947 }
2948
2949 // We have an AST that has invalid nodes due to compiler errors.
2950 // Use a crash recovery thread for protection.
2951
2952 llvm::CrashRecoveryContext CRC;
2953
2954 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2955 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2956 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2957 fprintf(stderr, " 'options' : %d,\n", options);
2958 fprintf(stderr, "}\n");
2959
2960 return CXSaveError_Unknown;
2961
2962 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2963 PrintLibclangResourceUsage(TU);
2964 }
2965
2966 return STUI.result;
2967}
2968
2969void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2970 if (CTUnit) {
2971 // If the translation unit has been marked as unsafe to free, just discard
2972 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002973 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2974 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 return;
2976
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002977 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002978 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002979 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2980 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002981 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 delete CTUnit;
2983 }
2984}
2985
2986unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2987 return CXReparse_None;
2988}
2989
2990struct ReparseTranslationUnitInfo {
2991 CXTranslationUnit TU;
2992 unsigned num_unsaved_files;
2993 struct CXUnsavedFile *unsaved_files;
2994 unsigned options;
2995 int result;
2996};
2997
2998static void clang_reparseTranslationUnit_Impl(void *UserData) {
2999 ReparseTranslationUnitInfo *RTUI =
3000 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003001 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003002
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003004 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3005 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3006 unsigned options = RTUI->options;
3007 (void) options;
3008
3009 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003010 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003011 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012 RTUI->result = CXError_InvalidArguments;
3013 return;
3014 }
3015 if (unsaved_files == NULL && num_unsaved_files != 0) {
3016 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003017 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003018 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003019
3020 // Reset the associated diagnostics.
3021 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3022 TU->Diagnostics = 0;
3023
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003024 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003025 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3026 setThreadBackgroundPriority();
3027
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003028 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3030
3031 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3032 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3033
3034 // Recover resources if we crash before exiting this function.
3035 llvm::CrashRecoveryContextCleanupRegistrar<
3036 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3037
3038 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3039 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3040 const llvm::MemoryBuffer *Buffer
3041 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3042 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3043 Buffer));
3044 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003046 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003047 RTUI->result = CXError_Success;
3048 else if (isASTReadError(CXXUnit))
3049 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003050}
3051
3052int clang_reparseTranslationUnit(CXTranslationUnit TU,
3053 unsigned num_unsaved_files,
3054 struct CXUnsavedFile *unsaved_files,
3055 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003056 LOG_FUNC_SECTION {
3057 *Log << TU;
3058 }
3059
Guy Benyei11169dd2012-12-18 14:30:41 +00003060 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003062
3063 if (getenv("LIBCLANG_NOTHREADS")) {
3064 clang_reparseTranslationUnit_Impl(&RTUI);
3065 return RTUI.result;
3066 }
3067
3068 llvm::CrashRecoveryContext CRC;
3069
3070 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3071 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003072 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003073 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3075 PrintLibclangResourceUsage(TU);
3076
3077 return RTUI.result;
3078}
3079
3080
3081CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003082 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003083 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003084 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003085 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003086
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003087 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003088 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003089}
3090
3091CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003092 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003093 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003094 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003095 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003096
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003097 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3099}
3100
3101} // end: extern "C"
3102
3103//===----------------------------------------------------------------------===//
3104// CXFile Operations.
3105//===----------------------------------------------------------------------===//
3106
3107extern "C" {
3108CXString clang_getFileName(CXFile SFile) {
3109 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003110 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
3112 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003113 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003114}
3115
3116time_t clang_getFileTime(CXFile SFile) {
3117 if (!SFile)
3118 return 0;
3119
3120 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3121 return FEnt->getModificationTime();
3122}
3123
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003124CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003125 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003126 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003128 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003131
3132 FileManager &FMgr = CXXUnit->getFileManager();
3133 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3134}
3135
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003136unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3137 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003138 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003139 LOG_BAD_TU(TU);
3140 return 0;
3141 }
3142
3143 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 return 0;
3145
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003146 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 FileEntry *FEnt = static_cast<FileEntry *>(file);
3148 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3149 .isFileMultipleIncludeGuarded(FEnt);
3150}
3151
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003152int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3153 if (!file || !outID)
3154 return 1;
3155
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003156 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003157 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3158 outID->data[0] = ID.getDevice();
3159 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003160 outID->data[2] = FEnt->getModificationTime();
3161 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003162}
3163
Guy Benyei11169dd2012-12-18 14:30:41 +00003164} // end: extern "C"
3165
3166//===----------------------------------------------------------------------===//
3167// CXCursor Operations.
3168//===----------------------------------------------------------------------===//
3169
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170static const Decl *getDeclFromExpr(const Stmt *E) {
3171 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 return getDeclFromExpr(CE->getSubExpr());
3173
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003180 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 if (PRE->isExplicitProperty())
3182 return PRE->getExplicitProperty();
3183 // It could be messaging both getter and setter as in:
3184 // ++myobj.myprop;
3185 // in which case prefer to associate the setter since it is less obvious
3186 // from inspecting the source that the setter is going to get called.
3187 if (PRE->isMessagingSetter())
3188 return PRE->getImplicitPropertySetter();
3189 return PRE->getImplicitPropertyGetter();
3190 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (Expr *Src = OVE->getSourceExpr())
3195 return getDeclFromExpr(Src);
3196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 if (!CE->isElidable())
3201 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 return OME->getMethodDecl();
3204
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003207 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3209 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003210 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3212 isa<ParmVarDecl>(SizeOfPack->getPack()))
3213 return SizeOfPack->getPack();
3214
3215 return 0;
3216}
3217
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218static SourceLocation getLocationFromExpr(const Expr *E) {
3219 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return getLocationFromExpr(CE->getSubExpr());
3221
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003226 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003228 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003230 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003232 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 return PropRef->getLocation();
3234
3235 return E->getLocStart();
3236}
3237
3238extern "C" {
3239
3240unsigned clang_visitChildren(CXCursor parent,
3241 CXCursorVisitor visitor,
3242 CXClientData client_data) {
3243 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3244 /*VisitPreprocessorLast=*/false);
3245 return CursorVis.VisitChildren(parent);
3246}
3247
3248#ifndef __has_feature
3249#define __has_feature(x) 0
3250#endif
3251#if __has_feature(blocks)
3252typedef enum CXChildVisitResult
3253 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3254
3255static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3256 CXClientData client_data) {
3257 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3258 return block(cursor, parent);
3259}
3260#else
3261// If we are compiled with a compiler that doesn't have native blocks support,
3262// define and call the block manually, so the
3263typedef struct _CXChildVisitResult
3264{
3265 void *isa;
3266 int flags;
3267 int reserved;
3268 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3269 CXCursor);
3270} *CXCursorVisitorBlock;
3271
3272static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3273 CXClientData client_data) {
3274 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3275 return block->invoke(block, cursor, parent);
3276}
3277#endif
3278
3279
3280unsigned clang_visitChildrenWithBlock(CXCursor parent,
3281 CXCursorVisitorBlock block) {
3282 return clang_visitChildren(parent, visitWithBlock, block);
3283}
3284
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003287 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003288
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003291 if (const ObjCPropertyImplDecl *PropImpl =
3292 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003294 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003298 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003299
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003300 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 }
3302
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003303 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003304 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003306 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3308 // and returns different names. NamedDecl returns the class name and
3309 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003310 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003311
3312 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003313 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003314
3315 SmallString<1024> S;
3316 llvm::raw_svector_ostream os(S);
3317 ND->printName(os);
3318
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003319 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003320}
3321
3322CXString clang_getCursorSpelling(CXCursor C) {
3323 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003324 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
3326 if (clang_isReference(C.kind)) {
3327 switch (C.kind) {
3328 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003329 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003330 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 }
3332 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003333 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003334 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 }
3336 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003337 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003339 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 }
3341 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003342 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 }
3345 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003346 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 assert(Type && "Missing type decl");
3348
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003349 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 getAsString());
3351 }
3352 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 assert(Template && "Missing template decl");
3355
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
3358
3359 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003360 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 assert(NS && "Missing namespace decl");
3362
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003363 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365
3366 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003367 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 assert(Field && "Missing member decl");
3369
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
3372
3373 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003374 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 assert(Label && "Missing label");
3376
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003377 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 case CXCursor_OverloadedDeclRef: {
3381 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003382 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3383 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003385 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003387 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003388 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 OverloadedTemplateStorage *Ovl
3390 = Storage.get<OverloadedTemplateStorage*>();
3391 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003392 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003393 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 }
3395
3396 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003397 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 assert(Var && "Missing variable decl");
3399
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003400 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 }
3402
3403 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003404 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 }
3406 }
3407
3408 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003409 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 if (D)
3411 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003412 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414
3415 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003416 const Stmt *S = getCursorStmt(C);
3417 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003418 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003424 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 ->getNameStart());
3426
3427 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 ->getNameStart());
3430
3431 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003432 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
3434 if (clang_isDeclaration(C.kind))
3435 return getDeclSpelling(getCursorDecl(C));
3436
3437 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003438 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003439 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 }
3441
3442 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003443 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003444 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 }
3446
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003447 if (C.kind == CXCursor_PackedAttr) {
3448 return cxstring::createRef("packed");
3449 }
3450
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003452}
3453
3454CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3455 unsigned pieceIndex,
3456 unsigned options) {
3457 if (clang_Cursor_isNull(C))
3458 return clang_getNullRange();
3459
3460 ASTContext &Ctx = getCursorContext(C);
3461
3462 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003463 const Stmt *S = getCursorStmt(C);
3464 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 if (pieceIndex > 0)
3466 return clang_getNullRange();
3467 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3468 }
3469
3470 return clang_getNullRange();
3471 }
3472
3473 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3476 if (pieceIndex >= ME->getNumSelectorLocs())
3477 return clang_getNullRange();
3478 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3479 }
3480 }
3481
3482 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3483 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3486 if (pieceIndex >= MD->getNumSelectorLocs())
3487 return clang_getNullRange();
3488 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3489 }
3490 }
3491
3492 if (C.kind == CXCursor_ObjCCategoryDecl ||
3493 C.kind == CXCursor_ObjCCategoryImplDecl) {
3494 if (pieceIndex > 0)
3495 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3498 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3501 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3502 }
3503
3504 if (C.kind == CXCursor_ModuleImportDecl) {
3505 if (pieceIndex > 0)
3506 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ImportDecl *ImportD =
3508 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3510 if (!Locs.empty())
3511 return cxloc::translateSourceRange(Ctx,
3512 SourceRange(Locs.front(), Locs.back()));
3513 }
3514 return clang_getNullRange();
3515 }
3516
3517 // FIXME: A CXCursor_InclusionDirective should give the location of the
3518 // filename, but we don't keep track of this.
3519
3520 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3521 // but we don't keep track of this.
3522
3523 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3524 // but we don't keep track of this.
3525
3526 // Default handling, give the location of the cursor.
3527
3528 if (pieceIndex > 0)
3529 return clang_getNullRange();
3530
3531 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3532 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3533 return cxloc::translateSourceRange(Ctx, Loc);
3534}
3535
3536CXString clang_getCursorDisplayName(CXCursor C) {
3537 if (!clang_isDeclaration(C.kind))
3538 return clang_getCursorSpelling(C);
3539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003540 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003542 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003543
3544 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 D = FunTmpl->getTemplatedDecl();
3547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 SmallString<64> Str;
3550 llvm::raw_svector_ostream OS(Str);
3551 OS << *Function;
3552 if (Function->getPrimaryTemplate())
3553 OS << "<>";
3554 OS << "(";
3555 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3556 if (I)
3557 OS << ", ";
3558 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3559 }
3560
3561 if (Function->isVariadic()) {
3562 if (Function->getNumParams())
3563 OS << ", ";
3564 OS << "...";
3565 }
3566 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 }
3569
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 SmallString<64> Str;
3572 llvm::raw_svector_ostream OS(Str);
3573 OS << *ClassTemplate;
3574 OS << "<";
3575 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3576 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3577 if (I)
3578 OS << ", ";
3579
3580 NamedDecl *Param = Params->getParam(I);
3581 if (Param->getIdentifier()) {
3582 OS << Param->getIdentifier()->getName();
3583 continue;
3584 }
3585
3586 // There is no parameter name, which makes this tricky. Try to come up
3587 // with something useful that isn't too long.
3588 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3589 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3590 else if (NonTypeTemplateParmDecl *NTTP
3591 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3592 OS << NTTP->getType().getAsString(Policy);
3593 else
3594 OS << "template<...> class";
3595 }
3596
3597 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3603 // If the type was explicitly written, use that.
3604 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
Benjamin Kramer9170e912013-02-22 15:46:01 +00003607 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 llvm::raw_svector_ostream OS(Str);
3609 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003610 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 ClassSpec->getTemplateArgs().data(),
3612 ClassSpec->getTemplateArgs().size(),
3613 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616
3617 return clang_getCursorSpelling(C);
3618}
3619
3620CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3621 switch (Kind) {
3622 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003750 case CXCursor_ObjCSelfExpr:
3751 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003868 case CXCursor_PackedAttr:
3869 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003918 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003919 return cxstring::createRef("OMPParallelDirective");
3920 case CXCursor_OMPSimdDirective:
3921 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 }
3923
3924 llvm_unreachable("Unhandled CXCursorKind");
3925}
3926
3927struct GetCursorData {
3928 SourceLocation TokenBeginLoc;
3929 bool PointsAtMacroArgExpansion;
3930 bool VisitedObjCPropertyImplDecl;
3931 SourceLocation VisitedDeclaratorDeclStartLoc;
3932 CXCursor &BestCursor;
3933
3934 GetCursorData(SourceManager &SM,
3935 SourceLocation tokenBegin, CXCursor &outputCursor)
3936 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3937 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3938 VisitedObjCPropertyImplDecl = false;
3939 }
3940};
3941
3942static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3943 CXCursor parent,
3944 CXClientData client_data) {
3945 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3946 CXCursor *BestCursor = &Data->BestCursor;
3947
3948 // If we point inside a macro argument we should provide info of what the
3949 // token is so use the actual cursor, don't replace it with a macro expansion
3950 // cursor.
3951 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3952 return CXChildVisit_Recurse;
3953
3954 if (clang_isDeclaration(cursor.kind)) {
3955 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003956 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3958 if (MD->isImplicit())
3959 return CXChildVisit_Break;
3960
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003961 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3963 // Check that when we have multiple @class references in the same line,
3964 // that later ones do not override the previous ones.
3965 // If we have:
3966 // @class Foo, Bar;
3967 // source ranges for both start at '@', so 'Bar' will end up overriding
3968 // 'Foo' even though the cursor location was at 'Foo'.
3969 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3970 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003971 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3973 if (PrevID != ID &&
3974 !PrevID->isThisDeclarationADefinition() &&
3975 !ID->isThisDeclarationADefinition())
3976 return CXChildVisit_Break;
3977 }
3978
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003979 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3981 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3982 // Check that when we have multiple declarators in the same line,
3983 // that later ones do not override the previous ones.
3984 // If we have:
3985 // int Foo, Bar;
3986 // source ranges for both start at 'int', so 'Bar' will end up overriding
3987 // 'Foo' even though the cursor location was at 'Foo'.
3988 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3989 return CXChildVisit_Break;
3990 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3991
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003992 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3994 (void)PropImp;
3995 // Check that when we have multiple @synthesize in the same line,
3996 // that later ones do not override the previous ones.
3997 // If we have:
3998 // @synthesize Foo, Bar;
3999 // source ranges for both start at '@', so 'Bar' will end up overriding
4000 // 'Foo' even though the cursor location was at 'Foo'.
4001 if (Data->VisitedObjCPropertyImplDecl)
4002 return CXChildVisit_Break;
4003 Data->VisitedObjCPropertyImplDecl = true;
4004 }
4005 }
4006
4007 if (clang_isExpression(cursor.kind) &&
4008 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004009 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 // Avoid having the cursor of an expression replace the declaration cursor
4011 // when the expression source range overlaps the declaration range.
4012 // This can happen for C++ constructor expressions whose range generally
4013 // include the variable declaration, e.g.:
4014 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4015 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4016 D->getLocation() == Data->TokenBeginLoc)
4017 return CXChildVisit_Break;
4018 }
4019 }
4020
4021 // If our current best cursor is the construction of a temporary object,
4022 // don't replace that cursor with a type reference, because we want
4023 // clang_getCursor() to point at the constructor.
4024 if (clang_isExpression(BestCursor->kind) &&
4025 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4026 cursor.kind == CXCursor_TypeRef) {
4027 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4028 // as having the actual point on the type reference.
4029 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4030 return CXChildVisit_Recurse;
4031 }
4032
4033 *BestCursor = cursor;
4034 return CXChildVisit_Recurse;
4035}
4036
4037CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004038 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004039 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004041 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004042
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004043 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4045
4046 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4047 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4048
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004049 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 CXFile SearchFile;
4051 unsigned SearchLine, SearchColumn;
4052 CXFile ResultFile;
4053 unsigned ResultLine, ResultColumn;
4054 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4055 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4056 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4057
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004058 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4059 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 &ResultColumn, 0);
4061 SearchFileName = clang_getFileName(SearchFile);
4062 ResultFileName = clang_getFileName(ResultFile);
4063 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4064 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004065 *Log << llvm::format("(%s:%d:%d) = %s",
4066 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4067 clang_getCString(KindSpelling))
4068 << llvm::format("(%s:%d:%d):%s%s",
4069 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4070 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 clang_disposeString(SearchFileName);
4072 clang_disposeString(ResultFileName);
4073 clang_disposeString(KindSpelling);
4074 clang_disposeString(USR);
4075
4076 CXCursor Definition = clang_getCursorDefinition(Result);
4077 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4078 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4079 CXString DefinitionKindSpelling
4080 = clang_getCursorKindSpelling(Definition.kind);
4081 CXFile DefinitionFile;
4082 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004083 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 &DefinitionLine, &DefinitionColumn, 0);
4085 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004086 *Log << llvm::format(" -> %s(%s:%d:%d)",
4087 clang_getCString(DefinitionKindSpelling),
4088 clang_getCString(DefinitionFileName),
4089 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 clang_disposeString(DefinitionFileName);
4091 clang_disposeString(DefinitionKindSpelling);
4092 }
4093 }
4094
4095 return Result;
4096}
4097
4098CXCursor clang_getNullCursor(void) {
4099 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4100}
4101
4102unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004103 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4104 // can't set consistently. For example, when visiting a DeclStmt we will set
4105 // it but we don't set it on the result of clang_getCursorDefinition for
4106 // a reference of the same declaration.
4107 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4108 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4109 // to provide that kind of info.
4110 if (clang_isDeclaration(X.kind))
4111 X.data[1] = 0;
4112 if (clang_isDeclaration(Y.kind))
4113 Y.data[1] = 0;
4114
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 return X == Y;
4116}
4117
4118unsigned clang_hashCursor(CXCursor C) {
4119 unsigned Index = 0;
4120 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4121 Index = 1;
4122
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 std::make_pair(C.kind, C.data[Index]));
4125}
4126
4127unsigned clang_isInvalid(enum CXCursorKind K) {
4128 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4129}
4130
4131unsigned clang_isDeclaration(enum CXCursorKind K) {
4132 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4133 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4134}
4135
4136unsigned clang_isReference(enum CXCursorKind K) {
4137 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4138}
4139
4140unsigned clang_isExpression(enum CXCursorKind K) {
4141 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4142}
4143
4144unsigned clang_isStatement(enum CXCursorKind K) {
4145 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4146}
4147
4148unsigned clang_isAttribute(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4150}
4151
4152unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4153 return K == CXCursor_TranslationUnit;
4154}
4155
4156unsigned clang_isPreprocessing(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4158}
4159
4160unsigned clang_isUnexposed(enum CXCursorKind K) {
4161 switch (K) {
4162 case CXCursor_UnexposedDecl:
4163 case CXCursor_UnexposedExpr:
4164 case CXCursor_UnexposedStmt:
4165 case CXCursor_UnexposedAttr:
4166 return true;
4167 default:
4168 return false;
4169 }
4170}
4171
4172CXCursorKind clang_getCursorKind(CXCursor C) {
4173 return C.kind;
4174}
4175
4176CXSourceLocation clang_getCursorLocation(CXCursor C) {
4177 if (clang_isReference(C.kind)) {
4178 switch (C.kind) {
4179 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004180 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 = getCursorObjCSuperClassRef(C);
4182 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4183 }
4184
4185 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004186 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 = getCursorObjCProtocolRef(C);
4188 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4189 }
4190
4191 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004192 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 = getCursorObjCClassRef(C);
4194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4200 }
4201
4202 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004203 std::pair<const TemplateDecl *, SourceLocation> P =
4204 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4211 }
4212
4213 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004214 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4216 }
4217
4218 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004219 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4221 }
4222
4223 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004224 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 if (!BaseSpec)
4226 return clang_getNullLocation();
4227
4228 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4229 return cxloc::translateSourceLocation(getCursorContext(C),
4230 TSInfo->getTypeLoc().getBeginLoc());
4231
4232 return cxloc::translateSourceLocation(getCursorContext(C),
4233 BaseSpec->getLocStart());
4234 }
4235
4236 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004237 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4239 }
4240
4241 case CXCursor_OverloadedDeclRef:
4242 return cxloc::translateSourceLocation(getCursorContext(C),
4243 getCursorOverloadedDeclRef(C).second);
4244
4245 default:
4246 // FIXME: Need a way to enumerate all non-reference cases.
4247 llvm_unreachable("Missed a reference kind");
4248 }
4249 }
4250
4251 if (clang_isExpression(C.kind))
4252 return cxloc::translateSourceLocation(getCursorContext(C),
4253 getLocationFromExpr(getCursorExpr(C)));
4254
4255 if (clang_isStatement(C.kind))
4256 return cxloc::translateSourceLocation(getCursorContext(C),
4257 getCursorStmt(C)->getLocStart());
4258
4259 if (C.kind == CXCursor_PreprocessingDirective) {
4260 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4261 return cxloc::translateSourceLocation(getCursorContext(C), L);
4262 }
4263
4264 if (C.kind == CXCursor_MacroExpansion) {
4265 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004266 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 return cxloc::translateSourceLocation(getCursorContext(C), L);
4268 }
4269
4270 if (C.kind == CXCursor_MacroDefinition) {
4271 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4272 return cxloc::translateSourceLocation(getCursorContext(C), L);
4273 }
4274
4275 if (C.kind == CXCursor_InclusionDirective) {
4276 SourceLocation L
4277 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4278 return cxloc::translateSourceLocation(getCursorContext(C), L);
4279 }
4280
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004281 if (clang_isAttribute(C.kind)) {
4282 SourceLocation L
4283 = cxcursor::getCursorAttr(C)->getLocation();
4284 return cxloc::translateSourceLocation(getCursorContext(C), L);
4285 }
4286
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 if (!clang_isDeclaration(C.kind))
4288 return clang_getNullLocation();
4289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004290 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 if (!D)
4292 return clang_getNullLocation();
4293
4294 SourceLocation Loc = D->getLocation();
4295 // FIXME: Multiple variables declared in a single declaration
4296 // currently lack the information needed to correctly determine their
4297 // ranges when accounting for the type-specifier. We use context
4298 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4299 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004300 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 if (!cxcursor::isFirstInDeclGroup(C))
4302 Loc = VD->getLocation();
4303 }
4304
4305 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004306 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 Loc = MD->getSelectorStartLoc();
4308
4309 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4310}
4311
4312} // end extern "C"
4313
4314CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4315 assert(TU);
4316
4317 // Guard against an invalid SourceLocation, or we may assert in one
4318 // of the following calls.
4319 if (SLoc.isInvalid())
4320 return clang_getNullCursor();
4321
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004322 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004323
4324 // Translate the given source location to make it point at the beginning of
4325 // the token under the cursor.
4326 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4327 CXXUnit->getASTContext().getLangOpts());
4328
4329 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4330 if (SLoc.isValid()) {
4331 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4332 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4333 /*VisitPreprocessorLast=*/true,
4334 /*VisitIncludedEntities=*/false,
4335 SourceLocation(SLoc));
4336 CursorVis.visitFileRegion();
4337 }
4338
4339 return Result;
4340}
4341
4342static SourceRange getRawCursorExtent(CXCursor C) {
4343 if (clang_isReference(C.kind)) {
4344 switch (C.kind) {
4345 case CXCursor_ObjCSuperClassRef:
4346 return getCursorObjCSuperClassRef(C).second;
4347
4348 case CXCursor_ObjCProtocolRef:
4349 return getCursorObjCProtocolRef(C).second;
4350
4351 case CXCursor_ObjCClassRef:
4352 return getCursorObjCClassRef(C).second;
4353
4354 case CXCursor_TypeRef:
4355 return getCursorTypeRef(C).second;
4356
4357 case CXCursor_TemplateRef:
4358 return getCursorTemplateRef(C).second;
4359
4360 case CXCursor_NamespaceRef:
4361 return getCursorNamespaceRef(C).second;
4362
4363 case CXCursor_MemberRef:
4364 return getCursorMemberRef(C).second;
4365
4366 case CXCursor_CXXBaseSpecifier:
4367 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4368
4369 case CXCursor_LabelRef:
4370 return getCursorLabelRef(C).second;
4371
4372 case CXCursor_OverloadedDeclRef:
4373 return getCursorOverloadedDeclRef(C).second;
4374
4375 case CXCursor_VariableRef:
4376 return getCursorVariableRef(C).second;
4377
4378 default:
4379 // FIXME: Need a way to enumerate all non-reference cases.
4380 llvm_unreachable("Missed a reference kind");
4381 }
4382 }
4383
4384 if (clang_isExpression(C.kind))
4385 return getCursorExpr(C)->getSourceRange();
4386
4387 if (clang_isStatement(C.kind))
4388 return getCursorStmt(C)->getSourceRange();
4389
4390 if (clang_isAttribute(C.kind))
4391 return getCursorAttr(C)->getRange();
4392
4393 if (C.kind == CXCursor_PreprocessingDirective)
4394 return cxcursor::getCursorPreprocessingDirective(C);
4395
4396 if (C.kind == CXCursor_MacroExpansion) {
4397 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004398 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 return TU->mapRangeFromPreamble(Range);
4400 }
4401
4402 if (C.kind == CXCursor_MacroDefinition) {
4403 ASTUnit *TU = getCursorASTUnit(C);
4404 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4405 return TU->mapRangeFromPreamble(Range);
4406 }
4407
4408 if (C.kind == CXCursor_InclusionDirective) {
4409 ASTUnit *TU = getCursorASTUnit(C);
4410 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4411 return TU->mapRangeFromPreamble(Range);
4412 }
4413
4414 if (C.kind == CXCursor_TranslationUnit) {
4415 ASTUnit *TU = getCursorASTUnit(C);
4416 FileID MainID = TU->getSourceManager().getMainFileID();
4417 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4418 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4419 return SourceRange(Start, End);
4420 }
4421
4422 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 if (!D)
4425 return SourceRange();
4426
4427 SourceRange R = D->getSourceRange();
4428 // FIXME: Multiple variables declared in a single declaration
4429 // currently lack the information needed to correctly determine their
4430 // ranges when accounting for the type-specifier. We use context
4431 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4432 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 if (!cxcursor::isFirstInDeclGroup(C))
4435 R.setBegin(VD->getLocation());
4436 }
4437 return R;
4438 }
4439 return SourceRange();
4440}
4441
4442/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4443/// the decl-specifier-seq for declarations.
4444static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4445 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004446 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 if (!D)
4448 return SourceRange();
4449
4450 SourceRange R = D->getSourceRange();
4451
4452 // Adjust the start of the location for declarations preceded by
4453 // declaration specifiers.
4454 SourceLocation StartLoc;
4455 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4456 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4457 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004458 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4460 StartLoc = TI->getTypeLoc().getLocStart();
4461 }
4462
4463 if (StartLoc.isValid() && R.getBegin().isValid() &&
4464 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4465 R.setBegin(StartLoc);
4466
4467 // FIXME: Multiple variables declared in a single declaration
4468 // currently lack the information needed to correctly determine their
4469 // ranges when accounting for the type-specifier. We use context
4470 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4471 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004472 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 if (!cxcursor::isFirstInDeclGroup(C))
4474 R.setBegin(VD->getLocation());
4475 }
4476
4477 return R;
4478 }
4479
4480 return getRawCursorExtent(C);
4481}
4482
4483extern "C" {
4484
4485CXSourceRange clang_getCursorExtent(CXCursor C) {
4486 SourceRange R = getRawCursorExtent(C);
4487 if (R.isInvalid())
4488 return clang_getNullRange();
4489
4490 return cxloc::translateSourceRange(getCursorContext(C), R);
4491}
4492
4493CXCursor clang_getCursorReferenced(CXCursor C) {
4494 if (clang_isInvalid(C.kind))
4495 return clang_getNullCursor();
4496
4497 CXTranslationUnit tu = getCursorTU(C);
4498 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004499 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 if (!D)
4501 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004502 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004504 if (const ObjCPropertyImplDecl *PropImpl =
4505 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4507 return MakeCXCursor(Property, tu);
4508
4509 return C;
4510 }
4511
4512 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 const Expr *E = getCursorExpr(C);
4514 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (D) {
4516 CXCursor declCursor = MakeCXCursor(D, tu);
4517 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4518 declCursor);
4519 return declCursor;
4520 }
4521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004522 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 return MakeCursorOverloadedDeclRef(Ovl, tu);
4524
4525 return clang_getNullCursor();
4526 }
4527
4528 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004529 const Stmt *S = getCursorStmt(C);
4530 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 if (LabelDecl *label = Goto->getLabel())
4532 if (LabelStmt *labelS = label->getStmt())
4533 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4534
4535 return clang_getNullCursor();
4536 }
4537
4538 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004539 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 return MakeMacroDefinitionCursor(Def, tu);
4541 }
4542
4543 if (!clang_isReference(C.kind))
4544 return clang_getNullCursor();
4545
4546 switch (C.kind) {
4547 case CXCursor_ObjCSuperClassRef:
4548 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4549
4550 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4552 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 return MakeCXCursor(Def, tu);
4554
4555 return MakeCXCursor(Prot, tu);
4556 }
4557
4558 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004559 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4560 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return MakeCXCursor(Def, tu);
4562
4563 return MakeCXCursor(Class, tu);
4564 }
4565
4566 case CXCursor_TypeRef:
4567 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4568
4569 case CXCursor_TemplateRef:
4570 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4571
4572 case CXCursor_NamespaceRef:
4573 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4574
4575 case CXCursor_MemberRef:
4576 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4577
4578 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004579 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4581 tu ));
4582 }
4583
4584 case CXCursor_LabelRef:
4585 // FIXME: We end up faking the "parent" declaration here because we
4586 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004587 return MakeCXCursor(getCursorLabelRef(C).first,
4588 cxtu::getASTUnit(tu)->getASTContext()
4589 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 tu);
4591
4592 case CXCursor_OverloadedDeclRef:
4593 return C;
4594
4595 case CXCursor_VariableRef:
4596 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4597
4598 default:
4599 // We would prefer to enumerate all non-reference cursor kinds here.
4600 llvm_unreachable("Unhandled reference cursor kind");
4601 }
4602}
4603
4604CXCursor clang_getCursorDefinition(CXCursor C) {
4605 if (clang_isInvalid(C.kind))
4606 return clang_getNullCursor();
4607
4608 CXTranslationUnit TU = getCursorTU(C);
4609
4610 bool WasReference = false;
4611 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4612 C = clang_getCursorReferenced(C);
4613 WasReference = true;
4614 }
4615
4616 if (C.kind == CXCursor_MacroExpansion)
4617 return clang_getCursorReferenced(C);
4618
4619 if (!clang_isDeclaration(C.kind))
4620 return clang_getNullCursor();
4621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004622 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 if (!D)
4624 return clang_getNullCursor();
4625
4626 switch (D->getKind()) {
4627 // Declaration kinds that don't really separate the notions of
4628 // declaration and definition.
4629 case Decl::Namespace:
4630 case Decl::Typedef:
4631 case Decl::TypeAlias:
4632 case Decl::TypeAliasTemplate:
4633 case Decl::TemplateTypeParm:
4634 case Decl::EnumConstant:
4635 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004636 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case Decl::IndirectField:
4638 case Decl::ObjCIvar:
4639 case Decl::ObjCAtDefsField:
4640 case Decl::ImplicitParam:
4641 case Decl::ParmVar:
4642 case Decl::NonTypeTemplateParm:
4643 case Decl::TemplateTemplateParm:
4644 case Decl::ObjCCategoryImpl:
4645 case Decl::ObjCImplementation:
4646 case Decl::AccessSpec:
4647 case Decl::LinkageSpec:
4648 case Decl::ObjCPropertyImpl:
4649 case Decl::FileScopeAsm:
4650 case Decl::StaticAssert:
4651 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004652 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case Decl::Label: // FIXME: Is this right??
4654 case Decl::ClassScopeFunctionSpecialization:
4655 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004656 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 return C;
4658
4659 // Declaration kinds that don't make any sense here, but are
4660 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004661 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 case Decl::TranslationUnit:
4663 break;
4664
4665 // Declaration kinds for which the definition is not resolvable.
4666 case Decl::UnresolvedUsingTypename:
4667 case Decl::UnresolvedUsingValue:
4668 break;
4669
4670 case Decl::UsingDirective:
4671 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4672 TU);
4673
4674 case Decl::NamespaceAlias:
4675 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4676
4677 case Decl::Enum:
4678 case Decl::Record:
4679 case Decl::CXXRecord:
4680 case Decl::ClassTemplateSpecialization:
4681 case Decl::ClassTemplatePartialSpecialization:
4682 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4683 return MakeCXCursor(Def, TU);
4684 return clang_getNullCursor();
4685
4686 case Decl::Function:
4687 case Decl::CXXMethod:
4688 case Decl::CXXConstructor:
4689 case Decl::CXXDestructor:
4690 case Decl::CXXConversion: {
4691 const FunctionDecl *Def = 0;
4692 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004693 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 return clang_getNullCursor();
4695 }
4696
Larisse Voufo39a1e502013-08-06 01:03:05 +00004697 case Decl::Var:
4698 case Decl::VarTemplateSpecialization:
4699 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004701 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 return MakeCXCursor(Def, TU);
4703 return clang_getNullCursor();
4704 }
4705
4706 case Decl::FunctionTemplate: {
4707 const FunctionDecl *Def = 0;
4708 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4709 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4710 return clang_getNullCursor();
4711 }
4712
4713 case Decl::ClassTemplate: {
4714 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4715 ->getDefinition())
4716 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4717 TU);
4718 return clang_getNullCursor();
4719 }
4720
Larisse Voufo39a1e502013-08-06 01:03:05 +00004721 case Decl::VarTemplate: {
4722 if (VarDecl *Def =
4723 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4724 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4725 return clang_getNullCursor();
4726 }
4727
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case Decl::Using:
4729 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4730 D->getLocation(), TU);
4731
4732 case Decl::UsingShadow:
4733 return clang_getCursorDefinition(
4734 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4735 TU));
4736
4737 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004738 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 if (Method->isThisDeclarationADefinition())
4740 return C;
4741
4742 // Dig out the method definition in the associated
4743 // @implementation, if we have it.
4744 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004745 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4747 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4748 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4749 Method->isInstanceMethod()))
4750 if (Def->isThisDeclarationADefinition())
4751 return MakeCXCursor(Def, TU);
4752
4753 return clang_getNullCursor();
4754 }
4755
4756 case Decl::ObjCCategory:
4757 if (ObjCCategoryImplDecl *Impl
4758 = cast<ObjCCategoryDecl>(D)->getImplementation())
4759 return MakeCXCursor(Impl, TU);
4760 return clang_getNullCursor();
4761
4762 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 return MakeCXCursor(Def, TU);
4765 return clang_getNullCursor();
4766
4767 case Decl::ObjCInterface: {
4768 // There are two notions of a "definition" for an Objective-C
4769 // class: the interface and its implementation. When we resolved a
4770 // reference to an Objective-C class, produce the @interface as
4771 // the definition; when we were provided with the interface,
4772 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004775 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 return MakeCXCursor(Def, TU);
4777 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4778 return MakeCXCursor(Impl, TU);
4779 return clang_getNullCursor();
4780 }
4781
4782 case Decl::ObjCProperty:
4783 // FIXME: We don't really know where to find the
4784 // ObjCPropertyImplDecls that implement this property.
4785 return clang_getNullCursor();
4786
4787 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004788 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 return MakeCXCursor(Def, TU);
4792
4793 return clang_getNullCursor();
4794
4795 case Decl::Friend:
4796 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4797 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4798 return clang_getNullCursor();
4799
4800 case Decl::FriendTemplate:
4801 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4802 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4803 return clang_getNullCursor();
4804 }
4805
4806 return clang_getNullCursor();
4807}
4808
4809unsigned clang_isCursorDefinition(CXCursor C) {
4810 if (!clang_isDeclaration(C.kind))
4811 return 0;
4812
4813 return clang_getCursorDefinition(C) == C;
4814}
4815
4816CXCursor clang_getCanonicalCursor(CXCursor C) {
4817 if (!clang_isDeclaration(C.kind))
4818 return C;
4819
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004820 if (const Decl *D = getCursorDecl(C)) {
4821 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4823 return MakeCXCursor(CatD, getCursorTU(C));
4824
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004825 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4826 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 return MakeCXCursor(IFD, getCursorTU(C));
4828
4829 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4830 }
4831
4832 return C;
4833}
4834
4835int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4836 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4837}
4838
4839unsigned clang_getNumOverloadedDecls(CXCursor C) {
4840 if (C.kind != CXCursor_OverloadedDeclRef)
4841 return 0;
4842
4843 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 return E->getNumDecls();
4846
4847 if (OverloadedTemplateStorage *S
4848 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4849 return S->size();
4850
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 const Decl *D = Storage.get<const Decl *>();
4852 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return Using->shadow_size();
4854
4855 return 0;
4856}
4857
4858CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4859 if (cursor.kind != CXCursor_OverloadedDeclRef)
4860 return clang_getNullCursor();
4861
4862 if (index >= clang_getNumOverloadedDecls(cursor))
4863 return clang_getNullCursor();
4864
4865 CXTranslationUnit TU = getCursorTU(cursor);
4866 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 return MakeCXCursor(E->decls_begin()[index], TU);
4869
4870 if (OverloadedTemplateStorage *S
4871 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4872 return MakeCXCursor(S->begin()[index], TU);
4873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 const Decl *D = Storage.get<const Decl *>();
4875 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 // FIXME: This is, unfortunately, linear time.
4877 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4878 std::advance(Pos, index);
4879 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4880 }
4881
4882 return clang_getNullCursor();
4883}
4884
4885void clang_getDefinitionSpellingAndExtent(CXCursor C,
4886 const char **startBuf,
4887 const char **endBuf,
4888 unsigned *startLine,
4889 unsigned *startColumn,
4890 unsigned *endLine,
4891 unsigned *endColumn) {
4892 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4895
4896 SourceManager &SM = FD->getASTContext().getSourceManager();
4897 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4898 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4899 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4900 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4901 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4902 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4903}
4904
4905
4906CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4907 unsigned PieceIndex) {
4908 RefNamePieces Pieces;
4909
4910 switch (C.kind) {
4911 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004912 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4914 E->getQualifierLoc().getSourceRange());
4915 break;
4916
4917 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004918 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4920 E->getQualifierLoc().getSourceRange(),
4921 E->getOptionalExplicitTemplateArgs());
4922 break;
4923
4924 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004925 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004927 const Expr *Callee = OCE->getCallee();
4928 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 Callee = ICE->getSubExpr();
4930
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004931 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4933 DRE->getQualifierLoc().getSourceRange());
4934 }
4935 break;
4936
4937 default:
4938 break;
4939 }
4940
4941 if (Pieces.empty()) {
4942 if (PieceIndex == 0)
4943 return clang_getCursorExtent(C);
4944 } else if (PieceIndex < Pieces.size()) {
4945 SourceRange R = Pieces[PieceIndex];
4946 if (R.isValid())
4947 return cxloc::translateSourceRange(getCursorContext(C), R);
4948 }
4949
4950 return clang_getNullRange();
4951}
4952
4953void clang_enableStackTraces(void) {
4954 llvm::sys::PrintStackTraceOnErrorSignal();
4955}
4956
4957void clang_executeOnThread(void (*fn)(void*), void *user_data,
4958 unsigned stack_size) {
4959 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4960}
4961
4962} // end: extern "C"
4963
4964//===----------------------------------------------------------------------===//
4965// Token-based Operations.
4966//===----------------------------------------------------------------------===//
4967
4968/* CXToken layout:
4969 * int_data[0]: a CXTokenKind
4970 * int_data[1]: starting token location
4971 * int_data[2]: token length
4972 * int_data[3]: reserved
4973 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4974 * otherwise unused.
4975 */
4976extern "C" {
4977
4978CXTokenKind clang_getTokenKind(CXToken CXTok) {
4979 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4980}
4981
4982CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4983 switch (clang_getTokenKind(CXTok)) {
4984 case CXToken_Identifier:
4985 case CXToken_Keyword:
4986 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004987 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 ->getNameStart());
4989
4990 case CXToken_Literal: {
4991 // We have stashed the starting pointer in the ptr_data field. Use it.
4992 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004993 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 }
4995
4996 case CXToken_Punctuation:
4997 case CXToken_Comment:
4998 break;
4999 }
5000
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005001 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005002 LOG_BAD_TU(TU);
5003 return cxstring::createEmpty();
5004 }
5005
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 // We have to find the starting buffer pointer the hard way, by
5007 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005009 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005010 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005011
5012 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5013 std::pair<FileID, unsigned> LocInfo
5014 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5015 bool Invalid = false;
5016 StringRef Buffer
5017 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5018 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005019 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005020
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005021 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005022}
5023
5024CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005025 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005026 LOG_BAD_TU(TU);
5027 return clang_getNullLocation();
5028 }
5029
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005030 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005031 if (!CXXUnit)
5032 return clang_getNullLocation();
5033
5034 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5035 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5036}
5037
5038CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005039 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005040 LOG_BAD_TU(TU);
5041 return clang_getNullRange();
5042 }
5043
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005044 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 if (!CXXUnit)
5046 return clang_getNullRange();
5047
5048 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5049 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5050}
5051
5052static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5053 SmallVectorImpl<CXToken> &CXTokens) {
5054 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5055 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005056 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005058 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005059
5060 // Cannot tokenize across files.
5061 if (BeginLocInfo.first != EndLocInfo.first)
5062 return;
5063
5064 // Create a lexer
5065 bool Invalid = false;
5066 StringRef Buffer
5067 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5068 if (Invalid)
5069 return;
5070
5071 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5072 CXXUnit->getASTContext().getLangOpts(),
5073 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5074 Lex.SetCommentRetentionState(true);
5075
5076 // Lex tokens until we hit the end of the range.
5077 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5078 Token Tok;
5079 bool previousWasAt = false;
5080 do {
5081 // Lex the next token
5082 Lex.LexFromRawLexer(Tok);
5083 if (Tok.is(tok::eof))
5084 break;
5085
5086 // Initialize the CXToken.
5087 CXToken CXTok;
5088
5089 // - Common fields
5090 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5091 CXTok.int_data[2] = Tok.getLength();
5092 CXTok.int_data[3] = 0;
5093
5094 // - Kind-specific fields
5095 if (Tok.isLiteral()) {
5096 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005097 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 } else if (Tok.is(tok::raw_identifier)) {
5099 // Lookup the identifier to determine whether we have a keyword.
5100 IdentifierInfo *II
5101 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5102
5103 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5104 CXTok.int_data[0] = CXToken_Keyword;
5105 }
5106 else {
5107 CXTok.int_data[0] = Tok.is(tok::identifier)
5108 ? CXToken_Identifier
5109 : CXToken_Keyword;
5110 }
5111 CXTok.ptr_data = II;
5112 } else if (Tok.is(tok::comment)) {
5113 CXTok.int_data[0] = CXToken_Comment;
5114 CXTok.ptr_data = 0;
5115 } else {
5116 CXTok.int_data[0] = CXToken_Punctuation;
5117 CXTok.ptr_data = 0;
5118 }
5119 CXTokens.push_back(CXTok);
5120 previousWasAt = Tok.is(tok::at);
5121 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5122}
5123
5124void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5125 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005126 LOG_FUNC_SECTION {
5127 *Log << TU << ' ' << Range;
5128 }
5129
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 if (Tokens)
5131 *Tokens = 0;
5132 if (NumTokens)
5133 *NumTokens = 0;
5134
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005135 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005136 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005137 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005138 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005140 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 if (!CXXUnit || !Tokens || !NumTokens)
5142 return;
5143
5144 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5145
5146 SourceRange R = cxloc::translateCXSourceRange(Range);
5147 if (R.isInvalid())
5148 return;
5149
5150 SmallVector<CXToken, 32> CXTokens;
5151 getTokens(CXXUnit, R, CXTokens);
5152
5153 if (CXTokens.empty())
5154 return;
5155
5156 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5157 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5158 *NumTokens = CXTokens.size();
5159}
5160
5161void clang_disposeTokens(CXTranslationUnit TU,
5162 CXToken *Tokens, unsigned NumTokens) {
5163 free(Tokens);
5164}
5165
5166} // end: extern "C"
5167
5168//===----------------------------------------------------------------------===//
5169// Token annotation APIs.
5170//===----------------------------------------------------------------------===//
5171
Guy Benyei11169dd2012-12-18 14:30:41 +00005172static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5173 CXCursor parent,
5174 CXClientData client_data);
5175static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5176 CXClientData client_data);
5177
5178namespace {
5179class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 CXToken *Tokens;
5181 CXCursor *Cursors;
5182 unsigned NumTokens;
5183 unsigned TokIdx;
5184 unsigned PreprocessingTokIdx;
5185 CursorVisitor AnnotateVis;
5186 SourceManager &SrcMgr;
5187 bool HasContextSensitiveKeywords;
5188
5189 struct PostChildrenInfo {
5190 CXCursor Cursor;
5191 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005192 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 unsigned BeforeChildrenTokenIdx;
5194 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005195 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005196
5197 CXToken &getTok(unsigned Idx) {
5198 assert(Idx < NumTokens);
5199 return Tokens[Idx];
5200 }
5201 const CXToken &getTok(unsigned Idx) const {
5202 assert(Idx < NumTokens);
5203 return Tokens[Idx];
5204 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 bool MoreTokens() const { return TokIdx < NumTokens; }
5206 unsigned NextToken() const { return TokIdx; }
5207 void AdvanceToken() { ++TokIdx; }
5208 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005209 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 }
5211 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005212 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 }
5214 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005215 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 }
5217
5218 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005219 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 SourceRange);
5221
5222public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005223 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005224 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005225 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005227 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 AnnotateTokensVisitor, this,
5229 /*VisitPreprocessorLast=*/true,
5230 /*VisitIncludedEntities=*/false,
5231 RegionOfInterest,
5232 /*VisitDeclsOnly=*/false,
5233 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005234 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 HasContextSensitiveKeywords(false) { }
5236
5237 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5238 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5239 bool postVisitChildren(CXCursor cursor);
5240 void AnnotateTokens();
5241
5242 /// \brief Determine whether the annotator saw any cursors that have
5243 /// context-sensitive keywords.
5244 bool hasContextSensitiveKeywords() const {
5245 return HasContextSensitiveKeywords;
5246 }
5247
5248 ~AnnotateTokensWorker() {
5249 assert(PostChildrenInfos.empty());
5250 }
5251};
5252}
5253
5254void AnnotateTokensWorker::AnnotateTokens() {
5255 // Walk the AST within the region of interest, annotating tokens
5256 // along the way.
5257 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005258}
Guy Benyei11169dd2012-12-18 14:30:41 +00005259
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005260static inline void updateCursorAnnotation(CXCursor &Cursor,
5261 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005262 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005264 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005265}
5266
5267/// \brief It annotates and advances tokens with a cursor until the comparison
5268//// between the cursor location and the source range is the same as
5269/// \arg compResult.
5270///
5271/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5272/// Pass RangeOverlap to annotate tokens inside a range.
5273void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5274 RangeComparisonResult compResult,
5275 SourceRange range) {
5276 while (MoreTokens()) {
5277 const unsigned I = NextToken();
5278 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005279 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5280 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005281
5282 SourceLocation TokLoc = GetTokenLoc(I);
5283 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005284 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 AdvanceToken();
5286 continue;
5287 }
5288 break;
5289 }
5290}
5291
5292/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005293/// \returns true if it advanced beyond all macro tokens, false otherwise.
5294bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 CXCursor updateC,
5296 RangeComparisonResult compResult,
5297 SourceRange range) {
5298 assert(MoreTokens());
5299 assert(isFunctionMacroToken(NextToken()) &&
5300 "Should be called only for macro arg tokens");
5301
5302 // This works differently than annotateAndAdvanceTokens; because expanded
5303 // macro arguments can have arbitrary translation-unit source order, we do not
5304 // advance the token index one by one until a token fails the range test.
5305 // We only advance once past all of the macro arg tokens if all of them
5306 // pass the range test. If one of them fails we keep the token index pointing
5307 // at the start of the macro arg tokens so that the failing token will be
5308 // annotated by a subsequent annotation try.
5309
5310 bool atLeastOneCompFail = false;
5311
5312 unsigned I = NextToken();
5313 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5314 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5315 if (TokLoc.isFileID())
5316 continue; // not macro arg token, it's parens or comma.
5317 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5318 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5319 Cursors[I] = updateC;
5320 } else
5321 atLeastOneCompFail = true;
5322 }
5323
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005324 if (atLeastOneCompFail)
5325 return false;
5326
5327 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5328 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005329}
5330
5331enum CXChildVisitResult
5332AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 SourceRange cursorRange = getRawCursorExtent(cursor);
5334 if (cursorRange.isInvalid())
5335 return CXChildVisit_Recurse;
5336
5337 if (!HasContextSensitiveKeywords) {
5338 // Objective-C properties can have context-sensitive keywords.
5339 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5342 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5343 }
5344 // Objective-C methods can have context-sensitive keywords.
5345 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5346 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005347 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5349 if (Method->getObjCDeclQualifier())
5350 HasContextSensitiveKeywords = true;
5351 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005352 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5353 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 P != PEnd; ++P) {
5355 if ((*P)->getObjCDeclQualifier()) {
5356 HasContextSensitiveKeywords = true;
5357 break;
5358 }
5359 }
5360 }
5361 }
5362 }
5363 // C++ methods can have context-sensitive keywords.
5364 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005365 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5367 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5368 HasContextSensitiveKeywords = true;
5369 }
5370 }
5371 // C++ classes can have context-sensitive keywords.
5372 else if (cursor.kind == CXCursor_StructDecl ||
5373 cursor.kind == CXCursor_ClassDecl ||
5374 cursor.kind == CXCursor_ClassTemplate ||
5375 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005376 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 if (D->hasAttr<FinalAttr>())
5378 HasContextSensitiveKeywords = true;
5379 }
5380 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005381
5382 // Don't override a property annotation with its getter/setter method.
5383 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5384 parent.kind == CXCursor_ObjCPropertyDecl)
5385 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005386
5387 if (clang_isPreprocessing(cursor.kind)) {
5388 // Items in the preprocessing record are kept separate from items in
5389 // declarations, so we keep a separate token index.
5390 unsigned SavedTokIdx = TokIdx;
5391 TokIdx = PreprocessingTokIdx;
5392
5393 // Skip tokens up until we catch up to the beginning of the preprocessing
5394 // entry.
5395 while (MoreTokens()) {
5396 const unsigned I = NextToken();
5397 SourceLocation TokLoc = GetTokenLoc(I);
5398 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5399 case RangeBefore:
5400 AdvanceToken();
5401 continue;
5402 case RangeAfter:
5403 case RangeOverlap:
5404 break;
5405 }
5406 break;
5407 }
5408
5409 // Look at all of the tokens within this range.
5410 while (MoreTokens()) {
5411 const unsigned I = NextToken();
5412 SourceLocation TokLoc = GetTokenLoc(I);
5413 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5414 case RangeBefore:
5415 llvm_unreachable("Infeasible");
5416 case RangeAfter:
5417 break;
5418 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005419 // For macro expansions, just note where the beginning of the macro
5420 // expansion occurs.
5421 if (cursor.kind == CXCursor_MacroExpansion) {
5422 if (TokLoc == cursorRange.getBegin())
5423 Cursors[I] = cursor;
5424 AdvanceToken();
5425 break;
5426 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005427 // We may have already annotated macro names inside macro definitions.
5428 if (Cursors[I].kind != CXCursor_MacroExpansion)
5429 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 continue;
5432 }
5433 break;
5434 }
5435
5436 // Save the preprocessing token index; restore the non-preprocessing
5437 // token index.
5438 PreprocessingTokIdx = TokIdx;
5439 TokIdx = SavedTokIdx;
5440 return CXChildVisit_Recurse;
5441 }
5442
5443 if (cursorRange.isInvalid())
5444 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005445
5446 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 const enum CXCursorKind K = clang_getCursorKind(parent);
5449 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005450 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5451 // Attributes are annotated out-of-order, skip tokens until we reach it.
5452 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 ? clang_getNullCursor() : parent;
5454
5455 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5456
5457 // Avoid having the cursor of an expression "overwrite" the annotation of the
5458 // variable declaration that it belongs to.
5459 // This can happen for C++ constructor expressions whose range generally
5460 // include the variable declaration, e.g.:
5461 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005462 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005463 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005464 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 const unsigned I = NextToken();
5466 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5467 E->getLocStart() == D->getLocation() &&
5468 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005469 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 AdvanceToken();
5471 }
5472 }
5473 }
5474
5475 // Before recursing into the children keep some state that we are going
5476 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5477 // extra work after the child nodes are visited.
5478 // Note that we don't call VisitChildren here to avoid traversing statements
5479 // code-recursively which can blow the stack.
5480
5481 PostChildrenInfo Info;
5482 Info.Cursor = cursor;
5483 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005484 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 Info.BeforeChildrenTokenIdx = NextToken();
5486 PostChildrenInfos.push_back(Info);
5487
5488 return CXChildVisit_Recurse;
5489}
5490
5491bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5492 if (PostChildrenInfos.empty())
5493 return false;
5494 const PostChildrenInfo &Info = PostChildrenInfos.back();
5495 if (!clang_equalCursors(Info.Cursor, cursor))
5496 return false;
5497
5498 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5499 const unsigned AfterChildren = NextToken();
5500 SourceRange cursorRange = Info.CursorRange;
5501
5502 // Scan the tokens that are at the end of the cursor, but are not captured
5503 // but the child cursors.
5504 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5505
5506 // Scan the tokens that are at the beginning of the cursor, but are not
5507 // capture by the child cursors.
5508 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5509 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5510 break;
5511
5512 Cursors[I] = cursor;
5513 }
5514
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005515 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5516 // encountered the attribute cursor.
5517 if (clang_isAttribute(cursor.kind))
5518 TokIdx = Info.BeforeReachingCursorIdx;
5519
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 PostChildrenInfos.pop_back();
5521 return false;
5522}
5523
5524static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5525 CXCursor parent,
5526 CXClientData client_data) {
5527 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5528}
5529
5530static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5531 CXClientData client_data) {
5532 return static_cast<AnnotateTokensWorker*>(client_data)->
5533 postVisitChildren(cursor);
5534}
5535
5536namespace {
5537
5538/// \brief Uses the macro expansions in the preprocessing record to find
5539/// and mark tokens that are macro arguments. This info is used by the
5540/// AnnotateTokensWorker.
5541class MarkMacroArgTokensVisitor {
5542 SourceManager &SM;
5543 CXToken *Tokens;
5544 unsigned NumTokens;
5545 unsigned CurIdx;
5546
5547public:
5548 MarkMacroArgTokensVisitor(SourceManager &SM,
5549 CXToken *tokens, unsigned numTokens)
5550 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5551
5552 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5553 if (cursor.kind != CXCursor_MacroExpansion)
5554 return CXChildVisit_Continue;
5555
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005556 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005557 if (macroRange.getBegin() == macroRange.getEnd())
5558 return CXChildVisit_Continue; // it's not a function macro.
5559
5560 for (; CurIdx < NumTokens; ++CurIdx) {
5561 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5562 macroRange.getBegin()))
5563 break;
5564 }
5565
5566 if (CurIdx == NumTokens)
5567 return CXChildVisit_Break;
5568
5569 for (; CurIdx < NumTokens; ++CurIdx) {
5570 SourceLocation tokLoc = getTokenLoc(CurIdx);
5571 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5572 break;
5573
5574 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5575 }
5576
5577 if (CurIdx == NumTokens)
5578 return CXChildVisit_Break;
5579
5580 return CXChildVisit_Continue;
5581 }
5582
5583private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005584 CXToken &getTok(unsigned Idx) {
5585 assert(Idx < NumTokens);
5586 return Tokens[Idx];
5587 }
5588 const CXToken &getTok(unsigned Idx) const {
5589 assert(Idx < NumTokens);
5590 return Tokens[Idx];
5591 }
5592
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005594 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 }
5596
5597 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5598 // The third field is reserved and currently not used. Use it here
5599 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005600 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 }
5602};
5603
5604} // end anonymous namespace
5605
5606static CXChildVisitResult
5607MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5608 CXClientData client_data) {
5609 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5610 parent);
5611}
5612
5613namespace {
5614 struct clang_annotateTokens_Data {
5615 CXTranslationUnit TU;
5616 ASTUnit *CXXUnit;
5617 CXToken *Tokens;
5618 unsigned NumTokens;
5619 CXCursor *Cursors;
5620 };
5621}
5622
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005623/// \brief Used by \c annotatePreprocessorTokens.
5624/// \returns true if lexing was finished, false otherwise.
5625static bool lexNext(Lexer &Lex, Token &Tok,
5626 unsigned &NextIdx, unsigned NumTokens) {
5627 if (NextIdx >= NumTokens)
5628 return true;
5629
5630 ++NextIdx;
5631 Lex.LexFromRawLexer(Tok);
5632 if (Tok.is(tok::eof))
5633 return true;
5634
5635 return false;
5636}
5637
Guy Benyei11169dd2012-12-18 14:30:41 +00005638static void annotatePreprocessorTokens(CXTranslationUnit TU,
5639 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005640 CXCursor *Cursors,
5641 CXToken *Tokens,
5642 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005643 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005644
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005645 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5647 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005648 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005650 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005651
5652 if (BeginLocInfo.first != EndLocInfo.first)
5653 return;
5654
5655 StringRef Buffer;
5656 bool Invalid = false;
5657 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5658 if (Buffer.empty() || Invalid)
5659 return;
5660
5661 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5662 CXXUnit->getASTContext().getLangOpts(),
5663 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5664 Buffer.end());
5665 Lex.SetCommentRetentionState(true);
5666
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005667 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 // Lex tokens in raw mode until we hit the end of the range, to avoid
5669 // entering #includes or expanding macros.
5670 while (true) {
5671 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005672 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5673 break;
5674 unsigned TokIdx = NextIdx-1;
5675 assert(Tok.getLocation() ==
5676 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005677
5678 reprocess:
5679 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680 // We have found a preprocessing directive. Annotate the tokens
5681 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 //
5683 // FIXME: Some simple tests here could identify macro definitions and
5684 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005685
5686 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005687 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5688 break;
5689
5690 MacroInfo *MI = 0;
5691 if (Tok.is(tok::raw_identifier) &&
5692 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5693 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5694 break;
5695
5696 if (Tok.is(tok::raw_identifier)) {
5697 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5698 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5699 SourceLocation MappedTokLoc =
5700 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5701 MI = getMacroInfo(II, MappedTokLoc, TU);
5702 }
5703 }
5704
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005705 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5708 finished = true;
5709 break;
5710 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005711 // If we are in a macro definition, check if the token was ever a
5712 // macro name and annotate it if that's the case.
5713 if (MI) {
5714 SourceLocation SaveLoc = Tok.getLocation();
5715 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5716 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5717 Tok.setLocation(SaveLoc);
5718 if (MacroDef)
5719 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5720 Tok.getLocation(), TU);
5721 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005722 } while (!Tok.isAtStartOfLine());
5723
5724 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5725 assert(TokIdx <= LastIdx);
5726 SourceLocation EndLoc =
5727 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5728 CXCursor Cursor =
5729 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5730
5731 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005732 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005733
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005734 if (finished)
5735 break;
5736 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 }
5739}
5740
5741// This gets run a separate thread to avoid stack blowout.
5742static void clang_annotateTokensImpl(void *UserData) {
5743 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5744 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5745 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5746 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5747 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5748
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005749 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5751 setThreadBackgroundPriority();
5752
5753 // Determine the region of interest, which contains all of the tokens.
5754 SourceRange RegionOfInterest;
5755 RegionOfInterest.setBegin(
5756 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5757 RegionOfInterest.setEnd(
5758 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5759 Tokens[NumTokens-1])));
5760
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 // Relex the tokens within the source range to look for preprocessing
5762 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005763 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005764
5765 // If begin location points inside a macro argument, set it to the expansion
5766 // location so we can have the full context when annotating semantically.
5767 {
5768 SourceManager &SM = CXXUnit->getSourceManager();
5769 SourceLocation Loc =
5770 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5771 if (Loc.isMacroID())
5772 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5773 }
5774
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5776 // Search and mark tokens that are macro argument expansions.
5777 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5778 Tokens, NumTokens);
5779 CursorVisitor MacroArgMarker(TU,
5780 MarkMacroArgTokensVisitorDelegate, &Visitor,
5781 /*VisitPreprocessorLast=*/true,
5782 /*VisitIncludedEntities=*/false,
5783 RegionOfInterest);
5784 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5785 }
5786
5787 // Annotate all of the source locations in the region of interest that map to
5788 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005789 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005790
5791 // FIXME: We use a ridiculous stack size here because the data-recursion
5792 // algorithm uses a large stack frame than the non-data recursive version,
5793 // and AnnotationTokensWorker currently transforms the data-recursion
5794 // algorithm back into a traditional recursion by explicitly calling
5795 // VisitChildren(). We will need to remove this explicit recursive call.
5796 W.AnnotateTokens();
5797
5798 // If we ran into any entities that involve context-sensitive keywords,
5799 // take another pass through the tokens to mark them as such.
5800 if (W.hasContextSensitiveKeywords()) {
5801 for (unsigned I = 0; I != NumTokens; ++I) {
5802 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5803 continue;
5804
5805 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5806 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005807 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5809 if (Property->getPropertyAttributesAsWritten() != 0 &&
5810 llvm::StringSwitch<bool>(II->getName())
5811 .Case("readonly", true)
5812 .Case("assign", true)
5813 .Case("unsafe_unretained", true)
5814 .Case("readwrite", true)
5815 .Case("retain", true)
5816 .Case("copy", true)
5817 .Case("nonatomic", true)
5818 .Case("atomic", true)
5819 .Case("getter", true)
5820 .Case("setter", true)
5821 .Case("strong", true)
5822 .Case("weak", true)
5823 .Default(false))
5824 Tokens[I].int_data[0] = CXToken_Keyword;
5825 }
5826 continue;
5827 }
5828
5829 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5830 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5831 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5832 if (llvm::StringSwitch<bool>(II->getName())
5833 .Case("in", true)
5834 .Case("out", true)
5835 .Case("inout", true)
5836 .Case("oneway", true)
5837 .Case("bycopy", true)
5838 .Case("byref", true)
5839 .Default(false))
5840 Tokens[I].int_data[0] = CXToken_Keyword;
5841 continue;
5842 }
5843
5844 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5845 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5846 Tokens[I].int_data[0] = CXToken_Keyword;
5847 continue;
5848 }
5849 }
5850 }
5851}
5852
5853extern "C" {
5854
5855void clang_annotateTokens(CXTranslationUnit TU,
5856 CXToken *Tokens, unsigned NumTokens,
5857 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005858 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005859 LOG_BAD_TU(TU);
5860 return;
5861 }
5862 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005863 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005864 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005865 }
5866
5867 LOG_FUNC_SECTION {
5868 *Log << TU << ' ';
5869 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5870 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5871 *Log << clang_getRange(bloc, eloc);
5872 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005873
5874 // Any token we don't specifically annotate will have a NULL cursor.
5875 CXCursor C = clang_getNullCursor();
5876 for (unsigned I = 0; I != NumTokens; ++I)
5877 Cursors[I] = C;
5878
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005879 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 if (!CXXUnit)
5881 return;
5882
5883 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5884
5885 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5886 llvm::CrashRecoveryContext CRC;
5887 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5888 GetSafetyThreadStackSize() * 2)) {
5889 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5890 }
5891}
5892
5893} // end: extern "C"
5894
5895//===----------------------------------------------------------------------===//
5896// Operations for querying linkage of a cursor.
5897//===----------------------------------------------------------------------===//
5898
5899extern "C" {
5900CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5901 if (!clang_isDeclaration(cursor.kind))
5902 return CXLinkage_Invalid;
5903
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005904 const Decl *D = cxcursor::getCursorDecl(cursor);
5905 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005906 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005907 case NoLinkage:
5908 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005909 case InternalLinkage: return CXLinkage_Internal;
5910 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5911 case ExternalLinkage: return CXLinkage_External;
5912 };
5913
5914 return CXLinkage_Invalid;
5915}
5916} // end: extern "C"
5917
5918//===----------------------------------------------------------------------===//
5919// Operations for querying language of a cursor.
5920//===----------------------------------------------------------------------===//
5921
5922static CXLanguageKind getDeclLanguage(const Decl *D) {
5923 if (!D)
5924 return CXLanguage_C;
5925
5926 switch (D->getKind()) {
5927 default:
5928 break;
5929 case Decl::ImplicitParam:
5930 case Decl::ObjCAtDefsField:
5931 case Decl::ObjCCategory:
5932 case Decl::ObjCCategoryImpl:
5933 case Decl::ObjCCompatibleAlias:
5934 case Decl::ObjCImplementation:
5935 case Decl::ObjCInterface:
5936 case Decl::ObjCIvar:
5937 case Decl::ObjCMethod:
5938 case Decl::ObjCProperty:
5939 case Decl::ObjCPropertyImpl:
5940 case Decl::ObjCProtocol:
5941 return CXLanguage_ObjC;
5942 case Decl::CXXConstructor:
5943 case Decl::CXXConversion:
5944 case Decl::CXXDestructor:
5945 case Decl::CXXMethod:
5946 case Decl::CXXRecord:
5947 case Decl::ClassTemplate:
5948 case Decl::ClassTemplatePartialSpecialization:
5949 case Decl::ClassTemplateSpecialization:
5950 case Decl::Friend:
5951 case Decl::FriendTemplate:
5952 case Decl::FunctionTemplate:
5953 case Decl::LinkageSpec:
5954 case Decl::Namespace:
5955 case Decl::NamespaceAlias:
5956 case Decl::NonTypeTemplateParm:
5957 case Decl::StaticAssert:
5958 case Decl::TemplateTemplateParm:
5959 case Decl::TemplateTypeParm:
5960 case Decl::UnresolvedUsingTypename:
5961 case Decl::UnresolvedUsingValue:
5962 case Decl::Using:
5963 case Decl::UsingDirective:
5964 case Decl::UsingShadow:
5965 return CXLanguage_CPlusPlus;
5966 }
5967
5968 return CXLanguage_C;
5969}
5970
5971extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005972
5973static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5974 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5975 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005976
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005977 switch (D->getAvailability()) {
5978 case AR_Available:
5979 case AR_NotYetIntroduced:
5980 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005981 return getCursorAvailabilityForDecl(
5982 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005983 return CXAvailability_Available;
5984
5985 case AR_Deprecated:
5986 return CXAvailability_Deprecated;
5987
5988 case AR_Unavailable:
5989 return CXAvailability_NotAvailable;
5990 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005991
5992 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005993}
5994
Guy Benyei11169dd2012-12-18 14:30:41 +00005995enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5996 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005997 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5998 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005999
6000 return CXAvailability_Available;
6001}
6002
6003static CXVersion convertVersion(VersionTuple In) {
6004 CXVersion Out = { -1, -1, -1 };
6005 if (In.empty())
6006 return Out;
6007
6008 Out.Major = In.getMajor();
6009
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006010 Optional<unsigned> Minor = In.getMinor();
6011 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 Out.Minor = *Minor;
6013 else
6014 return Out;
6015
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006016 Optional<unsigned> Subminor = In.getSubminor();
6017 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 Out.Subminor = *Subminor;
6019
6020 return Out;
6021}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006022
6023static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6024 int *always_deprecated,
6025 CXString *deprecated_message,
6026 int *always_unavailable,
6027 CXString *unavailable_message,
6028 CXPlatformAvailability *availability,
6029 int availability_size) {
6030 bool HadAvailAttr = false;
6031 int N = 0;
6032 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6033 ++A) {
6034 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6035 HadAvailAttr = true;
6036 if (always_deprecated)
6037 *always_deprecated = 1;
6038 if (deprecated_message)
6039 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6040 continue;
6041 }
6042
6043 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6044 HadAvailAttr = true;
6045 if (always_unavailable)
6046 *always_unavailable = 1;
6047 if (unavailable_message) {
6048 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6049 }
6050 continue;
6051 }
6052
6053 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6054 HadAvailAttr = true;
6055 if (N < availability_size) {
6056 availability[N].Platform
6057 = cxstring::createDup(Avail->getPlatform()->getName());
6058 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6059 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6060 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6061 availability[N].Unavailable = Avail->getUnavailable();
6062 availability[N].Message = cxstring::createDup(Avail->getMessage());
6063 }
6064 ++N;
6065 }
6066 }
6067
6068 if (!HadAvailAttr)
6069 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6070 return getCursorPlatformAvailabilityForDecl(
6071 cast<Decl>(EnumConst->getDeclContext()),
6072 always_deprecated,
6073 deprecated_message,
6074 always_unavailable,
6075 unavailable_message,
6076 availability,
6077 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006078
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006079 return N;
6080}
6081
Guy Benyei11169dd2012-12-18 14:30:41 +00006082int clang_getCursorPlatformAvailability(CXCursor cursor,
6083 int *always_deprecated,
6084 CXString *deprecated_message,
6085 int *always_unavailable,
6086 CXString *unavailable_message,
6087 CXPlatformAvailability *availability,
6088 int availability_size) {
6089 if (always_deprecated)
6090 *always_deprecated = 0;
6091 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006092 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 if (always_unavailable)
6094 *always_unavailable = 0;
6095 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006096 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097
Guy Benyei11169dd2012-12-18 14:30:41 +00006098 if (!clang_isDeclaration(cursor.kind))
6099 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006101 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006102 if (!D)
6103 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104
6105 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6106 deprecated_message,
6107 always_unavailable,
6108 unavailable_message,
6109 availability,
6110 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006111}
6112
6113void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6114 clang_disposeString(availability->Platform);
6115 clang_disposeString(availability->Message);
6116}
6117
6118CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6119 if (clang_isDeclaration(cursor.kind))
6120 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6121
6122 return CXLanguage_Invalid;
6123}
6124
6125 /// \brief If the given cursor is the "templated" declaration
6126 /// descibing a class or function template, return the class or
6127 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006128static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 if (!D)
6130 return 0;
6131
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006132 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006133 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6134 return FunTmpl;
6135
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006136 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6138 return ClassTmpl;
6139
6140 return D;
6141}
6142
6143CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6144 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006145 if (const Decl *D = getCursorDecl(cursor)) {
6146 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 if (!DC)
6148 return clang_getNullCursor();
6149
6150 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6151 getCursorTU(cursor));
6152 }
6153 }
6154
6155 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006156 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 return MakeCXCursor(D, getCursorTU(cursor));
6158 }
6159
6160 return clang_getNullCursor();
6161}
6162
6163CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6164 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006165 if (const Decl *D = getCursorDecl(cursor)) {
6166 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 if (!DC)
6168 return clang_getNullCursor();
6169
6170 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6171 getCursorTU(cursor));
6172 }
6173 }
6174
6175 // FIXME: Note that we can't easily compute the lexical context of a
6176 // statement or expression, so we return nothing.
6177 return clang_getNullCursor();
6178}
6179
6180CXFile clang_getIncludedFile(CXCursor cursor) {
6181 if (cursor.kind != CXCursor_InclusionDirective)
6182 return 0;
6183
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006184 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006185 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006186}
6187
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006188unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6189 if (C.kind != CXCursor_ObjCPropertyDecl)
6190 return CXObjCPropertyAttr_noattr;
6191
6192 unsigned Result = CXObjCPropertyAttr_noattr;
6193 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6194 ObjCPropertyDecl::PropertyAttributeKind Attr =
6195 PD->getPropertyAttributesAsWritten();
6196
6197#define SET_CXOBJCPROP_ATTR(A) \
6198 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6199 Result |= CXObjCPropertyAttr_##A
6200 SET_CXOBJCPROP_ATTR(readonly);
6201 SET_CXOBJCPROP_ATTR(getter);
6202 SET_CXOBJCPROP_ATTR(assign);
6203 SET_CXOBJCPROP_ATTR(readwrite);
6204 SET_CXOBJCPROP_ATTR(retain);
6205 SET_CXOBJCPROP_ATTR(copy);
6206 SET_CXOBJCPROP_ATTR(nonatomic);
6207 SET_CXOBJCPROP_ATTR(setter);
6208 SET_CXOBJCPROP_ATTR(atomic);
6209 SET_CXOBJCPROP_ATTR(weak);
6210 SET_CXOBJCPROP_ATTR(strong);
6211 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6212#undef SET_CXOBJCPROP_ATTR
6213
6214 return Result;
6215}
6216
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006217unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6218 if (!clang_isDeclaration(C.kind))
6219 return CXObjCDeclQualifier_None;
6220
6221 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6222 const Decl *D = getCursorDecl(C);
6223 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6224 QT = MD->getObjCDeclQualifier();
6225 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6226 QT = PD->getObjCDeclQualifier();
6227 if (QT == Decl::OBJC_TQ_None)
6228 return CXObjCDeclQualifier_None;
6229
6230 unsigned Result = CXObjCDeclQualifier_None;
6231 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6232 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6233 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6234 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6235 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6236 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6237
6238 return Result;
6239}
6240
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006241unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6242 if (!clang_isDeclaration(C.kind))
6243 return 0;
6244
6245 const Decl *D = getCursorDecl(C);
6246 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6247 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6248 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6249 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6250
6251 return 0;
6252}
6253
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006254unsigned clang_Cursor_isVariadic(CXCursor C) {
6255 if (!clang_isDeclaration(C.kind))
6256 return 0;
6257
6258 const Decl *D = getCursorDecl(C);
6259 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6260 return FD->isVariadic();
6261 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6262 return MD->isVariadic();
6263
6264 return 0;
6265}
6266
Guy Benyei11169dd2012-12-18 14:30:41 +00006267CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6268 if (!clang_isDeclaration(C.kind))
6269 return clang_getNullRange();
6270
6271 const Decl *D = getCursorDecl(C);
6272 ASTContext &Context = getCursorContext(C);
6273 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6274 if (!RC)
6275 return clang_getNullRange();
6276
6277 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6278}
6279
6280CXString clang_Cursor_getRawCommentText(CXCursor C) {
6281 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006282 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006283
6284 const Decl *D = getCursorDecl(C);
6285 ASTContext &Context = getCursorContext(C);
6286 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6287 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6288 StringRef();
6289
6290 // Don't duplicate the string because RawText points directly into source
6291 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006292 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006293}
6294
6295CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6296 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006297 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006298
6299 const Decl *D = getCursorDecl(C);
6300 const ASTContext &Context = getCursorContext(C);
6301 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6302
6303 if (RC) {
6304 StringRef BriefText = RC->getBriefText(Context);
6305
6306 // Don't duplicate the string because RawComment ensures that this memory
6307 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006308 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 }
6310
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006311 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006312}
6313
6314CXComment clang_Cursor_getParsedComment(CXCursor C) {
6315 if (!clang_isDeclaration(C.kind))
6316 return cxcomment::createCXComment(NULL, NULL);
6317
6318 const Decl *D = getCursorDecl(C);
6319 const ASTContext &Context = getCursorContext(C);
6320 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6321
6322 return cxcomment::createCXComment(FC, getCursorTU(C));
6323}
6324
6325CXModule clang_Cursor_getModule(CXCursor C) {
6326 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006327 if (const ImportDecl *ImportD =
6328 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006329 return ImportD->getImportedModule();
6330 }
6331
6332 return 0;
6333}
6334
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006335CXFile clang_Module_getASTFile(CXModule CXMod) {
6336 if (!CXMod)
6337 return 0;
6338 Module *Mod = static_cast<Module*>(CXMod);
6339 return const_cast<FileEntry *>(Mod->getASTFile());
6340}
6341
Guy Benyei11169dd2012-12-18 14:30:41 +00006342CXModule clang_Module_getParent(CXModule CXMod) {
6343 if (!CXMod)
6344 return 0;
6345 Module *Mod = static_cast<Module*>(CXMod);
6346 return Mod->Parent;
6347}
6348
6349CXString clang_Module_getName(CXModule CXMod) {
6350 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006351 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006352 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006353 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006354}
6355
6356CXString clang_Module_getFullName(CXModule CXMod) {
6357 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006358 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006360 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006361}
6362
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006363unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6364 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006365 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006366 LOG_BAD_TU(TU);
6367 return 0;
6368 }
6369 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006370 return 0;
6371 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006372 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6373 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6374 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375}
6376
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006377CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6378 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006379 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006380 LOG_BAD_TU(TU);
6381 return 0;
6382 }
6383 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 return 0;
6385 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006386 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006387
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006388 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6389 if (Index < TopHeaders.size())
6390 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006391
6392 return 0;
6393}
6394
6395} // end: extern "C"
6396
6397//===----------------------------------------------------------------------===//
6398// C++ AST instrospection.
6399//===----------------------------------------------------------------------===//
6400
6401extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006402unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6403 if (!clang_isDeclaration(C.kind))
6404 return 0;
6405
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006406 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006407 const CXXMethodDecl *Method =
6408 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006409 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6410}
6411
Guy Benyei11169dd2012-12-18 14:30:41 +00006412unsigned clang_CXXMethod_isStatic(CXCursor C) {
6413 if (!clang_isDeclaration(C.kind))
6414 return 0;
6415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006416 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006417 const CXXMethodDecl *Method =
6418 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 return (Method && Method->isStatic()) ? 1 : 0;
6420}
6421
6422unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6423 if (!clang_isDeclaration(C.kind))
6424 return 0;
6425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006426 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006427 const CXXMethodDecl *Method =
6428 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 return (Method && Method->isVirtual()) ? 1 : 0;
6430}
6431} // end: extern "C"
6432
6433//===----------------------------------------------------------------------===//
6434// Attribute introspection.
6435//===----------------------------------------------------------------------===//
6436
6437extern "C" {
6438CXType clang_getIBOutletCollectionType(CXCursor C) {
6439 if (C.kind != CXCursor_IBOutletCollectionAttr)
6440 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6441
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006442 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006443 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6444
6445 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6446}
6447} // end: extern "C"
6448
6449//===----------------------------------------------------------------------===//
6450// Inspecting memory usage.
6451//===----------------------------------------------------------------------===//
6452
6453typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6454
6455static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6456 enum CXTUResourceUsageKind k,
6457 unsigned long amount) {
6458 CXTUResourceUsageEntry entry = { k, amount };
6459 entries.push_back(entry);
6460}
6461
6462extern "C" {
6463
6464const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6465 const char *str = "";
6466 switch (kind) {
6467 case CXTUResourceUsage_AST:
6468 str = "ASTContext: expressions, declarations, and types";
6469 break;
6470 case CXTUResourceUsage_Identifiers:
6471 str = "ASTContext: identifiers";
6472 break;
6473 case CXTUResourceUsage_Selectors:
6474 str = "ASTContext: selectors";
6475 break;
6476 case CXTUResourceUsage_GlobalCompletionResults:
6477 str = "Code completion: cached global results";
6478 break;
6479 case CXTUResourceUsage_SourceManagerContentCache:
6480 str = "SourceManager: content cache allocator";
6481 break;
6482 case CXTUResourceUsage_AST_SideTables:
6483 str = "ASTContext: side tables";
6484 break;
6485 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6486 str = "SourceManager: malloc'ed memory buffers";
6487 break;
6488 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6489 str = "SourceManager: mmap'ed memory buffers";
6490 break;
6491 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6492 str = "ExternalASTSource: malloc'ed memory buffers";
6493 break;
6494 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6495 str = "ExternalASTSource: mmap'ed memory buffers";
6496 break;
6497 case CXTUResourceUsage_Preprocessor:
6498 str = "Preprocessor: malloc'ed memory";
6499 break;
6500 case CXTUResourceUsage_PreprocessingRecord:
6501 str = "Preprocessor: PreprocessingRecord";
6502 break;
6503 case CXTUResourceUsage_SourceManager_DataStructures:
6504 str = "SourceManager: data structures and tables";
6505 break;
6506 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6507 str = "Preprocessor: header search tables";
6508 break;
6509 }
6510 return str;
6511}
6512
6513CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006514 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006515 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006516 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6517 return usage;
6518 }
6519
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006520 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006521 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6522 ASTContext &astContext = astUnit->getASTContext();
6523
6524 // How much memory is used by AST nodes and types?
6525 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6526 (unsigned long) astContext.getASTAllocatedMemory());
6527
6528 // How much memory is used by identifiers?
6529 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6530 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6531
6532 // How much memory is used for selectors?
6533 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6534 (unsigned long) astContext.Selectors.getTotalMemory());
6535
6536 // How much memory is used by ASTContext's side tables?
6537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6538 (unsigned long) astContext.getSideTableAllocatedMemory());
6539
6540 // How much memory is used for caching global code completion results?
6541 unsigned long completionBytes = 0;
6542 if (GlobalCodeCompletionAllocator *completionAllocator =
6543 astUnit->getCachedCompletionAllocator().getPtr()) {
6544 completionBytes = completionAllocator->getTotalMemory();
6545 }
6546 createCXTUResourceUsageEntry(*entries,
6547 CXTUResourceUsage_GlobalCompletionResults,
6548 completionBytes);
6549
6550 // How much memory is being used by SourceManager's content cache?
6551 createCXTUResourceUsageEntry(*entries,
6552 CXTUResourceUsage_SourceManagerContentCache,
6553 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6554
6555 // How much memory is being used by the MemoryBuffer's in SourceManager?
6556 const SourceManager::MemoryBufferSizes &srcBufs =
6557 astUnit->getSourceManager().getMemoryBufferSizes();
6558
6559 createCXTUResourceUsageEntry(*entries,
6560 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6561 (unsigned long) srcBufs.malloc_bytes);
6562 createCXTUResourceUsageEntry(*entries,
6563 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6564 (unsigned long) srcBufs.mmap_bytes);
6565 createCXTUResourceUsageEntry(*entries,
6566 CXTUResourceUsage_SourceManager_DataStructures,
6567 (unsigned long) astContext.getSourceManager()
6568 .getDataStructureSizes());
6569
6570 // How much memory is being used by the ExternalASTSource?
6571 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6572 const ExternalASTSource::MemoryBufferSizes &sizes =
6573 esrc->getMemoryBufferSizes();
6574
6575 createCXTUResourceUsageEntry(*entries,
6576 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6577 (unsigned long) sizes.malloc_bytes);
6578 createCXTUResourceUsageEntry(*entries,
6579 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6580 (unsigned long) sizes.mmap_bytes);
6581 }
6582
6583 // How much memory is being used by the Preprocessor?
6584 Preprocessor &pp = astUnit->getPreprocessor();
6585 createCXTUResourceUsageEntry(*entries,
6586 CXTUResourceUsage_Preprocessor,
6587 pp.getTotalMemory());
6588
6589 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6590 createCXTUResourceUsageEntry(*entries,
6591 CXTUResourceUsage_PreprocessingRecord,
6592 pRec->getTotalMemory());
6593 }
6594
6595 createCXTUResourceUsageEntry(*entries,
6596 CXTUResourceUsage_Preprocessor_HeaderSearch,
6597 pp.getHeaderSearchInfo().getTotalMemory());
6598
6599 CXTUResourceUsage usage = { (void*) entries.get(),
6600 (unsigned) entries->size(),
6601 entries->size() ? &(*entries)[0] : 0 };
6602 entries.take();
6603 return usage;
6604}
6605
6606void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6607 if (usage.data)
6608 delete (MemUsageEntries*) usage.data;
6609}
6610
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006611CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6612 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006613 skipped->count = 0;
6614 skipped->ranges = 0;
6615
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006616 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006617 LOG_BAD_TU(TU);
6618 return skipped;
6619 }
6620
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006621 if (!file)
6622 return skipped;
6623
6624 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6625 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6626 if (!ppRec)
6627 return skipped;
6628
6629 ASTContext &Ctx = astUnit->getASTContext();
6630 SourceManager &sm = Ctx.getSourceManager();
6631 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6632 FileID wantedFileID = sm.translateFile(fileEntry);
6633
6634 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6635 std::vector<SourceRange> wantedRanges;
6636 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6637 i != ei; ++i) {
6638 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6639 wantedRanges.push_back(*i);
6640 }
6641
6642 skipped->count = wantedRanges.size();
6643 skipped->ranges = new CXSourceRange[skipped->count];
6644 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6645 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6646
6647 return skipped;
6648}
6649
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006650void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6651 if (ranges) {
6652 delete[] ranges->ranges;
6653 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006654 }
6655}
6656
Guy Benyei11169dd2012-12-18 14:30:41 +00006657} // end extern "C"
6658
6659void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6660 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6661 for (unsigned I = 0; I != Usage.numEntries; ++I)
6662 fprintf(stderr, " %s: %lu\n",
6663 clang_getTUResourceUsageName(Usage.entries[I].kind),
6664 Usage.entries[I].amount);
6665
6666 clang_disposeCXTUResourceUsage(Usage);
6667}
6668
6669//===----------------------------------------------------------------------===//
6670// Misc. utility functions.
6671//===----------------------------------------------------------------------===//
6672
6673/// Default to using an 8 MB stack size on "safety" threads.
6674static unsigned SafetyStackThreadSize = 8 << 20;
6675
6676namespace clang {
6677
6678bool RunSafely(llvm::CrashRecoveryContext &CRC,
6679 void (*Fn)(void*), void *UserData,
6680 unsigned Size) {
6681 if (!Size)
6682 Size = GetSafetyThreadStackSize();
6683 if (Size)
6684 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6685 return CRC.RunSafely(Fn, UserData);
6686}
6687
6688unsigned GetSafetyThreadStackSize() {
6689 return SafetyStackThreadSize;
6690}
6691
6692void SetSafetyThreadStackSize(unsigned Value) {
6693 SafetyStackThreadSize = Value;
6694}
6695
6696}
6697
6698void clang::setThreadBackgroundPriority() {
6699 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6700 return;
6701
6702 // FIXME: Move to llvm/Support and make it cross-platform.
6703#ifdef __APPLE__
6704 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6705#endif
6706}
6707
6708void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6709 if (!Unit)
6710 return;
6711
6712 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6713 DEnd = Unit->stored_diag_end();
6714 D != DEnd; ++D) {
6715 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6716 CXString Msg = clang_formatDiagnostic(&Diag,
6717 clang_defaultDiagnosticDisplayOptions());
6718 fprintf(stderr, "%s\n", clang_getCString(Msg));
6719 clang_disposeString(Msg);
6720 }
6721#ifdef LLVM_ON_WIN32
6722 // On Windows, force a flush, since there may be multiple copies of
6723 // stderr and stdout in the file system, all with different buffers
6724 // but writing to the same device.
6725 fflush(stderr);
6726#endif
6727}
6728
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006729MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6730 SourceLocation MacroDefLoc,
6731 CXTranslationUnit TU){
6732 if (MacroDefLoc.isInvalid() || !TU)
6733 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006734 if (!II.hadMacroDefinition())
6735 return 0;
6736
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006737 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006738 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006739 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006740 if (MD) {
6741 for (MacroDirective::DefInfo
6742 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6743 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6744 return Def.getMacroInfo();
6745 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006746 }
6747
6748 return 0;
6749}
6750
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006751const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6752 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006753 if (!MacroDef || !TU)
6754 return 0;
6755 const IdentifierInfo *II = MacroDef->getName();
6756 if (!II)
6757 return 0;
6758
6759 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6760}
6761
6762MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6763 const Token &Tok,
6764 CXTranslationUnit TU) {
6765 if (!MI || !TU)
6766 return 0;
6767 if (Tok.isNot(tok::raw_identifier))
6768 return 0;
6769
6770 if (MI->getNumTokens() == 0)
6771 return 0;
6772 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6773 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006774 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006775
6776 // Check that the token is inside the definition and not its argument list.
6777 SourceManager &SM = Unit->getSourceManager();
6778 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6779 return 0;
6780 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6781 return 0;
6782
6783 Preprocessor &PP = Unit->getPreprocessor();
6784 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6785 if (!PPRec)
6786 return 0;
6787
6788 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6789 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6790 if (!II.hadMacroDefinition())
6791 return 0;
6792
6793 // Check that the identifier is not one of the macro arguments.
6794 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6795 return 0;
6796
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006797 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6798 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006799 return 0;
6800
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006801 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006802}
6803
6804MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6805 SourceLocation Loc,
6806 CXTranslationUnit TU) {
6807 if (Loc.isInvalid() || !MI || !TU)
6808 return 0;
6809
6810 if (MI->getNumTokens() == 0)
6811 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006812 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006813 Preprocessor &PP = Unit->getPreprocessor();
6814 if (!PP.getPreprocessingRecord())
6815 return 0;
6816 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6817 Token Tok;
6818 if (PP.getRawToken(Loc, Tok))
6819 return 0;
6820
6821 return checkForMacroInMacroDefinition(MI, Tok, TU);
6822}
6823
Guy Benyei11169dd2012-12-18 14:30:41 +00006824extern "C" {
6825
6826CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006827 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006828}
6829
6830} // end: extern "C"
6831
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006832Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6833 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006834 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006835 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006836 if (Unit->isMainFileAST())
6837 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006838 return *this;
6839 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006840 } else {
6841 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006842 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006843 return *this;
6844}
6845
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006846Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6847 *this << FE->getName();
6848 return *this;
6849}
6850
6851Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6852 CXString cursorName = clang_getCursorDisplayName(cursor);
6853 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6854 clang_disposeString(cursorName);
6855 return *this;
6856}
6857
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006858Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6859 CXFile File;
6860 unsigned Line, Column;
6861 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6862 CXString FileName = clang_getFileName(File);
6863 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6864 clang_disposeString(FileName);
6865 return *this;
6866}
6867
6868Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6869 CXSourceLocation BLoc = clang_getRangeStart(range);
6870 CXSourceLocation ELoc = clang_getRangeEnd(range);
6871
6872 CXFile BFile;
6873 unsigned BLine, BColumn;
6874 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6875
6876 CXFile EFile;
6877 unsigned ELine, EColumn;
6878 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6879
6880 CXString BFileName = clang_getFileName(BFile);
6881 if (BFile == EFile) {
6882 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6883 BLine, BColumn, ELine, EColumn);
6884 } else {
6885 CXString EFileName = clang_getFileName(EFile);
6886 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6887 BLine, BColumn)
6888 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6889 ELine, EColumn);
6890 clang_disposeString(EFileName);
6891 }
6892 clang_disposeString(BFileName);
6893 return *this;
6894}
6895
6896Logger &cxindex::Logger::operator<<(CXString Str) {
6897 *this << clang_getCString(Str);
6898 return *this;
6899}
6900
6901Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6902 LogOS << Fmt;
6903 return *this;
6904}
6905
6906cxindex::Logger::~Logger() {
6907 LogOS.flush();
6908
6909 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6910
6911 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6912
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006913 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006914 OS << "[libclang:" << Name << ':';
6915
6916 // FIXME: Portability.
6917#if HAVE_PTHREAD_H && __APPLE__
6918 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6919 OS << tid << ':';
6920#endif
6921
6922 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6923 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6924 OS << Msg.str() << '\n';
6925
6926 if (Trace) {
6927 llvm::sys::PrintStackTrace(stderr);
6928 OS << "--------------------------------------------------\n";
6929 }
6930}