blob: 5bfac5180240f77fed6d46f08ed795345566d051 [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 "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.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
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 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
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1848 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1849 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1850 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1851 void VisitVAArgExpr(const VAArgExpr *E);
1852 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1853 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1854 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1855 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001856 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1857 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001858 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001859 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001860 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001861 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001862 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001863 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001864 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865
Guy Benyei11169dd2012-12-18 14:30:41 +00001866private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001868 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1869 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1871 void AddStmt(const Stmt *S);
1872 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001874 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001875 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001876};
1877} // end anonyous namespace
1878
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 // 'S' should always be non-null, since it comes from the
1881 // statement we are visiting.
1882 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1883}
1884
1885void
1886EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1887 if (Qualifier)
1888 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1889}
1890
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001892 if (S)
1893 WL.push_back(StmtVisit(S, Parent));
1894}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 if (D)
1897 WL.push_back(DeclVisit(D, Parent, isFirst));
1898}
1899void EnqueueVisitor::
1900 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1901 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001903}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 if (D)
1906 WL.push_back(MemberRefVisit(D, L, Parent));
1907}
1908void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1909 if (TI)
1910 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1911 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 AddStmt(*Child);
1916 }
1917 if (size == WL.size())
1918 return;
1919 // Now reverse the entries we just added. This will match the DFS
1920 // ordering performed by the worklist.
1921 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1922 std::reverse(I, E);
1923}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001924namespace {
1925class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1926 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001927 /// \brief Process clauses with list of variables.
1928 template <typename T>
1929 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001930public:
1931 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1932#define OPENMP_CLAUSE(Name, Class) \
1933 void Visit##Class(const Class *C);
1934#include "clang/Basic/OpenMPKinds.def"
1935};
1936
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001937void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1938 Visitor->AddStmt(C->getCondition());
1939}
1940
Alexey Bataev568a8332014-03-06 06:15:19 +00001941void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1942 Visitor->AddStmt(C->getNumThreads());
1943}
1944
Alexey Bataev62c87d22014-03-21 04:51:18 +00001945void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1946 Visitor->AddStmt(C->getSafelen());
1947}
1948
Alexander Musman8bd31e62014-05-27 15:12:19 +00001949void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1950 Visitor->AddStmt(C->getNumForLoops());
1951}
1952
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001954
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001955void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1956
Alexey Bataev56dafe82014-06-20 07:16:17 +00001957void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1958 Visitor->AddStmt(C->getChunkSize());
1959}
1960
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001961void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1962
Alexey Bataev236070f2014-06-20 11:19:47 +00001963void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1964
Alexey Bataev756c1962013-09-24 03:17:45 +00001965template<typename T>
1966void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001967 for (const auto *I : Node->varlists())
1968 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001969}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001970
1971void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001972 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001973}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001974void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1975 const OMPFirstprivateClause *C) {
1976 VisitOMPClauseList(C);
1977}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001978void OMPClauseEnqueue::VisitOMPLastprivateClause(
1979 const OMPLastprivateClause *C) {
1980 VisitOMPClauseList(C);
1981}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001982void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001983 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001984}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001985void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1986 VisitOMPClauseList(C);
1987}
Alexander Musman8dba6642014-04-22 13:09:42 +00001988void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1989 VisitOMPClauseList(C);
1990 Visitor->AddStmt(C->getStep());
1991}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001992void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1993 VisitOMPClauseList(C);
1994 Visitor->AddStmt(C->getAlignment());
1995}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001996void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1997 VisitOMPClauseList(C);
1998}
Alexey Bataevbae9a792014-06-27 10:37:06 +00001999void
2000OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2001 VisitOMPClauseList(C);
2002}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003}
Alexey Bataev756c1962013-09-24 03:17:45 +00002004
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002005void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2006 unsigned size = WL.size();
2007 OMPClauseEnqueue Visitor(this);
2008 Visitor.Visit(S);
2009 if (size == WL.size())
2010 return;
2011 // Now reverse the entries we just added. This will match the DFS
2012 // ordering performed by the worklist.
2013 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2014 std::reverse(I, E);
2015}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002020 AddDecl(B->getBlockDecl());
2021}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 EnqueueChildren(E);
2024 AddTypeLoc(E->getTypeSourceInfo());
2025}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2027 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 E = S->body_rend(); I != E; ++I) {
2029 AddStmt(*I);
2030 }
2031}
2032void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002033VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002034 AddStmt(S->getSubStmt());
2035 AddDeclarationNameInfo(S);
2036 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2037 AddNestedNameSpecifierLoc(QualifierLoc);
2038}
2039
2040void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2043 AddDeclarationNameInfo(E);
2044 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2045 AddNestedNameSpecifierLoc(QualifierLoc);
2046 if (!E->isImplicitAccess())
2047 AddStmt(E->getBase());
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 // Enqueue the initializer , if any.
2051 AddStmt(E->getInitializer());
2052 // Enqueue the array size, if any.
2053 AddStmt(E->getArraySize());
2054 // Enqueue the allocated type.
2055 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2056 // Enqueue the placement arguments.
2057 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2058 AddStmt(E->getPlacementArg(I-1));
2059}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2062 AddStmt(CE->getArg(I-1));
2063 AddStmt(CE->getCallee());
2064 AddStmt(CE->getArg(0));
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2067 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 // Visit the name of the type being destroyed.
2069 AddTypeLoc(E->getDestroyedTypeInfo());
2070 // Visit the scope type that looks disturbingly like the nested-name-specifier
2071 // but isn't.
2072 AddTypeLoc(E->getScopeTypeInfo());
2073 // Visit the nested-name-specifier.
2074 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2075 AddNestedNameSpecifierLoc(QualifierLoc);
2076 // Visit base expression.
2077 AddStmt(E->getBase());
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2080 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddTypeLoc(E->getTypeSourceInfo());
2082}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2084 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 EnqueueChildren(E);
2086 AddTypeLoc(E->getTypeSourceInfo());
2087}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 EnqueueChildren(E);
2090 if (E->isTypeOperand())
2091 AddTypeLoc(E->getTypeOperandSourceInfo());
2092}
2093
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002094void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2095 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 EnqueueChildren(E);
2097 AddTypeLoc(E->getTypeSourceInfo());
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 EnqueueChildren(E);
2101 if (E->isTypeOperand())
2102 AddTypeLoc(E->getTypeOperandSourceInfo());
2103}
2104
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002106 EnqueueChildren(S);
2107 AddDecl(S->getExceptionDecl());
2108}
2109
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 if (DR->hasExplicitTemplateArgs()) {
2112 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2113 }
2114 WL.push_back(DeclRefExprParts(DR, Parent));
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2117 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2119 AddDeclarationNameInfo(E);
2120 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 unsigned size = WL.size();
2124 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002125 for (const auto *D : S->decls()) {
2126 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 isFirst = false;
2128 }
2129 if (size == WL.size())
2130 return;
2131 // Now reverse the entries we just added. This will match the DFS
2132 // ordering performed by the worklist.
2133 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2134 std::reverse(I, E);
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 D = E->designators_rbegin(), DEnd = E->designators_rend();
2140 D != DEnd; ++D) {
2141 if (D->isFieldDesignator()) {
2142 if (FieldDecl *Field = D->getField())
2143 AddMemberRef(Field, D->getFieldLoc());
2144 continue;
2145 }
2146 if (D->isArrayDesignator()) {
2147 AddStmt(E->getArrayIndex(*D));
2148 continue;
2149 }
2150 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2151 AddStmt(E->getArrayRangeEnd(*D));
2152 AddStmt(E->getArrayRangeStart(*D));
2153 }
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 EnqueueChildren(E);
2157 AddTypeLoc(E->getTypeInfoAsWritten());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 AddStmt(FS->getBody());
2161 AddStmt(FS->getInc());
2162 AddStmt(FS->getCond());
2163 AddDecl(FS->getConditionVariable());
2164 AddStmt(FS->getInit());
2165}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 AddStmt(If->getElse());
2171 AddStmt(If->getThen());
2172 AddStmt(If->getCond());
2173 AddDecl(If->getConditionVariable());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 // We care about the syntactic form of the initializer list, only.
2177 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2178 IE = Syntactic;
2179 EnqueueChildren(IE);
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 WL.push_back(MemberExprParts(M, Parent));
2183
2184 // If the base of the member access expression is an implicit 'this', don't
2185 // visit it.
2186 // FIXME: If we ever want to show these implicit accesses, this will be
2187 // unfortunate. However, clang_getCursor() relies on this behavior.
2188 if (!M->isImplicitAccess())
2189 AddStmt(M->getBase());
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddTypeLoc(E->getEncodedTypeSourceInfo());
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 EnqueueChildren(M);
2196 AddTypeLoc(M->getClassReceiverTypeInfo());
2197}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 // Visit the components of the offsetof expression.
2200 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2201 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2202 const OffsetOfNode &Node = E->getComponent(I-1);
2203 switch (Node.getKind()) {
2204 case OffsetOfNode::Array:
2205 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2206 break;
2207 case OffsetOfNode::Field:
2208 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2209 break;
2210 case OffsetOfNode::Identifier:
2211 case OffsetOfNode::Base:
2212 continue;
2213 }
2214 }
2215 // Visit the type into which we're computing the offset.
2216 AddTypeLoc(E->getTypeSourceInfo());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2220 WL.push_back(OverloadExprParts(E, Parent));
2221}
2222void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 EnqueueChildren(E);
2225 if (E->isArgumentType())
2226 AddTypeLoc(E->getArgumentTypeInfo());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 EnqueueChildren(S);
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(S->getBody());
2233 AddStmt(S->getCond());
2234 AddDecl(S->getConditionVariable());
2235}
2236
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 AddStmt(W->getBody());
2239 AddStmt(W->getCond());
2240 AddDecl(W->getConditionVariable());
2241}
2242
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 for (unsigned I = E->getNumArgs(); I > 0; --I)
2245 AddTypeLoc(E->getArg(I-1));
2246}
2247
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddTypeLoc(E->getQueriedTypeSourceInfo());
2250}
2251
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 EnqueueChildren(E);
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 VisitOverloadExpr(U);
2258 if (!U->isImplicitAccess())
2259 AddStmt(U->getBase());
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddStmt(E->getSubExpr());
2263 AddTypeLoc(E->getWrittenTypeInfo());
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 WL.push_back(SizeOfPackExprParts(E, Parent));
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 // If the opaque value has a source expression, just transparently
2270 // visit that. This is useful for (e.g.) pseudo-object expressions.
2271 if (Expr *SourceExpr = E->getSourceExpr())
2272 return Visit(SourceExpr);
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 AddStmt(E->getBody());
2276 WL.push_back(LambdaExprParts(E, Parent));
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 // Treat the expression like its syntactic form.
2280 Visit(E->getSyntacticForm());
2281}
2282
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002283void EnqueueVisitor::VisitOMPExecutableDirective(
2284 const OMPExecutableDirective *D) {
2285 EnqueueChildren(D);
2286 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2287 E = D->clauses().end();
2288 I != E; ++I)
2289 EnqueueChildren(*I);
2290}
2291
2292void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2293 VisitOMPExecutableDirective(D);
2294}
2295
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002296void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2297 VisitOMPExecutableDirective(D);
2298}
2299
Alexey Bataevf29276e2014-06-18 04:14:57 +00002300void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2301 VisitOMPExecutableDirective(D);
2302}
2303
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002304void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2305 VisitOMPExecutableDirective(D);
2306}
2307
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002308void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2309 VisitOMPExecutableDirective(D);
2310}
2311
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002312void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2313 VisitOMPExecutableDirective(D);
2314}
2315
Alexey Bataev4acb8592014-07-07 13:01:15 +00002316void
2317EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2318 VisitOMPExecutableDirective(D);
2319}
2320
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002321void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2322 const OMPParallelSectionsDirective *D) {
2323 VisitOMPExecutableDirective(D);
2324}
2325
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2328}
2329
2330bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2331 if (RegionOfInterest.isValid()) {
2332 SourceRange Range = getRawCursorExtent(C);
2333 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2334 return false;
2335 }
2336 return true;
2337}
2338
2339bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2340 while (!WL.empty()) {
2341 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002342 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343
2344 // Set the Parent field, then back to its old value once we're done.
2345 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2346
2347 switch (LI.getKind()) {
2348 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002349 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002350 if (!D)
2351 continue;
2352
2353 // For now, perform default visitation for Decls.
2354 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2355 cast<DeclVisit>(&LI)->isFirst())))
2356 return true;
2357
2358 continue;
2359 }
2360 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2361 const ASTTemplateArgumentListInfo *ArgList =
2362 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2363 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2364 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2365 Arg != ArgEnd; ++Arg) {
2366 if (VisitTemplateArgumentLoc(*Arg))
2367 return true;
2368 }
2369 continue;
2370 }
2371 case VisitorJob::TypeLocVisitKind: {
2372 // Perform default visitation for TypeLocs.
2373 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2374 return true;
2375 continue;
2376 }
2377 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002378 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 if (LabelStmt *stmt = LS->getStmt()) {
2380 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2381 TU))) {
2382 return true;
2383 }
2384 }
2385 continue;
2386 }
2387
2388 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2389 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2390 if (VisitNestedNameSpecifierLoc(V->get()))
2391 return true;
2392 continue;
2393 }
2394
2395 case VisitorJob::DeclarationNameInfoVisitKind: {
2396 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2397 ->get()))
2398 return true;
2399 continue;
2400 }
2401 case VisitorJob::MemberRefVisitKind: {
2402 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2403 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2404 return true;
2405 continue;
2406 }
2407 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 if (!S)
2410 continue;
2411
2412 // Update the current cursor.
2413 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2414 if (!IsInRegionOfInterest(Cursor))
2415 continue;
2416 switch (Visitor(Cursor, Parent, ClientData)) {
2417 case CXChildVisit_Break: return true;
2418 case CXChildVisit_Continue: break;
2419 case CXChildVisit_Recurse:
2420 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002421 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 EnqueueWorkList(WL, S);
2423 break;
2424 }
2425 continue;
2426 }
2427 case VisitorJob::MemberExprPartsKind: {
2428 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002430
2431 // Visit the nested-name-specifier
2432 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2433 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2434 return true;
2435
2436 // Visit the declaration name.
2437 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2438 return true;
2439
2440 // Visit the explicitly-specified template arguments, if any.
2441 if (M->hasExplicitTemplateArgs()) {
2442 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2443 *ArgEnd = Arg + M->getNumTemplateArgs();
2444 Arg != ArgEnd; ++Arg) {
2445 if (VisitTemplateArgumentLoc(*Arg))
2446 return true;
2447 }
2448 }
2449 continue;
2450 }
2451 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002452 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002453 // Visit nested-name-specifier, if present.
2454 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2455 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2456 return true;
2457 // Visit declaration name.
2458 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2459 return true;
2460 continue;
2461 }
2462 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 // Visit the nested-name-specifier.
2465 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2466 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2467 return true;
2468 // Visit the declaration name.
2469 if (VisitDeclarationNameInfo(O->getNameInfo()))
2470 return true;
2471 // Visit the overloaded declaration reference.
2472 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2473 return true;
2474 continue;
2475 }
2476 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002477 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002478 NamedDecl *Pack = E->getPack();
2479 if (isa<TemplateTypeParmDecl>(Pack)) {
2480 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2481 E->getPackLoc(), TU)))
2482 return true;
2483
2484 continue;
2485 }
2486
2487 if (isa<TemplateTemplateParmDecl>(Pack)) {
2488 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2489 E->getPackLoc(), TU)))
2490 return true;
2491
2492 continue;
2493 }
2494
2495 // Non-type template parameter packs and function parameter packs are
2496 // treated like DeclRefExpr cursors.
2497 continue;
2498 }
2499
2500 case VisitorJob::LambdaExprPartsKind: {
2501 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2504 CEnd = E->explicit_capture_end();
2505 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002506 // FIXME: Lambda init-captures.
2507 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002509
Guy Benyei11169dd2012-12-18 14:30:41 +00002510 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2511 C->getLocation(),
2512 TU)))
2513 return true;
2514 }
2515
2516 // Visit parameters and return type, if present.
2517 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2518 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2519 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2520 // Visit the whole type.
2521 if (Visit(TL))
2522 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002523 } else if (FunctionProtoTypeLoc Proto =
2524 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 if (E->hasExplicitParameters()) {
2526 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002527 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2528 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 return true;
2530 } else {
2531 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002532 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 return true;
2534 }
2535 }
2536 }
2537 break;
2538 }
2539
2540 case VisitorJob::PostChildrenVisitKind:
2541 if (PostChildrenVisitor(Parent, ClientData))
2542 return true;
2543 break;
2544 }
2545 }
2546 return false;
2547}
2548
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002549bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002550 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 if (!WorkListFreeList.empty()) {
2552 WL = WorkListFreeList.back();
2553 WL->clear();
2554 WorkListFreeList.pop_back();
2555 }
2556 else {
2557 WL = new VisitorWorkList();
2558 WorkListCache.push_back(WL);
2559 }
2560 EnqueueWorkList(*WL, S);
2561 bool result = RunVisitorWorkList(*WL);
2562 WorkListFreeList.push_back(WL);
2563 return result;
2564}
2565
2566namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002567typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002568RefNamePieces
2569buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2570 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2571 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002572 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2573 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2574 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2575
2576 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2577
2578 RefNamePieces Pieces;
2579
2580 if (WantQualifier && QLoc.isValid())
2581 Pieces.push_back(QLoc);
2582
2583 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2584 Pieces.push_back(NI.getLoc());
2585
2586 if (WantTemplateArgs && TemplateArgs)
2587 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2588 TemplateArgs->RAngleLoc));
2589
2590 if (Kind == DeclarationName::CXXOperatorName) {
2591 Pieces.push_back(SourceLocation::getFromRawEncoding(
2592 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2593 Pieces.push_back(SourceLocation::getFromRawEncoding(
2594 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2595 }
2596
2597 if (WantSinglePiece) {
2598 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2599 Pieces.clear();
2600 Pieces.push_back(R);
2601 }
2602
2603 return Pieces;
2604}
2605}
2606
2607//===----------------------------------------------------------------------===//
2608// Misc. API hooks.
2609//===----------------------------------------------------------------------===//
2610
Chad Rosier05c71aa2013-03-27 18:28:23 +00002611static void fatal_error_handler(void *user_data, const std::string& reason,
2612 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 // Write the result out to stderr avoiding errs() because raw_ostreams can
2614 // call report_fatal_error.
2615 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2616 ::abort();
2617}
2618
Chandler Carruth66660742014-06-27 16:37:27 +00002619namespace {
2620struct RegisterFatalErrorHandler {
2621 RegisterFatalErrorHandler() {
2622 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2623 }
2624};
2625}
2626
2627static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2628
Guy Benyei11169dd2012-12-18 14:30:41 +00002629extern "C" {
2630CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2631 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002632 // We use crash recovery to make some of our APIs more reliable, implicitly
2633 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002634 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2635 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002636
Chandler Carruth66660742014-06-27 16:37:27 +00002637 // Look through the managed static to trigger construction of the managed
2638 // static which registers our fatal error handler. This ensures it is only
2639 // registered once.
2640 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002641
2642 CIndexer *CIdxr = new CIndexer();
2643 if (excludeDeclarationsFromPCH)
2644 CIdxr->setOnlyLocalDecls();
2645 if (displayDiagnostics)
2646 CIdxr->setDisplayDiagnostics();
2647
2648 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2649 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2650 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2651 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2652 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2653 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2654
2655 return CIdxr;
2656}
2657
2658void clang_disposeIndex(CXIndex CIdx) {
2659 if (CIdx)
2660 delete static_cast<CIndexer *>(CIdx);
2661}
2662
2663void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2664 if (CIdx)
2665 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2666}
2667
2668unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2669 if (CIdx)
2670 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2671 return 0;
2672}
2673
2674void clang_toggleCrashRecovery(unsigned isEnabled) {
2675 if (isEnabled)
2676 llvm::CrashRecoveryContext::Enable();
2677 else
2678 llvm::CrashRecoveryContext::Disable();
2679}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002680
Guy Benyei11169dd2012-12-18 14:30:41 +00002681CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2682 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002683 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002684 enum CXErrorCode Result =
2685 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002686 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 assert((TU && Result == CXError_Success) ||
2688 (!TU && Result != CXError_Success));
2689 return TU;
2690}
2691
2692enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2693 const char *ast_filename,
2694 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002695 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002696 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002697
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002698 if (!CIdx || !ast_filename || !out_TU)
2699 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002700
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002701 LOG_FUNC_SECTION {
2702 *Log << ast_filename;
2703 }
2704
Guy Benyei11169dd2012-12-18 14:30:41 +00002705 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2706 FileSystemOptions FileSystemOpts;
2707
2708 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002709 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002710 CXXIdx->getOnlyLocalDecls(), None,
2711 /*CaptureDiagnostics=*/true,
2712 /*AllowPCHWithCompilerErrors=*/true,
2713 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002714 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2715 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002716}
2717
2718unsigned clang_defaultEditingTranslationUnitOptions() {
2719 return CXTranslationUnit_PrecompiledPreamble |
2720 CXTranslationUnit_CacheCompletionResults;
2721}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002722
Guy Benyei11169dd2012-12-18 14:30:41 +00002723CXTranslationUnit
2724clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2725 const char *source_filename,
2726 int num_command_line_args,
2727 const char * const *command_line_args,
2728 unsigned num_unsaved_files,
2729 struct CXUnsavedFile *unsaved_files) {
2730 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2731 return clang_parseTranslationUnit(CIdx, source_filename,
2732 command_line_args, num_command_line_args,
2733 unsaved_files, num_unsaved_files,
2734 Options);
2735}
2736
2737struct ParseTranslationUnitInfo {
2738 CXIndex CIdx;
2739 const char *source_filename;
2740 const char *const *command_line_args;
2741 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002742 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002743 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002744 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002745 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002746};
2747static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002748 const ParseTranslationUnitInfo *PTUI =
2749 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002750 CXIndex CIdx = PTUI->CIdx;
2751 const char *source_filename = PTUI->source_filename;
2752 const char * const *command_line_args = PTUI->command_line_args;
2753 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002755 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002756
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002757 // Set up the initial return values.
2758 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002759 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002760
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002761 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002762 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002763 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002764 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002765 }
2766
Guy Benyei11169dd2012-12-18 14:30:41 +00002767 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2768
2769 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2770 setThreadBackgroundPriority();
2771
2772 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2773 // FIXME: Add a flag for modules.
2774 TranslationUnitKind TUKind
2775 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002776 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 = options & CXTranslationUnit_CacheCompletionResults;
2778 bool IncludeBriefCommentsInCodeCompletion
2779 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2780 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2781 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2782
2783 // Configure the diagnostics.
2784 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002785 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002786
2787 // Recover resources if we crash before exiting this function.
2788 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2789 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002790 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002791
Ahmed Charlesb8984322014-03-07 20:03:18 +00002792 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2793 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002794
2795 // Recover resources if we crash before exiting this function.
2796 llvm::CrashRecoveryContextCleanupRegistrar<
2797 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2798
Alp Toker9d85b182014-07-07 01:23:14 +00002799 for (auto &UF : PTUI->unsaved_files) {
2800 llvm::MemoryBuffer *MB =
2801 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2802 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002803 }
2804
Ahmed Charlesb8984322014-03-07 20:03:18 +00002805 std::unique_ptr<std::vector<const char *>> Args(
2806 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002807
2808 // Recover resources if we crash before exiting this method.
2809 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2810 ArgsCleanup(Args.get());
2811
2812 // Since the Clang C library is primarily used by batch tools dealing with
2813 // (often very broken) source code, where spell-checking can have a
2814 // significant negative impact on performance (particularly when
2815 // precompiled headers are involved), we disable it by default.
2816 // Only do this if we haven't found a spell-checking-related argument.
2817 bool FoundSpellCheckingArgument = false;
2818 for (int I = 0; I != num_command_line_args; ++I) {
2819 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2820 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2821 FoundSpellCheckingArgument = true;
2822 break;
2823 }
2824 }
2825 if (!FoundSpellCheckingArgument)
2826 Args->push_back("-fno-spell-checking");
2827
2828 Args->insert(Args->end(), command_line_args,
2829 command_line_args + num_command_line_args);
2830
2831 // The 'source_filename' argument is optional. If the caller does not
2832 // specify it then it is assumed that the source file is specified
2833 // in the actual argument list.
2834 // Put the source file after command_line_args otherwise if '-x' flag is
2835 // present it will be unused.
2836 if (source_filename)
2837 Args->push_back(source_filename);
2838
2839 // Do we need the detailed preprocessing record?
2840 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2841 Args->push_back("-Xclang");
2842 Args->push_back("-detailed-preprocessing-record");
2843 }
2844
2845 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002846 std::unique_ptr<ASTUnit> ErrUnit;
2847 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002848 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002849 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2850 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2851 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2852 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2853 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2854 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002855
2856 if (NumErrors != Diags->getClient()->getNumErrors()) {
2857 // Make sure to check that 'Unit' is non-NULL.
2858 if (CXXIdx->getDisplayDiagnostics())
2859 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2860 }
2861
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002862 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2863 PTUI->result = CXError_ASTReadError;
2864 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002865 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002866 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2867 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002868}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869
2870CXTranslationUnit
2871clang_parseTranslationUnit(CXIndex CIdx,
2872 const char *source_filename,
2873 const char *const *command_line_args,
2874 int num_command_line_args,
2875 struct CXUnsavedFile *unsaved_files,
2876 unsigned num_unsaved_files,
2877 unsigned options) {
2878 CXTranslationUnit TU;
2879 enum CXErrorCode Result = clang_parseTranslationUnit2(
2880 CIdx, source_filename, command_line_args, num_command_line_args,
2881 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002882 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002883 assert((TU && Result == CXError_Success) ||
2884 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002885 return TU;
2886}
2887
2888enum CXErrorCode clang_parseTranslationUnit2(
2889 CXIndex CIdx,
2890 const char *source_filename,
2891 const char *const *command_line_args,
2892 int num_command_line_args,
2893 struct CXUnsavedFile *unsaved_files,
2894 unsigned num_unsaved_files,
2895 unsigned options,
2896 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002897 LOG_FUNC_SECTION {
2898 *Log << source_filename << ": ";
2899 for (int i = 0; i != num_command_line_args; ++i)
2900 *Log << command_line_args[i] << " ";
2901 }
2902
Alp Toker9d85b182014-07-07 01:23:14 +00002903 if (num_unsaved_files && !unsaved_files)
2904 return CXError_InvalidArguments;
2905
Alp Toker5c532982014-07-07 22:42:03 +00002906 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002907 ParseTranslationUnitInfo PTUI = {
2908 CIdx,
2909 source_filename,
2910 command_line_args,
2911 num_command_line_args,
2912 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2913 options,
2914 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002915 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 llvm::CrashRecoveryContext CRC;
2917
2918 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2919 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2920 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2921 fprintf(stderr, " 'command_line_args' : [");
2922 for (int i = 0; i != num_command_line_args; ++i) {
2923 if (i)
2924 fprintf(stderr, ", ");
2925 fprintf(stderr, "'%s'", command_line_args[i]);
2926 }
2927 fprintf(stderr, "],\n");
2928 fprintf(stderr, " 'unsaved_files' : [");
2929 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2930 if (i)
2931 fprintf(stderr, ", ");
2932 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2933 unsaved_files[i].Length);
2934 }
2935 fprintf(stderr, "],\n");
2936 fprintf(stderr, " 'options' : %d,\n", options);
2937 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002938
2939 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002940 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002941 if (CXTranslationUnit *TU = PTUI.out_TU)
2942 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002943 }
Alp Toker5c532982014-07-07 22:42:03 +00002944
2945 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002946}
2947
2948unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2949 return CXSaveTranslationUnit_None;
2950}
2951
2952namespace {
2953
2954struct SaveTranslationUnitInfo {
2955 CXTranslationUnit TU;
2956 const char *FileName;
2957 unsigned options;
2958 CXSaveError result;
2959};
2960
2961}
2962
2963static void clang_saveTranslationUnit_Impl(void *UserData) {
2964 SaveTranslationUnitInfo *STUI =
2965 static_cast<SaveTranslationUnitInfo*>(UserData);
2966
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002967 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002968 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2969 setThreadBackgroundPriority();
2970
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002971 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002972 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2973}
2974
2975int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2976 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002977 LOG_FUNC_SECTION {
2978 *Log << TU << ' ' << FileName;
2979 }
2980
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002981 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002982 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002983 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002984 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002985
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002986 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002987 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2988 if (!CXXUnit->hasSema())
2989 return CXSaveError_InvalidTU;
2990
2991 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2992
2993 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2994 getenv("LIBCLANG_NOTHREADS")) {
2995 clang_saveTranslationUnit_Impl(&STUI);
2996
2997 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2998 PrintLibclangResourceUsage(TU);
2999
3000 return STUI.result;
3001 }
3002
3003 // We have an AST that has invalid nodes due to compiler errors.
3004 // Use a crash recovery thread for protection.
3005
3006 llvm::CrashRecoveryContext CRC;
3007
3008 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3009 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3010 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3011 fprintf(stderr, " 'options' : %d,\n", options);
3012 fprintf(stderr, "}\n");
3013
3014 return CXSaveError_Unknown;
3015
3016 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3017 PrintLibclangResourceUsage(TU);
3018 }
3019
3020 return STUI.result;
3021}
3022
3023void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3024 if (CTUnit) {
3025 // If the translation unit has been marked as unsafe to free, just discard
3026 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3028 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 return;
3030
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003031 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003032 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003033 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3034 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003035 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003036 delete CTUnit;
3037 }
3038}
3039
3040unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3041 return CXReparse_None;
3042}
3043
3044struct ReparseTranslationUnitInfo {
3045 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003046 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003048 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003049};
3050
3051static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003052 const ReparseTranslationUnitInfo *RTUI =
3053 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 unsigned options = RTUI->options;
3056 (void) options;
3057
3058 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003059 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003060 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061 RTUI->result = CXError_InvalidArguments;
3062 return;
3063 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003064
3065 // Reset the associated diagnostics.
3066 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003067 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003068
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003069 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3071 setThreadBackgroundPriority();
3072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003073 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003075
3076 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3077 new std::vector<ASTUnit::RemappedFile>());
3078
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 // Recover resources if we crash before exiting this function.
3080 llvm::CrashRecoveryContextCleanupRegistrar<
3081 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003082
3083 for (auto &UF : RTUI->unsaved_files) {
3084 llvm::MemoryBuffer *MB =
3085 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3086 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003087 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003088
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003089 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003090 RTUI->result = CXError_Success;
3091 else if (isASTReadError(CXXUnit))
3092 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003093}
3094
3095int clang_reparseTranslationUnit(CXTranslationUnit TU,
3096 unsigned num_unsaved_files,
3097 struct CXUnsavedFile *unsaved_files,
3098 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003099 LOG_FUNC_SECTION {
3100 *Log << TU;
3101 }
3102
Alp Toker9d85b182014-07-07 01:23:14 +00003103 if (num_unsaved_files && !unsaved_files)
3104 return CXError_InvalidArguments;
3105
Alp Toker5c532982014-07-07 22:42:03 +00003106 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003107 ReparseTranslationUnitInfo RTUI = {
3108 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003109 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
3111 if (getenv("LIBCLANG_NOTHREADS")) {
3112 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003113 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 }
3115
3116 llvm::CrashRecoveryContext CRC;
3117
3118 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3119 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003120 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003121 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3123 PrintLibclangResourceUsage(TU);
3124
Alp Toker5c532982014-07-07 22:42:03 +00003125 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003126}
3127
3128
3129CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003130 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003131 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003132 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003133 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003134
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003135 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003136 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003137}
3138
3139CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003140 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003141 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003142 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003143 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003144
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003145 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3147}
3148
3149} // end: extern "C"
3150
3151//===----------------------------------------------------------------------===//
3152// CXFile Operations.
3153//===----------------------------------------------------------------------===//
3154
3155extern "C" {
3156CXString clang_getFileName(CXFile SFile) {
3157 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003158 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003159
3160 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003161 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003162}
3163
3164time_t clang_getFileTime(CXFile SFile) {
3165 if (!SFile)
3166 return 0;
3167
3168 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3169 return FEnt->getModificationTime();
3170}
3171
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003172CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003173 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003174 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003175 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003176 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003177
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003178 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003179
3180 FileManager &FMgr = CXXUnit->getFileManager();
3181 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3182}
3183
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003184unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3185 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003186 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003187 LOG_BAD_TU(TU);
3188 return 0;
3189 }
3190
3191 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 return 0;
3193
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003194 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 FileEntry *FEnt = static_cast<FileEntry *>(file);
3196 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3197 .isFileMultipleIncludeGuarded(FEnt);
3198}
3199
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003200int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3201 if (!file || !outID)
3202 return 1;
3203
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003204 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003205 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3206 outID->data[0] = ID.getDevice();
3207 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003208 outID->data[2] = FEnt->getModificationTime();
3209 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003210}
3211
Guy Benyei11169dd2012-12-18 14:30:41 +00003212} // end: extern "C"
3213
3214//===----------------------------------------------------------------------===//
3215// CXCursor Operations.
3216//===----------------------------------------------------------------------===//
3217
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003218static const Decl *getDeclFromExpr(const Stmt *E) {
3219 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return getDeclFromExpr(CE->getSubExpr());
3221
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003222 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003224 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003226 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003228 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 if (PRE->isExplicitProperty())
3230 return PRE->getExplicitProperty();
3231 // It could be messaging both getter and setter as in:
3232 // ++myobj.myprop;
3233 // in which case prefer to associate the setter since it is less obvious
3234 // from inspecting the source that the setter is going to get called.
3235 if (PRE->isMessagingSetter())
3236 return PRE->getImplicitPropertySetter();
3237 return PRE->getImplicitPropertyGetter();
3238 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003239 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003241 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 if (Expr *Src = OVE->getSourceExpr())
3243 return getDeclFromExpr(Src);
3244
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003245 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003247 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 if (!CE->isElidable())
3249 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003250 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 return OME->getMethodDecl();
3252
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003253 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003255 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3257 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003258 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3260 isa<ParmVarDecl>(SizeOfPack->getPack()))
3261 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003262
3263 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003264}
3265
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003266static SourceLocation getLocationFromExpr(const Expr *E) {
3267 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 return getLocationFromExpr(CE->getSubExpr());
3269
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003270 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003272 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003274 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003276 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003278 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003280 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 return PropRef->getLocation();
3282
3283 return E->getLocStart();
3284}
3285
3286extern "C" {
3287
3288unsigned clang_visitChildren(CXCursor parent,
3289 CXCursorVisitor visitor,
3290 CXClientData client_data) {
3291 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3292 /*VisitPreprocessorLast=*/false);
3293 return CursorVis.VisitChildren(parent);
3294}
3295
3296#ifndef __has_feature
3297#define __has_feature(x) 0
3298#endif
3299#if __has_feature(blocks)
3300typedef enum CXChildVisitResult
3301 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3302
3303static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3304 CXClientData client_data) {
3305 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3306 return block(cursor, parent);
3307}
3308#else
3309// If we are compiled with a compiler that doesn't have native blocks support,
3310// define and call the block manually, so the
3311typedef struct _CXChildVisitResult
3312{
3313 void *isa;
3314 int flags;
3315 int reserved;
3316 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3317 CXCursor);
3318} *CXCursorVisitorBlock;
3319
3320static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3321 CXClientData client_data) {
3322 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3323 return block->invoke(block, cursor, parent);
3324}
3325#endif
3326
3327
3328unsigned clang_visitChildrenWithBlock(CXCursor parent,
3329 CXCursorVisitorBlock block) {
3330 return clang_visitChildren(parent, visitWithBlock, block);
3331}
3332
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003333static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003335 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003336
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003337 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003339 if (const ObjCPropertyImplDecl *PropImpl =
3340 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003344 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003346 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003348 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003351 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003352 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003354 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3356 // and returns different names. NamedDecl returns the class name and
3357 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003358 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003359
3360 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003361 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003362
3363 SmallString<1024> S;
3364 llvm::raw_svector_ostream os(S);
3365 ND->printName(os);
3366
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368}
3369
3370CXString clang_getCursorSpelling(CXCursor C) {
3371 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003372 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003373
3374 if (clang_isReference(C.kind)) {
3375 switch (C.kind) {
3376 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003377 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003378 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 }
3380 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003381 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003382 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 }
3384 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003385 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003387 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003390 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003391 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 }
3393 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003394 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 assert(Type && "Missing type decl");
3396
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003397 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 getAsString());
3399 }
3400 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003401 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 assert(Template && "Missing template decl");
3403
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003404 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 }
3406
3407 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003408 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 assert(NS && "Missing namespace decl");
3410
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003411 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413
3414 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003415 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 assert(Field && "Missing member decl");
3417
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003418 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 }
3420
3421 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003422 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 assert(Label && "Missing label");
3424
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003425 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 }
3427
3428 case CXCursor_OverloadedDeclRef: {
3429 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003430 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3431 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003432 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003433 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003436 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 OverloadedTemplateStorage *Ovl
3438 = Storage.get<OverloadedTemplateStorage*>();
3439 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003440 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003441 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 }
3443
3444 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003445 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 assert(Var && "Missing variable decl");
3447
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003448 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 }
3450
3451 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003452 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454 }
3455
3456 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003457 const Expr *E = getCursorExpr(C);
3458
3459 if (C.kind == CXCursor_ObjCStringLiteral ||
3460 C.kind == CXCursor_StringLiteral) {
3461 const StringLiteral *SLit;
3462 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3463 SLit = OSL->getString();
3464 } else {
3465 SLit = cast<StringLiteral>(E);
3466 }
3467 SmallString<256> Buf;
3468 llvm::raw_svector_ostream OS(Buf);
3469 SLit->outputString(OS);
3470 return cxstring::createDup(OS.str());
3471 }
3472
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 if (D)
3475 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003476 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 }
3478
3479 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003480 const Stmt *S = getCursorStmt(C);
3481 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003482 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003483
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003484 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 }
3486
3487 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003488 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 ->getNameStart());
3490
3491 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003492 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 ->getNameStart());
3494
3495 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003496 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497
3498 if (clang_isDeclaration(C.kind))
3499 return getDeclSpelling(getCursorDecl(C));
3500
3501 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003502 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003503 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
3505
3506 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003507 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 }
3510
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003511 if (C.kind == CXCursor_PackedAttr) {
3512 return cxstring::createRef("packed");
3513 }
3514
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003515 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003516}
3517
3518CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3519 unsigned pieceIndex,
3520 unsigned options) {
3521 if (clang_Cursor_isNull(C))
3522 return clang_getNullRange();
3523
3524 ASTContext &Ctx = getCursorContext(C);
3525
3526 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003527 const Stmt *S = getCursorStmt(C);
3528 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 if (pieceIndex > 0)
3530 return clang_getNullRange();
3531 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3532 }
3533
3534 return clang_getNullRange();
3535 }
3536
3537 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003538 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3540 if (pieceIndex >= ME->getNumSelectorLocs())
3541 return clang_getNullRange();
3542 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3543 }
3544 }
3545
3546 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3547 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3550 if (pieceIndex >= MD->getNumSelectorLocs())
3551 return clang_getNullRange();
3552 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3553 }
3554 }
3555
3556 if (C.kind == CXCursor_ObjCCategoryDecl ||
3557 C.kind == CXCursor_ObjCCategoryImplDecl) {
3558 if (pieceIndex > 0)
3559 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3562 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003563 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3565 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3566 }
3567
3568 if (C.kind == CXCursor_ModuleImportDecl) {
3569 if (pieceIndex > 0)
3570 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003571 if (const ImportDecl *ImportD =
3572 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3574 if (!Locs.empty())
3575 return cxloc::translateSourceRange(Ctx,
3576 SourceRange(Locs.front(), Locs.back()));
3577 }
3578 return clang_getNullRange();
3579 }
3580
3581 // FIXME: A CXCursor_InclusionDirective should give the location of the
3582 // filename, but we don't keep track of this.
3583
3584 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3585 // but we don't keep track of this.
3586
3587 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3588 // but we don't keep track of this.
3589
3590 // Default handling, give the location of the cursor.
3591
3592 if (pieceIndex > 0)
3593 return clang_getNullRange();
3594
3595 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3596 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3597 return cxloc::translateSourceRange(Ctx, Loc);
3598}
3599
3600CXString clang_getCursorDisplayName(CXCursor C) {
3601 if (!clang_isDeclaration(C.kind))
3602 return clang_getCursorSpelling(C);
3603
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003604 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003606 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003607
3608 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003609 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 D = FunTmpl->getTemplatedDecl();
3611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003612 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 SmallString<64> Str;
3614 llvm::raw_svector_ostream OS(Str);
3615 OS << *Function;
3616 if (Function->getPrimaryTemplate())
3617 OS << "<>";
3618 OS << "(";
3619 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3620 if (I)
3621 OS << ", ";
3622 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3623 }
3624
3625 if (Function->isVariadic()) {
3626 if (Function->getNumParams())
3627 OS << ", ";
3628 OS << "...";
3629 }
3630 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003631 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 }
3633
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003634 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 SmallString<64> Str;
3636 llvm::raw_svector_ostream OS(Str);
3637 OS << *ClassTemplate;
3638 OS << "<";
3639 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3640 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3641 if (I)
3642 OS << ", ";
3643
3644 NamedDecl *Param = Params->getParam(I);
3645 if (Param->getIdentifier()) {
3646 OS << Param->getIdentifier()->getName();
3647 continue;
3648 }
3649
3650 // There is no parameter name, which makes this tricky. Try to come up
3651 // with something useful that isn't too long.
3652 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3653 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3654 else if (NonTypeTemplateParmDecl *NTTP
3655 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3656 OS << NTTP->getType().getAsString(Policy);
3657 else
3658 OS << "template<...> class";
3659 }
3660
3661 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003662 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 }
3664
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003665 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3667 // If the type was explicitly written, use that.
3668 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003669 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003670
Benjamin Kramer9170e912013-02-22 15:46:01 +00003671 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 llvm::raw_svector_ostream OS(Str);
3673 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003674 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 ClassSpec->getTemplateArgs().data(),
3676 ClassSpec->getTemplateArgs().size(),
3677 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003678 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680
3681 return clang_getCursorSpelling(C);
3682}
3683
3684CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3685 switch (Kind) {
3686 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003814 case CXCursor_ObjCSelfExpr:
3815 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003904 case CXCursor_SEHLeaveStmt:
3905 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003934 case CXCursor_PackedAttr:
3935 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003936 case CXCursor_PureAttr:
3937 return cxstring::createRef("attribute(pure)");
3938 case CXCursor_ConstAttr:
3939 return cxstring::createRef("attribute(const)");
3940 case CXCursor_NoDuplicateAttr:
3941 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003942 case CXCursor_CUDAConstantAttr:
3943 return cxstring::createRef("attribute(constant)");
3944 case CXCursor_CUDADeviceAttr:
3945 return cxstring::createRef("attribute(device)");
3946 case CXCursor_CUDAGlobalAttr:
3947 return cxstring::createRef("attribute(global)");
3948 case CXCursor_CUDAHostAttr:
3949 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003998 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003999 return cxstring::createRef("OMPParallelDirective");
4000 case CXCursor_OMPSimdDirective:
4001 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004002 case CXCursor_OMPForDirective:
4003 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004004 case CXCursor_OMPSectionsDirective:
4005 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004006 case CXCursor_OMPSectionDirective:
4007 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004008 case CXCursor_OMPSingleDirective:
4009 return cxstring::createRef("OMPSingleDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004010 case CXCursor_OMPParallelForDirective:
4011 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004012 case CXCursor_OMPParallelSectionsDirective:
4013 return cxstring::createRef("OMPParallelSectionsDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 }
4015
4016 llvm_unreachable("Unhandled CXCursorKind");
4017}
4018
4019struct GetCursorData {
4020 SourceLocation TokenBeginLoc;
4021 bool PointsAtMacroArgExpansion;
4022 bool VisitedObjCPropertyImplDecl;
4023 SourceLocation VisitedDeclaratorDeclStartLoc;
4024 CXCursor &BestCursor;
4025
4026 GetCursorData(SourceManager &SM,
4027 SourceLocation tokenBegin, CXCursor &outputCursor)
4028 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4029 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4030 VisitedObjCPropertyImplDecl = false;
4031 }
4032};
4033
4034static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4035 CXCursor parent,
4036 CXClientData client_data) {
4037 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4038 CXCursor *BestCursor = &Data->BestCursor;
4039
4040 // If we point inside a macro argument we should provide info of what the
4041 // token is so use the actual cursor, don't replace it with a macro expansion
4042 // cursor.
4043 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4044 return CXChildVisit_Recurse;
4045
4046 if (clang_isDeclaration(cursor.kind)) {
4047 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4050 if (MD->isImplicit())
4051 return CXChildVisit_Break;
4052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004053 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4055 // Check that when we have multiple @class references in the same line,
4056 // that later ones do not override the previous ones.
4057 // If we have:
4058 // @class Foo, Bar;
4059 // source ranges for both start at '@', so 'Bar' will end up overriding
4060 // 'Foo' even though the cursor location was at 'Foo'.
4061 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4062 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004063 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4065 if (PrevID != ID &&
4066 !PrevID->isThisDeclarationADefinition() &&
4067 !ID->isThisDeclarationADefinition())
4068 return CXChildVisit_Break;
4069 }
4070
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004071 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4073 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4074 // Check that when we have multiple declarators in the same line,
4075 // that later ones do not override the previous ones.
4076 // If we have:
4077 // int Foo, Bar;
4078 // source ranges for both start at 'int', so 'Bar' will end up overriding
4079 // 'Foo' even though the cursor location was at 'Foo'.
4080 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4081 return CXChildVisit_Break;
4082 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4083
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004084 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4086 (void)PropImp;
4087 // Check that when we have multiple @synthesize in the same line,
4088 // that later ones do not override the previous ones.
4089 // If we have:
4090 // @synthesize Foo, Bar;
4091 // source ranges for both start at '@', so 'Bar' will end up overriding
4092 // 'Foo' even though the cursor location was at 'Foo'.
4093 if (Data->VisitedObjCPropertyImplDecl)
4094 return CXChildVisit_Break;
4095 Data->VisitedObjCPropertyImplDecl = true;
4096 }
4097 }
4098
4099 if (clang_isExpression(cursor.kind) &&
4100 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004101 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 // Avoid having the cursor of an expression replace the declaration cursor
4103 // when the expression source range overlaps the declaration range.
4104 // This can happen for C++ constructor expressions whose range generally
4105 // include the variable declaration, e.g.:
4106 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4107 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4108 D->getLocation() == Data->TokenBeginLoc)
4109 return CXChildVisit_Break;
4110 }
4111 }
4112
4113 // If our current best cursor is the construction of a temporary object,
4114 // don't replace that cursor with a type reference, because we want
4115 // clang_getCursor() to point at the constructor.
4116 if (clang_isExpression(BestCursor->kind) &&
4117 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4118 cursor.kind == CXCursor_TypeRef) {
4119 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4120 // as having the actual point on the type reference.
4121 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4122 return CXChildVisit_Recurse;
4123 }
4124
4125 *BestCursor = cursor;
4126 return CXChildVisit_Recurse;
4127}
4128
4129CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004130 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004131 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004133 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004134
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004135 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4137
4138 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4139 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4140
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004141 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 CXFile SearchFile;
4143 unsigned SearchLine, SearchColumn;
4144 CXFile ResultFile;
4145 unsigned ResultLine, ResultColumn;
4146 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4147 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4148 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004149
4150 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4151 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004152 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004153 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 SearchFileName = clang_getFileName(SearchFile);
4155 ResultFileName = clang_getFileName(ResultFile);
4156 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4157 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004158 *Log << llvm::format("(%s:%d:%d) = %s",
4159 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4160 clang_getCString(KindSpelling))
4161 << llvm::format("(%s:%d:%d):%s%s",
4162 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4163 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 clang_disposeString(SearchFileName);
4165 clang_disposeString(ResultFileName);
4166 clang_disposeString(KindSpelling);
4167 clang_disposeString(USR);
4168
4169 CXCursor Definition = clang_getCursorDefinition(Result);
4170 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4171 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4172 CXString DefinitionKindSpelling
4173 = clang_getCursorKindSpelling(Definition.kind);
4174 CXFile DefinitionFile;
4175 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004176 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004177 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004179 *Log << llvm::format(" -> %s(%s:%d:%d)",
4180 clang_getCString(DefinitionKindSpelling),
4181 clang_getCString(DefinitionFileName),
4182 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 clang_disposeString(DefinitionFileName);
4184 clang_disposeString(DefinitionKindSpelling);
4185 }
4186 }
4187
4188 return Result;
4189}
4190
4191CXCursor clang_getNullCursor(void) {
4192 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4193}
4194
4195unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004196 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4197 // can't set consistently. For example, when visiting a DeclStmt we will set
4198 // it but we don't set it on the result of clang_getCursorDefinition for
4199 // a reference of the same declaration.
4200 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4201 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4202 // to provide that kind of info.
4203 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004204 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004205 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004206 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004207
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 return X == Y;
4209}
4210
4211unsigned clang_hashCursor(CXCursor C) {
4212 unsigned Index = 0;
4213 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4214 Index = 1;
4215
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004216 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 std::make_pair(C.kind, C.data[Index]));
4218}
4219
4220unsigned clang_isInvalid(enum CXCursorKind K) {
4221 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4222}
4223
4224unsigned clang_isDeclaration(enum CXCursorKind K) {
4225 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4226 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4227}
4228
4229unsigned clang_isReference(enum CXCursorKind K) {
4230 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4231}
4232
4233unsigned clang_isExpression(enum CXCursorKind K) {
4234 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4235}
4236
4237unsigned clang_isStatement(enum CXCursorKind K) {
4238 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4239}
4240
4241unsigned clang_isAttribute(enum CXCursorKind K) {
4242 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4243}
4244
4245unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4246 return K == CXCursor_TranslationUnit;
4247}
4248
4249unsigned clang_isPreprocessing(enum CXCursorKind K) {
4250 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4251}
4252
4253unsigned clang_isUnexposed(enum CXCursorKind K) {
4254 switch (K) {
4255 case CXCursor_UnexposedDecl:
4256 case CXCursor_UnexposedExpr:
4257 case CXCursor_UnexposedStmt:
4258 case CXCursor_UnexposedAttr:
4259 return true;
4260 default:
4261 return false;
4262 }
4263}
4264
4265CXCursorKind clang_getCursorKind(CXCursor C) {
4266 return C.kind;
4267}
4268
4269CXSourceLocation clang_getCursorLocation(CXCursor C) {
4270 if (clang_isReference(C.kind)) {
4271 switch (C.kind) {
4272 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004273 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 = getCursorObjCSuperClassRef(C);
4275 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4276 }
4277
4278 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004279 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 = getCursorObjCProtocolRef(C);
4281 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4282 }
4283
4284 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004285 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 = getCursorObjCClassRef(C);
4287 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4288 }
4289
4290 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004291 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4293 }
4294
4295 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004296 std::pair<const TemplateDecl *, SourceLocation> P =
4297 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4299 }
4300
4301 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004302 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4304 }
4305
4306 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004307 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4309 }
4310
4311 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004312 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4314 }
4315
4316 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004317 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 if (!BaseSpec)
4319 return clang_getNullLocation();
4320
4321 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4322 return cxloc::translateSourceLocation(getCursorContext(C),
4323 TSInfo->getTypeLoc().getBeginLoc());
4324
4325 return cxloc::translateSourceLocation(getCursorContext(C),
4326 BaseSpec->getLocStart());
4327 }
4328
4329 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004330 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4332 }
4333
4334 case CXCursor_OverloadedDeclRef:
4335 return cxloc::translateSourceLocation(getCursorContext(C),
4336 getCursorOverloadedDeclRef(C).second);
4337
4338 default:
4339 // FIXME: Need a way to enumerate all non-reference cases.
4340 llvm_unreachable("Missed a reference kind");
4341 }
4342 }
4343
4344 if (clang_isExpression(C.kind))
4345 return cxloc::translateSourceLocation(getCursorContext(C),
4346 getLocationFromExpr(getCursorExpr(C)));
4347
4348 if (clang_isStatement(C.kind))
4349 return cxloc::translateSourceLocation(getCursorContext(C),
4350 getCursorStmt(C)->getLocStart());
4351
4352 if (C.kind == CXCursor_PreprocessingDirective) {
4353 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4354 return cxloc::translateSourceLocation(getCursorContext(C), L);
4355 }
4356
4357 if (C.kind == CXCursor_MacroExpansion) {
4358 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004359 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 return cxloc::translateSourceLocation(getCursorContext(C), L);
4361 }
4362
4363 if (C.kind == CXCursor_MacroDefinition) {
4364 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4365 return cxloc::translateSourceLocation(getCursorContext(C), L);
4366 }
4367
4368 if (C.kind == CXCursor_InclusionDirective) {
4369 SourceLocation L
4370 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4371 return cxloc::translateSourceLocation(getCursorContext(C), L);
4372 }
4373
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004374 if (clang_isAttribute(C.kind)) {
4375 SourceLocation L
4376 = cxcursor::getCursorAttr(C)->getLocation();
4377 return cxloc::translateSourceLocation(getCursorContext(C), L);
4378 }
4379
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 if (!clang_isDeclaration(C.kind))
4381 return clang_getNullLocation();
4382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004383 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 if (!D)
4385 return clang_getNullLocation();
4386
4387 SourceLocation Loc = D->getLocation();
4388 // FIXME: Multiple variables declared in a single declaration
4389 // currently lack the information needed to correctly determine their
4390 // ranges when accounting for the type-specifier. We use context
4391 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4392 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004393 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 if (!cxcursor::isFirstInDeclGroup(C))
4395 Loc = VD->getLocation();
4396 }
4397
4398 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004399 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 Loc = MD->getSelectorStartLoc();
4401
4402 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4403}
4404
4405} // end extern "C"
4406
4407CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4408 assert(TU);
4409
4410 // Guard against an invalid SourceLocation, or we may assert in one
4411 // of the following calls.
4412 if (SLoc.isInvalid())
4413 return clang_getNullCursor();
4414
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004415 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004416
4417 // Translate the given source location to make it point at the beginning of
4418 // the token under the cursor.
4419 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4420 CXXUnit->getASTContext().getLangOpts());
4421
4422 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4423 if (SLoc.isValid()) {
4424 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4425 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4426 /*VisitPreprocessorLast=*/true,
4427 /*VisitIncludedEntities=*/false,
4428 SourceLocation(SLoc));
4429 CursorVis.visitFileRegion();
4430 }
4431
4432 return Result;
4433}
4434
4435static SourceRange getRawCursorExtent(CXCursor C) {
4436 if (clang_isReference(C.kind)) {
4437 switch (C.kind) {
4438 case CXCursor_ObjCSuperClassRef:
4439 return getCursorObjCSuperClassRef(C).second;
4440
4441 case CXCursor_ObjCProtocolRef:
4442 return getCursorObjCProtocolRef(C).second;
4443
4444 case CXCursor_ObjCClassRef:
4445 return getCursorObjCClassRef(C).second;
4446
4447 case CXCursor_TypeRef:
4448 return getCursorTypeRef(C).second;
4449
4450 case CXCursor_TemplateRef:
4451 return getCursorTemplateRef(C).second;
4452
4453 case CXCursor_NamespaceRef:
4454 return getCursorNamespaceRef(C).second;
4455
4456 case CXCursor_MemberRef:
4457 return getCursorMemberRef(C).second;
4458
4459 case CXCursor_CXXBaseSpecifier:
4460 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4461
4462 case CXCursor_LabelRef:
4463 return getCursorLabelRef(C).second;
4464
4465 case CXCursor_OverloadedDeclRef:
4466 return getCursorOverloadedDeclRef(C).second;
4467
4468 case CXCursor_VariableRef:
4469 return getCursorVariableRef(C).second;
4470
4471 default:
4472 // FIXME: Need a way to enumerate all non-reference cases.
4473 llvm_unreachable("Missed a reference kind");
4474 }
4475 }
4476
4477 if (clang_isExpression(C.kind))
4478 return getCursorExpr(C)->getSourceRange();
4479
4480 if (clang_isStatement(C.kind))
4481 return getCursorStmt(C)->getSourceRange();
4482
4483 if (clang_isAttribute(C.kind))
4484 return getCursorAttr(C)->getRange();
4485
4486 if (C.kind == CXCursor_PreprocessingDirective)
4487 return cxcursor::getCursorPreprocessingDirective(C);
4488
4489 if (C.kind == CXCursor_MacroExpansion) {
4490 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004491 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 return TU->mapRangeFromPreamble(Range);
4493 }
4494
4495 if (C.kind == CXCursor_MacroDefinition) {
4496 ASTUnit *TU = getCursorASTUnit(C);
4497 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4498 return TU->mapRangeFromPreamble(Range);
4499 }
4500
4501 if (C.kind == CXCursor_InclusionDirective) {
4502 ASTUnit *TU = getCursorASTUnit(C);
4503 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4504 return TU->mapRangeFromPreamble(Range);
4505 }
4506
4507 if (C.kind == CXCursor_TranslationUnit) {
4508 ASTUnit *TU = getCursorASTUnit(C);
4509 FileID MainID = TU->getSourceManager().getMainFileID();
4510 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4511 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4512 return SourceRange(Start, End);
4513 }
4514
4515 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (!D)
4518 return SourceRange();
4519
4520 SourceRange R = D->getSourceRange();
4521 // FIXME: Multiple variables declared in a single declaration
4522 // currently lack the information needed to correctly determine their
4523 // ranges when accounting for the type-specifier. We use context
4524 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4525 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 if (!cxcursor::isFirstInDeclGroup(C))
4528 R.setBegin(VD->getLocation());
4529 }
4530 return R;
4531 }
4532 return SourceRange();
4533}
4534
4535/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4536/// the decl-specifier-seq for declarations.
4537static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4538 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004539 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 if (!D)
4541 return SourceRange();
4542
4543 SourceRange R = D->getSourceRange();
4544
4545 // Adjust the start of the location for declarations preceded by
4546 // declaration specifiers.
4547 SourceLocation StartLoc;
4548 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4549 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4550 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004551 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4553 StartLoc = TI->getTypeLoc().getLocStart();
4554 }
4555
4556 if (StartLoc.isValid() && R.getBegin().isValid() &&
4557 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4558 R.setBegin(StartLoc);
4559
4560 // FIXME: Multiple variables declared in a single declaration
4561 // currently lack the information needed to correctly determine their
4562 // ranges when accounting for the type-specifier. We use context
4563 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4564 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004565 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 if (!cxcursor::isFirstInDeclGroup(C))
4567 R.setBegin(VD->getLocation());
4568 }
4569
4570 return R;
4571 }
4572
4573 return getRawCursorExtent(C);
4574}
4575
4576extern "C" {
4577
4578CXSourceRange clang_getCursorExtent(CXCursor C) {
4579 SourceRange R = getRawCursorExtent(C);
4580 if (R.isInvalid())
4581 return clang_getNullRange();
4582
4583 return cxloc::translateSourceRange(getCursorContext(C), R);
4584}
4585
4586CXCursor clang_getCursorReferenced(CXCursor C) {
4587 if (clang_isInvalid(C.kind))
4588 return clang_getNullCursor();
4589
4590 CXTranslationUnit tu = getCursorTU(C);
4591 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004592 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 if (!D)
4594 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004595 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004597 if (const ObjCPropertyImplDecl *PropImpl =
4598 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4600 return MakeCXCursor(Property, tu);
4601
4602 return C;
4603 }
4604
4605 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004606 const Expr *E = getCursorExpr(C);
4607 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 if (D) {
4609 CXCursor declCursor = MakeCXCursor(D, tu);
4610 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4611 declCursor);
4612 return declCursor;
4613 }
4614
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004615 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 return MakeCursorOverloadedDeclRef(Ovl, tu);
4617
4618 return clang_getNullCursor();
4619 }
4620
4621 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004622 const Stmt *S = getCursorStmt(C);
4623 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 if (LabelDecl *label = Goto->getLabel())
4625 if (LabelStmt *labelS = label->getStmt())
4626 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4627
4628 return clang_getNullCursor();
4629 }
4630
4631 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004632 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 return MakeMacroDefinitionCursor(Def, tu);
4634 }
4635
4636 if (!clang_isReference(C.kind))
4637 return clang_getNullCursor();
4638
4639 switch (C.kind) {
4640 case CXCursor_ObjCSuperClassRef:
4641 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4642
4643 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004644 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4645 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 return MakeCXCursor(Def, tu);
4647
4648 return MakeCXCursor(Prot, tu);
4649 }
4650
4651 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004652 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4653 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 return MakeCXCursor(Def, tu);
4655
4656 return MakeCXCursor(Class, tu);
4657 }
4658
4659 case CXCursor_TypeRef:
4660 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4661
4662 case CXCursor_TemplateRef:
4663 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4664
4665 case CXCursor_NamespaceRef:
4666 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4667
4668 case CXCursor_MemberRef:
4669 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4670
4671 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004672 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4674 tu ));
4675 }
4676
4677 case CXCursor_LabelRef:
4678 // FIXME: We end up faking the "parent" declaration here because we
4679 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004680 return MakeCXCursor(getCursorLabelRef(C).first,
4681 cxtu::getASTUnit(tu)->getASTContext()
4682 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 tu);
4684
4685 case CXCursor_OverloadedDeclRef:
4686 return C;
4687
4688 case CXCursor_VariableRef:
4689 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4690
4691 default:
4692 // We would prefer to enumerate all non-reference cursor kinds here.
4693 llvm_unreachable("Unhandled reference cursor kind");
4694 }
4695}
4696
4697CXCursor clang_getCursorDefinition(CXCursor C) {
4698 if (clang_isInvalid(C.kind))
4699 return clang_getNullCursor();
4700
4701 CXTranslationUnit TU = getCursorTU(C);
4702
4703 bool WasReference = false;
4704 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4705 C = clang_getCursorReferenced(C);
4706 WasReference = true;
4707 }
4708
4709 if (C.kind == CXCursor_MacroExpansion)
4710 return clang_getCursorReferenced(C);
4711
4712 if (!clang_isDeclaration(C.kind))
4713 return clang_getNullCursor();
4714
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004715 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 if (!D)
4717 return clang_getNullCursor();
4718
4719 switch (D->getKind()) {
4720 // Declaration kinds that don't really separate the notions of
4721 // declaration and definition.
4722 case Decl::Namespace:
4723 case Decl::Typedef:
4724 case Decl::TypeAlias:
4725 case Decl::TypeAliasTemplate:
4726 case Decl::TemplateTypeParm:
4727 case Decl::EnumConstant:
4728 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004729 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 case Decl::IndirectField:
4731 case Decl::ObjCIvar:
4732 case Decl::ObjCAtDefsField:
4733 case Decl::ImplicitParam:
4734 case Decl::ParmVar:
4735 case Decl::NonTypeTemplateParm:
4736 case Decl::TemplateTemplateParm:
4737 case Decl::ObjCCategoryImpl:
4738 case Decl::ObjCImplementation:
4739 case Decl::AccessSpec:
4740 case Decl::LinkageSpec:
4741 case Decl::ObjCPropertyImpl:
4742 case Decl::FileScopeAsm:
4743 case Decl::StaticAssert:
4744 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004745 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 case Decl::Label: // FIXME: Is this right??
4747 case Decl::ClassScopeFunctionSpecialization:
4748 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004749 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 return C;
4751
4752 // Declaration kinds that don't make any sense here, but are
4753 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004754 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 case Decl::TranslationUnit:
4756 break;
4757
4758 // Declaration kinds for which the definition is not resolvable.
4759 case Decl::UnresolvedUsingTypename:
4760 case Decl::UnresolvedUsingValue:
4761 break;
4762
4763 case Decl::UsingDirective:
4764 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4765 TU);
4766
4767 case Decl::NamespaceAlias:
4768 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4769
4770 case Decl::Enum:
4771 case Decl::Record:
4772 case Decl::CXXRecord:
4773 case Decl::ClassTemplateSpecialization:
4774 case Decl::ClassTemplatePartialSpecialization:
4775 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4776 return MakeCXCursor(Def, TU);
4777 return clang_getNullCursor();
4778
4779 case Decl::Function:
4780 case Decl::CXXMethod:
4781 case Decl::CXXConstructor:
4782 case Decl::CXXDestructor:
4783 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004784 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004786 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return clang_getNullCursor();
4788 }
4789
Larisse Voufo39a1e502013-08-06 01:03:05 +00004790 case Decl::Var:
4791 case Decl::VarTemplateSpecialization:
4792 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004794 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 return MakeCXCursor(Def, TU);
4796 return clang_getNullCursor();
4797 }
4798
4799 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004800 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4802 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4803 return clang_getNullCursor();
4804 }
4805
4806 case Decl::ClassTemplate: {
4807 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4808 ->getDefinition())
4809 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4810 TU);
4811 return clang_getNullCursor();
4812 }
4813
Larisse Voufo39a1e502013-08-06 01:03:05 +00004814 case Decl::VarTemplate: {
4815 if (VarDecl *Def =
4816 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4817 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4818 return clang_getNullCursor();
4819 }
4820
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 case Decl::Using:
4822 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4823 D->getLocation(), TU);
4824
4825 case Decl::UsingShadow:
4826 return clang_getCursorDefinition(
4827 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4828 TU));
4829
4830 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 if (Method->isThisDeclarationADefinition())
4833 return C;
4834
4835 // Dig out the method definition in the associated
4836 // @implementation, if we have it.
4837 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004838 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4840 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4841 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4842 Method->isInstanceMethod()))
4843 if (Def->isThisDeclarationADefinition())
4844 return MakeCXCursor(Def, TU);
4845
4846 return clang_getNullCursor();
4847 }
4848
4849 case Decl::ObjCCategory:
4850 if (ObjCCategoryImplDecl *Impl
4851 = cast<ObjCCategoryDecl>(D)->getImplementation())
4852 return MakeCXCursor(Impl, TU);
4853 return clang_getNullCursor();
4854
4855 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 return MakeCXCursor(Def, TU);
4858 return clang_getNullCursor();
4859
4860 case Decl::ObjCInterface: {
4861 // There are two notions of a "definition" for an Objective-C
4862 // class: the interface and its implementation. When we resolved a
4863 // reference to an Objective-C class, produce the @interface as
4864 // the definition; when we were provided with the interface,
4865 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 return MakeCXCursor(Def, TU);
4870 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4871 return MakeCXCursor(Impl, TU);
4872 return clang_getNullCursor();
4873 }
4874
4875 case Decl::ObjCProperty:
4876 // FIXME: We don't really know where to find the
4877 // ObjCPropertyImplDecls that implement this property.
4878 return clang_getNullCursor();
4879
4880 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004881 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004882 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004883 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 return MakeCXCursor(Def, TU);
4885
4886 return clang_getNullCursor();
4887
4888 case Decl::Friend:
4889 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4890 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4891 return clang_getNullCursor();
4892
4893 case Decl::FriendTemplate:
4894 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4895 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4896 return clang_getNullCursor();
4897 }
4898
4899 return clang_getNullCursor();
4900}
4901
4902unsigned clang_isCursorDefinition(CXCursor C) {
4903 if (!clang_isDeclaration(C.kind))
4904 return 0;
4905
4906 return clang_getCursorDefinition(C) == C;
4907}
4908
4909CXCursor clang_getCanonicalCursor(CXCursor C) {
4910 if (!clang_isDeclaration(C.kind))
4911 return C;
4912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 if (const Decl *D = getCursorDecl(C)) {
4914 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4916 return MakeCXCursor(CatD, getCursorTU(C));
4917
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004918 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4919 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 return MakeCXCursor(IFD, getCursorTU(C));
4921
4922 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4923 }
4924
4925 return C;
4926}
4927
4928int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4929 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4930}
4931
4932unsigned clang_getNumOverloadedDecls(CXCursor C) {
4933 if (C.kind != CXCursor_OverloadedDeclRef)
4934 return 0;
4935
4936 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004937 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 return E->getNumDecls();
4939
4940 if (OverloadedTemplateStorage *S
4941 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4942 return S->size();
4943
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004944 const Decl *D = Storage.get<const Decl *>();
4945 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 return Using->shadow_size();
4947
4948 return 0;
4949}
4950
4951CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4952 if (cursor.kind != CXCursor_OverloadedDeclRef)
4953 return clang_getNullCursor();
4954
4955 if (index >= clang_getNumOverloadedDecls(cursor))
4956 return clang_getNullCursor();
4957
4958 CXTranslationUnit TU = getCursorTU(cursor);
4959 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004960 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 return MakeCXCursor(E->decls_begin()[index], TU);
4962
4963 if (OverloadedTemplateStorage *S
4964 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4965 return MakeCXCursor(S->begin()[index], TU);
4966
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004967 const Decl *D = Storage.get<const Decl *>();
4968 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 // FIXME: This is, unfortunately, linear time.
4970 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4971 std::advance(Pos, index);
4972 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4973 }
4974
4975 return clang_getNullCursor();
4976}
4977
4978void clang_getDefinitionSpellingAndExtent(CXCursor C,
4979 const char **startBuf,
4980 const char **endBuf,
4981 unsigned *startLine,
4982 unsigned *startColumn,
4983 unsigned *endLine,
4984 unsigned *endColumn) {
4985 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004986 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4988
4989 SourceManager &SM = FD->getASTContext().getSourceManager();
4990 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4991 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4992 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4993 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4994 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4995 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4996}
4997
4998
4999CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5000 unsigned PieceIndex) {
5001 RefNamePieces Pieces;
5002
5003 switch (C.kind) {
5004 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005005 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5007 E->getQualifierLoc().getSourceRange());
5008 break;
5009
5010 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005011 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5013 E->getQualifierLoc().getSourceRange(),
5014 E->getOptionalExplicitTemplateArgs());
5015 break;
5016
5017 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005018 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005020 const Expr *Callee = OCE->getCallee();
5021 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 Callee = ICE->getSubExpr();
5023
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005024 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5026 DRE->getQualifierLoc().getSourceRange());
5027 }
5028 break;
5029
5030 default:
5031 break;
5032 }
5033
5034 if (Pieces.empty()) {
5035 if (PieceIndex == 0)
5036 return clang_getCursorExtent(C);
5037 } else if (PieceIndex < Pieces.size()) {
5038 SourceRange R = Pieces[PieceIndex];
5039 if (R.isValid())
5040 return cxloc::translateSourceRange(getCursorContext(C), R);
5041 }
5042
5043 return clang_getNullRange();
5044}
5045
5046void clang_enableStackTraces(void) {
5047 llvm::sys::PrintStackTraceOnErrorSignal();
5048}
5049
5050void clang_executeOnThread(void (*fn)(void*), void *user_data,
5051 unsigned stack_size) {
5052 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5053}
5054
5055} // end: extern "C"
5056
5057//===----------------------------------------------------------------------===//
5058// Token-based Operations.
5059//===----------------------------------------------------------------------===//
5060
5061/* CXToken layout:
5062 * int_data[0]: a CXTokenKind
5063 * int_data[1]: starting token location
5064 * int_data[2]: token length
5065 * int_data[3]: reserved
5066 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5067 * otherwise unused.
5068 */
5069extern "C" {
5070
5071CXTokenKind clang_getTokenKind(CXToken CXTok) {
5072 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5073}
5074
5075CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5076 switch (clang_getTokenKind(CXTok)) {
5077 case CXToken_Identifier:
5078 case CXToken_Keyword:
5079 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005080 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 ->getNameStart());
5082
5083 case CXToken_Literal: {
5084 // We have stashed the starting pointer in the ptr_data field. Use it.
5085 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005086 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 }
5088
5089 case CXToken_Punctuation:
5090 case CXToken_Comment:
5091 break;
5092 }
5093
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005094 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005095 LOG_BAD_TU(TU);
5096 return cxstring::createEmpty();
5097 }
5098
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 // We have to find the starting buffer pointer the hard way, by
5100 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005101 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005103 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005104
5105 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5106 std::pair<FileID, unsigned> LocInfo
5107 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5108 bool Invalid = false;
5109 StringRef Buffer
5110 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5111 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005112 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005113
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005114 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005115}
5116
5117CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005118 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005119 LOG_BAD_TU(TU);
5120 return clang_getNullLocation();
5121 }
5122
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005123 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 if (!CXXUnit)
5125 return clang_getNullLocation();
5126
5127 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5128 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5129}
5130
5131CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005132 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005133 LOG_BAD_TU(TU);
5134 return clang_getNullRange();
5135 }
5136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005137 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 if (!CXXUnit)
5139 return clang_getNullRange();
5140
5141 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5142 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5143}
5144
5145static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5146 SmallVectorImpl<CXToken> &CXTokens) {
5147 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5148 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005149 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005151 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005152
5153 // Cannot tokenize across files.
5154 if (BeginLocInfo.first != EndLocInfo.first)
5155 return;
5156
5157 // Create a lexer
5158 bool Invalid = false;
5159 StringRef Buffer
5160 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5161 if (Invalid)
5162 return;
5163
5164 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5165 CXXUnit->getASTContext().getLangOpts(),
5166 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5167 Lex.SetCommentRetentionState(true);
5168
5169 // Lex tokens until we hit the end of the range.
5170 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5171 Token Tok;
5172 bool previousWasAt = false;
5173 do {
5174 // Lex the next token
5175 Lex.LexFromRawLexer(Tok);
5176 if (Tok.is(tok::eof))
5177 break;
5178
5179 // Initialize the CXToken.
5180 CXToken CXTok;
5181
5182 // - Common fields
5183 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5184 CXTok.int_data[2] = Tok.getLength();
5185 CXTok.int_data[3] = 0;
5186
5187 // - Kind-specific fields
5188 if (Tok.isLiteral()) {
5189 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005190 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 } else if (Tok.is(tok::raw_identifier)) {
5192 // Lookup the identifier to determine whether we have a keyword.
5193 IdentifierInfo *II
5194 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5195
5196 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5197 CXTok.int_data[0] = CXToken_Keyword;
5198 }
5199 else {
5200 CXTok.int_data[0] = Tok.is(tok::identifier)
5201 ? CXToken_Identifier
5202 : CXToken_Keyword;
5203 }
5204 CXTok.ptr_data = II;
5205 } else if (Tok.is(tok::comment)) {
5206 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005207 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 } else {
5209 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005210 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 }
5212 CXTokens.push_back(CXTok);
5213 previousWasAt = Tok.is(tok::at);
5214 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5215}
5216
5217void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5218 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005219 LOG_FUNC_SECTION {
5220 *Log << TU << ' ' << Range;
5221 }
5222
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005224 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 if (NumTokens)
5226 *NumTokens = 0;
5227
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005228 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005229 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005230 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005231 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005232
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005233 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 if (!CXXUnit || !Tokens || !NumTokens)
5235 return;
5236
5237 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5238
5239 SourceRange R = cxloc::translateCXSourceRange(Range);
5240 if (R.isInvalid())
5241 return;
5242
5243 SmallVector<CXToken, 32> CXTokens;
5244 getTokens(CXXUnit, R, CXTokens);
5245
5246 if (CXTokens.empty())
5247 return;
5248
5249 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5250 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5251 *NumTokens = CXTokens.size();
5252}
5253
5254void clang_disposeTokens(CXTranslationUnit TU,
5255 CXToken *Tokens, unsigned NumTokens) {
5256 free(Tokens);
5257}
5258
5259} // end: extern "C"
5260
5261//===----------------------------------------------------------------------===//
5262// Token annotation APIs.
5263//===----------------------------------------------------------------------===//
5264
Guy Benyei11169dd2012-12-18 14:30:41 +00005265static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5266 CXCursor parent,
5267 CXClientData client_data);
5268static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5269 CXClientData client_data);
5270
5271namespace {
5272class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 CXToken *Tokens;
5274 CXCursor *Cursors;
5275 unsigned NumTokens;
5276 unsigned TokIdx;
5277 unsigned PreprocessingTokIdx;
5278 CursorVisitor AnnotateVis;
5279 SourceManager &SrcMgr;
5280 bool HasContextSensitiveKeywords;
5281
5282 struct PostChildrenInfo {
5283 CXCursor Cursor;
5284 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005285 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 unsigned BeforeChildrenTokenIdx;
5287 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005288 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005289
5290 CXToken &getTok(unsigned Idx) {
5291 assert(Idx < NumTokens);
5292 return Tokens[Idx];
5293 }
5294 const CXToken &getTok(unsigned Idx) const {
5295 assert(Idx < NumTokens);
5296 return Tokens[Idx];
5297 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 bool MoreTokens() const { return TokIdx < NumTokens; }
5299 unsigned NextToken() const { return TokIdx; }
5300 void AdvanceToken() { ++TokIdx; }
5301 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005302 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 }
5304 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005305 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 }
5307 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005308 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 }
5310
5311 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005312 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 SourceRange);
5314
5315public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005316 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005317 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005318 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005319 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005320 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 AnnotateTokensVisitor, this,
5322 /*VisitPreprocessorLast=*/true,
5323 /*VisitIncludedEntities=*/false,
5324 RegionOfInterest,
5325 /*VisitDeclsOnly=*/false,
5326 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005327 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 HasContextSensitiveKeywords(false) { }
5329
5330 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5331 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5332 bool postVisitChildren(CXCursor cursor);
5333 void AnnotateTokens();
5334
5335 /// \brief Determine whether the annotator saw any cursors that have
5336 /// context-sensitive keywords.
5337 bool hasContextSensitiveKeywords() const {
5338 return HasContextSensitiveKeywords;
5339 }
5340
5341 ~AnnotateTokensWorker() {
5342 assert(PostChildrenInfos.empty());
5343 }
5344};
5345}
5346
5347void AnnotateTokensWorker::AnnotateTokens() {
5348 // Walk the AST within the region of interest, annotating tokens
5349 // along the way.
5350 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005351}
Guy Benyei11169dd2012-12-18 14:30:41 +00005352
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005353static inline void updateCursorAnnotation(CXCursor &Cursor,
5354 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005355 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005357 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005358}
5359
5360/// \brief It annotates and advances tokens with a cursor until the comparison
5361//// between the cursor location and the source range is the same as
5362/// \arg compResult.
5363///
5364/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5365/// Pass RangeOverlap to annotate tokens inside a range.
5366void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5367 RangeComparisonResult compResult,
5368 SourceRange range) {
5369 while (MoreTokens()) {
5370 const unsigned I = NextToken();
5371 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005372 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5373 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005374
5375 SourceLocation TokLoc = GetTokenLoc(I);
5376 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005377 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 AdvanceToken();
5379 continue;
5380 }
5381 break;
5382 }
5383}
5384
5385/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005386/// \returns true if it advanced beyond all macro tokens, false otherwise.
5387bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 CXCursor updateC,
5389 RangeComparisonResult compResult,
5390 SourceRange range) {
5391 assert(MoreTokens());
5392 assert(isFunctionMacroToken(NextToken()) &&
5393 "Should be called only for macro arg tokens");
5394
5395 // This works differently than annotateAndAdvanceTokens; because expanded
5396 // macro arguments can have arbitrary translation-unit source order, we do not
5397 // advance the token index one by one until a token fails the range test.
5398 // We only advance once past all of the macro arg tokens if all of them
5399 // pass the range test. If one of them fails we keep the token index pointing
5400 // at the start of the macro arg tokens so that the failing token will be
5401 // annotated by a subsequent annotation try.
5402
5403 bool atLeastOneCompFail = false;
5404
5405 unsigned I = NextToken();
5406 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5407 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5408 if (TokLoc.isFileID())
5409 continue; // not macro arg token, it's parens or comma.
5410 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5411 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5412 Cursors[I] = updateC;
5413 } else
5414 atLeastOneCompFail = true;
5415 }
5416
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005417 if (atLeastOneCompFail)
5418 return false;
5419
5420 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5421 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005422}
5423
5424enum CXChildVisitResult
5425AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 SourceRange cursorRange = getRawCursorExtent(cursor);
5427 if (cursorRange.isInvalid())
5428 return CXChildVisit_Recurse;
5429
5430 if (!HasContextSensitiveKeywords) {
5431 // Objective-C properties can have context-sensitive keywords.
5432 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005433 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5435 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5436 }
5437 // Objective-C methods can have context-sensitive keywords.
5438 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5439 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005440 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5442 if (Method->getObjCDeclQualifier())
5443 HasContextSensitiveKeywords = true;
5444 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005445 for (const auto *P : Method->params()) {
5446 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 HasContextSensitiveKeywords = true;
5448 break;
5449 }
5450 }
5451 }
5452 }
5453 }
5454 // C++ methods can have context-sensitive keywords.
5455 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005456 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5458 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5459 HasContextSensitiveKeywords = true;
5460 }
5461 }
5462 // C++ classes can have context-sensitive keywords.
5463 else if (cursor.kind == CXCursor_StructDecl ||
5464 cursor.kind == CXCursor_ClassDecl ||
5465 cursor.kind == CXCursor_ClassTemplate ||
5466 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005467 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 if (D->hasAttr<FinalAttr>())
5469 HasContextSensitiveKeywords = true;
5470 }
5471 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005472
5473 // Don't override a property annotation with its getter/setter method.
5474 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5475 parent.kind == CXCursor_ObjCPropertyDecl)
5476 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005477
5478 if (clang_isPreprocessing(cursor.kind)) {
5479 // Items in the preprocessing record are kept separate from items in
5480 // declarations, so we keep a separate token index.
5481 unsigned SavedTokIdx = TokIdx;
5482 TokIdx = PreprocessingTokIdx;
5483
5484 // Skip tokens up until we catch up to the beginning of the preprocessing
5485 // entry.
5486 while (MoreTokens()) {
5487 const unsigned I = NextToken();
5488 SourceLocation TokLoc = GetTokenLoc(I);
5489 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5490 case RangeBefore:
5491 AdvanceToken();
5492 continue;
5493 case RangeAfter:
5494 case RangeOverlap:
5495 break;
5496 }
5497 break;
5498 }
5499
5500 // Look at all of the tokens within this range.
5501 while (MoreTokens()) {
5502 const unsigned I = NextToken();
5503 SourceLocation TokLoc = GetTokenLoc(I);
5504 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5505 case RangeBefore:
5506 llvm_unreachable("Infeasible");
5507 case RangeAfter:
5508 break;
5509 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005510 // For macro expansions, just note where the beginning of the macro
5511 // expansion occurs.
5512 if (cursor.kind == CXCursor_MacroExpansion) {
5513 if (TokLoc == cursorRange.getBegin())
5514 Cursors[I] = cursor;
5515 AdvanceToken();
5516 break;
5517 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005518 // We may have already annotated macro names inside macro definitions.
5519 if (Cursors[I].kind != CXCursor_MacroExpansion)
5520 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 continue;
5523 }
5524 break;
5525 }
5526
5527 // Save the preprocessing token index; restore the non-preprocessing
5528 // token index.
5529 PreprocessingTokIdx = TokIdx;
5530 TokIdx = SavedTokIdx;
5531 return CXChildVisit_Recurse;
5532 }
5533
5534 if (cursorRange.isInvalid())
5535 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005536
5537 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005539 const enum CXCursorKind K = clang_getCursorKind(parent);
5540 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005541 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5542 // Attributes are annotated out-of-order, skip tokens until we reach it.
5543 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 ? clang_getNullCursor() : parent;
5545
5546 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5547
5548 // Avoid having the cursor of an expression "overwrite" the annotation of the
5549 // variable declaration that it belongs to.
5550 // This can happen for C++ constructor expressions whose range generally
5551 // include the variable declaration, e.g.:
5552 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005553 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005554 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005555 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 const unsigned I = NextToken();
5557 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5558 E->getLocStart() == D->getLocation() &&
5559 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005560 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 AdvanceToken();
5562 }
5563 }
5564 }
5565
5566 // Before recursing into the children keep some state that we are going
5567 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5568 // extra work after the child nodes are visited.
5569 // Note that we don't call VisitChildren here to avoid traversing statements
5570 // code-recursively which can blow the stack.
5571
5572 PostChildrenInfo Info;
5573 Info.Cursor = cursor;
5574 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005575 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005576 Info.BeforeChildrenTokenIdx = NextToken();
5577 PostChildrenInfos.push_back(Info);
5578
5579 return CXChildVisit_Recurse;
5580}
5581
5582bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5583 if (PostChildrenInfos.empty())
5584 return false;
5585 const PostChildrenInfo &Info = PostChildrenInfos.back();
5586 if (!clang_equalCursors(Info.Cursor, cursor))
5587 return false;
5588
5589 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5590 const unsigned AfterChildren = NextToken();
5591 SourceRange cursorRange = Info.CursorRange;
5592
5593 // Scan the tokens that are at the end of the cursor, but are not captured
5594 // but the child cursors.
5595 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5596
5597 // Scan the tokens that are at the beginning of the cursor, but are not
5598 // capture by the child cursors.
5599 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5600 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5601 break;
5602
5603 Cursors[I] = cursor;
5604 }
5605
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005606 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5607 // encountered the attribute cursor.
5608 if (clang_isAttribute(cursor.kind))
5609 TokIdx = Info.BeforeReachingCursorIdx;
5610
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 PostChildrenInfos.pop_back();
5612 return false;
5613}
5614
5615static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5616 CXCursor parent,
5617 CXClientData client_data) {
5618 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5619}
5620
5621static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5622 CXClientData client_data) {
5623 return static_cast<AnnotateTokensWorker*>(client_data)->
5624 postVisitChildren(cursor);
5625}
5626
5627namespace {
5628
5629/// \brief Uses the macro expansions in the preprocessing record to find
5630/// and mark tokens that are macro arguments. This info is used by the
5631/// AnnotateTokensWorker.
5632class MarkMacroArgTokensVisitor {
5633 SourceManager &SM;
5634 CXToken *Tokens;
5635 unsigned NumTokens;
5636 unsigned CurIdx;
5637
5638public:
5639 MarkMacroArgTokensVisitor(SourceManager &SM,
5640 CXToken *tokens, unsigned numTokens)
5641 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5642
5643 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5644 if (cursor.kind != CXCursor_MacroExpansion)
5645 return CXChildVisit_Continue;
5646
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005647 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 if (macroRange.getBegin() == macroRange.getEnd())
5649 return CXChildVisit_Continue; // it's not a function macro.
5650
5651 for (; CurIdx < NumTokens; ++CurIdx) {
5652 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5653 macroRange.getBegin()))
5654 break;
5655 }
5656
5657 if (CurIdx == NumTokens)
5658 return CXChildVisit_Break;
5659
5660 for (; CurIdx < NumTokens; ++CurIdx) {
5661 SourceLocation tokLoc = getTokenLoc(CurIdx);
5662 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5663 break;
5664
5665 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5666 }
5667
5668 if (CurIdx == NumTokens)
5669 return CXChildVisit_Break;
5670
5671 return CXChildVisit_Continue;
5672 }
5673
5674private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005675 CXToken &getTok(unsigned Idx) {
5676 assert(Idx < NumTokens);
5677 return Tokens[Idx];
5678 }
5679 const CXToken &getTok(unsigned Idx) const {
5680 assert(Idx < NumTokens);
5681 return Tokens[Idx];
5682 }
5683
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005685 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 }
5687
5688 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5689 // The third field is reserved and currently not used. Use it here
5690 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005691 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 }
5693};
5694
5695} // end anonymous namespace
5696
5697static CXChildVisitResult
5698MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5699 CXClientData client_data) {
5700 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5701 parent);
5702}
5703
5704namespace {
5705 struct clang_annotateTokens_Data {
5706 CXTranslationUnit TU;
5707 ASTUnit *CXXUnit;
5708 CXToken *Tokens;
5709 unsigned NumTokens;
5710 CXCursor *Cursors;
5711 };
5712}
5713
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714/// \brief Used by \c annotatePreprocessorTokens.
5715/// \returns true if lexing was finished, false otherwise.
5716static bool lexNext(Lexer &Lex, Token &Tok,
5717 unsigned &NextIdx, unsigned NumTokens) {
5718 if (NextIdx >= NumTokens)
5719 return true;
5720
5721 ++NextIdx;
5722 Lex.LexFromRawLexer(Tok);
5723 if (Tok.is(tok::eof))
5724 return true;
5725
5726 return false;
5727}
5728
Guy Benyei11169dd2012-12-18 14:30:41 +00005729static void annotatePreprocessorTokens(CXTranslationUnit TU,
5730 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005731 CXCursor *Cursors,
5732 CXToken *Tokens,
5733 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005734 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005735
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005736 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5738 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005739 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005741 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005742
5743 if (BeginLocInfo.first != EndLocInfo.first)
5744 return;
5745
5746 StringRef Buffer;
5747 bool Invalid = false;
5748 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5749 if (Buffer.empty() || Invalid)
5750 return;
5751
5752 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5753 CXXUnit->getASTContext().getLangOpts(),
5754 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5755 Buffer.end());
5756 Lex.SetCommentRetentionState(true);
5757
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 // Lex tokens in raw mode until we hit the end of the range, to avoid
5760 // entering #includes or expanding macros.
5761 while (true) {
5762 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005763 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5764 break;
5765 unsigned TokIdx = NextIdx-1;
5766 assert(Tok.getLocation() ==
5767 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005768
5769 reprocess:
5770 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005771 // We have found a preprocessing directive. Annotate the tokens
5772 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 //
5774 // FIXME: Some simple tests here could identify macro definitions and
5775 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005776
5777 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005778 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5779 break;
5780
Craig Topper69186e72014-06-08 08:38:04 +00005781 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005782 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005783 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5784 break;
5785
5786 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005787 IdentifierInfo &II =
5788 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005789 SourceLocation MappedTokLoc =
5790 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5791 MI = getMacroInfo(II, MappedTokLoc, TU);
5792 }
5793 }
5794
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005795 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005797 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5798 finished = true;
5799 break;
5800 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005801 // If we are in a macro definition, check if the token was ever a
5802 // macro name and annotate it if that's the case.
5803 if (MI) {
5804 SourceLocation SaveLoc = Tok.getLocation();
5805 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5806 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5807 Tok.setLocation(SaveLoc);
5808 if (MacroDef)
5809 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5810 Tok.getLocation(), TU);
5811 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005812 } while (!Tok.isAtStartOfLine());
5813
5814 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5815 assert(TokIdx <= LastIdx);
5816 SourceLocation EndLoc =
5817 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5818 CXCursor Cursor =
5819 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5820
5821 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005822 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005823
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005824 if (finished)
5825 break;
5826 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005827 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 }
5829}
5830
5831// This gets run a separate thread to avoid stack blowout.
5832static void clang_annotateTokensImpl(void *UserData) {
5833 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5834 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5835 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5836 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5837 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5838
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005839 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005840 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5841 setThreadBackgroundPriority();
5842
5843 // Determine the region of interest, which contains all of the tokens.
5844 SourceRange RegionOfInterest;
5845 RegionOfInterest.setBegin(
5846 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5847 RegionOfInterest.setEnd(
5848 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5849 Tokens[NumTokens-1])));
5850
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 // Relex the tokens within the source range to look for preprocessing
5852 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005853 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005854
5855 // If begin location points inside a macro argument, set it to the expansion
5856 // location so we can have the full context when annotating semantically.
5857 {
5858 SourceManager &SM = CXXUnit->getSourceManager();
5859 SourceLocation Loc =
5860 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5861 if (Loc.isMacroID())
5862 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5863 }
5864
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5866 // Search and mark tokens that are macro argument expansions.
5867 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5868 Tokens, NumTokens);
5869 CursorVisitor MacroArgMarker(TU,
5870 MarkMacroArgTokensVisitorDelegate, &Visitor,
5871 /*VisitPreprocessorLast=*/true,
5872 /*VisitIncludedEntities=*/false,
5873 RegionOfInterest);
5874 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5875 }
5876
5877 // Annotate all of the source locations in the region of interest that map to
5878 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005879 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005880
5881 // FIXME: We use a ridiculous stack size here because the data-recursion
5882 // algorithm uses a large stack frame than the non-data recursive version,
5883 // and AnnotationTokensWorker currently transforms the data-recursion
5884 // algorithm back into a traditional recursion by explicitly calling
5885 // VisitChildren(). We will need to remove this explicit recursive call.
5886 W.AnnotateTokens();
5887
5888 // If we ran into any entities that involve context-sensitive keywords,
5889 // take another pass through the tokens to mark them as such.
5890 if (W.hasContextSensitiveKeywords()) {
5891 for (unsigned I = 0; I != NumTokens; ++I) {
5892 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5893 continue;
5894
5895 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5896 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005897 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5899 if (Property->getPropertyAttributesAsWritten() != 0 &&
5900 llvm::StringSwitch<bool>(II->getName())
5901 .Case("readonly", true)
5902 .Case("assign", true)
5903 .Case("unsafe_unretained", true)
5904 .Case("readwrite", true)
5905 .Case("retain", true)
5906 .Case("copy", true)
5907 .Case("nonatomic", true)
5908 .Case("atomic", true)
5909 .Case("getter", true)
5910 .Case("setter", true)
5911 .Case("strong", true)
5912 .Case("weak", true)
5913 .Default(false))
5914 Tokens[I].int_data[0] = CXToken_Keyword;
5915 }
5916 continue;
5917 }
5918
5919 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5920 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5921 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5922 if (llvm::StringSwitch<bool>(II->getName())
5923 .Case("in", true)
5924 .Case("out", true)
5925 .Case("inout", true)
5926 .Case("oneway", true)
5927 .Case("bycopy", true)
5928 .Case("byref", true)
5929 .Default(false))
5930 Tokens[I].int_data[0] = CXToken_Keyword;
5931 continue;
5932 }
5933
5934 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5935 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5936 Tokens[I].int_data[0] = CXToken_Keyword;
5937 continue;
5938 }
5939 }
5940 }
5941}
5942
5943extern "C" {
5944
5945void clang_annotateTokens(CXTranslationUnit TU,
5946 CXToken *Tokens, unsigned NumTokens,
5947 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005948 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005949 LOG_BAD_TU(TU);
5950 return;
5951 }
5952 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005953 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005954 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005955 }
5956
5957 LOG_FUNC_SECTION {
5958 *Log << TU << ' ';
5959 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5960 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5961 *Log << clang_getRange(bloc, eloc);
5962 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005963
5964 // Any token we don't specifically annotate will have a NULL cursor.
5965 CXCursor C = clang_getNullCursor();
5966 for (unsigned I = 0; I != NumTokens; ++I)
5967 Cursors[I] = C;
5968
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005969 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 if (!CXXUnit)
5971 return;
5972
5973 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5974
5975 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5976 llvm::CrashRecoveryContext CRC;
5977 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5978 GetSafetyThreadStackSize() * 2)) {
5979 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5980 }
5981}
5982
5983} // end: extern "C"
5984
5985//===----------------------------------------------------------------------===//
5986// Operations for querying linkage of a cursor.
5987//===----------------------------------------------------------------------===//
5988
5989extern "C" {
5990CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5991 if (!clang_isDeclaration(cursor.kind))
5992 return CXLinkage_Invalid;
5993
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005994 const Decl *D = cxcursor::getCursorDecl(cursor);
5995 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005996 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005997 case NoLinkage:
5998 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005999 case InternalLinkage: return CXLinkage_Internal;
6000 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6001 case ExternalLinkage: return CXLinkage_External;
6002 };
6003
6004 return CXLinkage_Invalid;
6005}
6006} // end: extern "C"
6007
6008//===----------------------------------------------------------------------===//
6009// Operations for querying language of a cursor.
6010//===----------------------------------------------------------------------===//
6011
6012static CXLanguageKind getDeclLanguage(const Decl *D) {
6013 if (!D)
6014 return CXLanguage_C;
6015
6016 switch (D->getKind()) {
6017 default:
6018 break;
6019 case Decl::ImplicitParam:
6020 case Decl::ObjCAtDefsField:
6021 case Decl::ObjCCategory:
6022 case Decl::ObjCCategoryImpl:
6023 case Decl::ObjCCompatibleAlias:
6024 case Decl::ObjCImplementation:
6025 case Decl::ObjCInterface:
6026 case Decl::ObjCIvar:
6027 case Decl::ObjCMethod:
6028 case Decl::ObjCProperty:
6029 case Decl::ObjCPropertyImpl:
6030 case Decl::ObjCProtocol:
6031 return CXLanguage_ObjC;
6032 case Decl::CXXConstructor:
6033 case Decl::CXXConversion:
6034 case Decl::CXXDestructor:
6035 case Decl::CXXMethod:
6036 case Decl::CXXRecord:
6037 case Decl::ClassTemplate:
6038 case Decl::ClassTemplatePartialSpecialization:
6039 case Decl::ClassTemplateSpecialization:
6040 case Decl::Friend:
6041 case Decl::FriendTemplate:
6042 case Decl::FunctionTemplate:
6043 case Decl::LinkageSpec:
6044 case Decl::Namespace:
6045 case Decl::NamespaceAlias:
6046 case Decl::NonTypeTemplateParm:
6047 case Decl::StaticAssert:
6048 case Decl::TemplateTemplateParm:
6049 case Decl::TemplateTypeParm:
6050 case Decl::UnresolvedUsingTypename:
6051 case Decl::UnresolvedUsingValue:
6052 case Decl::Using:
6053 case Decl::UsingDirective:
6054 case Decl::UsingShadow:
6055 return CXLanguage_CPlusPlus;
6056 }
6057
6058 return CXLanguage_C;
6059}
6060
6061extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006062
6063static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6064 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6065 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006066
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006067 switch (D->getAvailability()) {
6068 case AR_Available:
6069 case AR_NotYetIntroduced:
6070 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006071 return getCursorAvailabilityForDecl(
6072 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006073 return CXAvailability_Available;
6074
6075 case AR_Deprecated:
6076 return CXAvailability_Deprecated;
6077
6078 case AR_Unavailable:
6079 return CXAvailability_NotAvailable;
6080 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006081
6082 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006083}
6084
Guy Benyei11169dd2012-12-18 14:30:41 +00006085enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6086 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6088 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006089
6090 return CXAvailability_Available;
6091}
6092
6093static CXVersion convertVersion(VersionTuple In) {
6094 CXVersion Out = { -1, -1, -1 };
6095 if (In.empty())
6096 return Out;
6097
6098 Out.Major = In.getMajor();
6099
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006100 Optional<unsigned> Minor = In.getMinor();
6101 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006102 Out.Minor = *Minor;
6103 else
6104 return Out;
6105
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006106 Optional<unsigned> Subminor = In.getSubminor();
6107 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 Out.Subminor = *Subminor;
6109
6110 return Out;
6111}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006112
6113static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6114 int *always_deprecated,
6115 CXString *deprecated_message,
6116 int *always_unavailable,
6117 CXString *unavailable_message,
6118 CXPlatformAvailability *availability,
6119 int availability_size) {
6120 bool HadAvailAttr = false;
6121 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006122 for (auto A : D->attrs()) {
6123 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006124 HadAvailAttr = true;
6125 if (always_deprecated)
6126 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006127 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006128 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006129 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006130 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006131 continue;
6132 }
6133
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006134 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006135 HadAvailAttr = true;
6136 if (always_unavailable)
6137 *always_unavailable = 1;
6138 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006139 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006140 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6141 }
6142 continue;
6143 }
6144
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006145 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006146 HadAvailAttr = true;
6147 if (N < availability_size) {
6148 availability[N].Platform
6149 = cxstring::createDup(Avail->getPlatform()->getName());
6150 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6151 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6152 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6153 availability[N].Unavailable = Avail->getUnavailable();
6154 availability[N].Message = cxstring::createDup(Avail->getMessage());
6155 }
6156 ++N;
6157 }
6158 }
6159
6160 if (!HadAvailAttr)
6161 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6162 return getCursorPlatformAvailabilityForDecl(
6163 cast<Decl>(EnumConst->getDeclContext()),
6164 always_deprecated,
6165 deprecated_message,
6166 always_unavailable,
6167 unavailable_message,
6168 availability,
6169 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006170
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006171 return N;
6172}
6173
Guy Benyei11169dd2012-12-18 14:30:41 +00006174int clang_getCursorPlatformAvailability(CXCursor cursor,
6175 int *always_deprecated,
6176 CXString *deprecated_message,
6177 int *always_unavailable,
6178 CXString *unavailable_message,
6179 CXPlatformAvailability *availability,
6180 int availability_size) {
6181 if (always_deprecated)
6182 *always_deprecated = 0;
6183 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006184 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006185 if (always_unavailable)
6186 *always_unavailable = 0;
6187 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006188 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006189
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (!clang_isDeclaration(cursor.kind))
6191 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006193 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 if (!D)
6195 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006196
6197 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6198 deprecated_message,
6199 always_unavailable,
6200 unavailable_message,
6201 availability,
6202 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006203}
6204
6205void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6206 clang_disposeString(availability->Platform);
6207 clang_disposeString(availability->Message);
6208}
6209
6210CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6211 if (clang_isDeclaration(cursor.kind))
6212 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6213
6214 return CXLanguage_Invalid;
6215}
6216
6217 /// \brief If the given cursor is the "templated" declaration
6218 /// descibing a class or function template, return the class or
6219 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006220static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006222 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006223
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006224 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006225 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6226 return FunTmpl;
6227
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006228 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006229 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6230 return ClassTmpl;
6231
6232 return D;
6233}
6234
6235CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6236 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006237 if (const Decl *D = getCursorDecl(cursor)) {
6238 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 if (!DC)
6240 return clang_getNullCursor();
6241
6242 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6243 getCursorTU(cursor));
6244 }
6245 }
6246
6247 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006248 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 return MakeCXCursor(D, getCursorTU(cursor));
6250 }
6251
6252 return clang_getNullCursor();
6253}
6254
6255CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6256 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006257 if (const Decl *D = getCursorDecl(cursor)) {
6258 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006259 if (!DC)
6260 return clang_getNullCursor();
6261
6262 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6263 getCursorTU(cursor));
6264 }
6265 }
6266
6267 // FIXME: Note that we can't easily compute the lexical context of a
6268 // statement or expression, so we return nothing.
6269 return clang_getNullCursor();
6270}
6271
6272CXFile clang_getIncludedFile(CXCursor cursor) {
6273 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006274 return nullptr;
6275
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006276 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006277 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006278}
6279
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006280unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6281 if (C.kind != CXCursor_ObjCPropertyDecl)
6282 return CXObjCPropertyAttr_noattr;
6283
6284 unsigned Result = CXObjCPropertyAttr_noattr;
6285 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6286 ObjCPropertyDecl::PropertyAttributeKind Attr =
6287 PD->getPropertyAttributesAsWritten();
6288
6289#define SET_CXOBJCPROP_ATTR(A) \
6290 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6291 Result |= CXObjCPropertyAttr_##A
6292 SET_CXOBJCPROP_ATTR(readonly);
6293 SET_CXOBJCPROP_ATTR(getter);
6294 SET_CXOBJCPROP_ATTR(assign);
6295 SET_CXOBJCPROP_ATTR(readwrite);
6296 SET_CXOBJCPROP_ATTR(retain);
6297 SET_CXOBJCPROP_ATTR(copy);
6298 SET_CXOBJCPROP_ATTR(nonatomic);
6299 SET_CXOBJCPROP_ATTR(setter);
6300 SET_CXOBJCPROP_ATTR(atomic);
6301 SET_CXOBJCPROP_ATTR(weak);
6302 SET_CXOBJCPROP_ATTR(strong);
6303 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6304#undef SET_CXOBJCPROP_ATTR
6305
6306 return Result;
6307}
6308
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006309unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6310 if (!clang_isDeclaration(C.kind))
6311 return CXObjCDeclQualifier_None;
6312
6313 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6314 const Decl *D = getCursorDecl(C);
6315 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6316 QT = MD->getObjCDeclQualifier();
6317 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6318 QT = PD->getObjCDeclQualifier();
6319 if (QT == Decl::OBJC_TQ_None)
6320 return CXObjCDeclQualifier_None;
6321
6322 unsigned Result = CXObjCDeclQualifier_None;
6323 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6324 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6325 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6326 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6327 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6328 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6329
6330 return Result;
6331}
6332
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006333unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6334 if (!clang_isDeclaration(C.kind))
6335 return 0;
6336
6337 const Decl *D = getCursorDecl(C);
6338 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6339 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6340 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6341 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6342
6343 return 0;
6344}
6345
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006346unsigned clang_Cursor_isVariadic(CXCursor C) {
6347 if (!clang_isDeclaration(C.kind))
6348 return 0;
6349
6350 const Decl *D = getCursorDecl(C);
6351 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6352 return FD->isVariadic();
6353 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6354 return MD->isVariadic();
6355
6356 return 0;
6357}
6358
Guy Benyei11169dd2012-12-18 14:30:41 +00006359CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6360 if (!clang_isDeclaration(C.kind))
6361 return clang_getNullRange();
6362
6363 const Decl *D = getCursorDecl(C);
6364 ASTContext &Context = getCursorContext(C);
6365 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6366 if (!RC)
6367 return clang_getNullRange();
6368
6369 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6370}
6371
6372CXString clang_Cursor_getRawCommentText(CXCursor C) {
6373 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006374 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375
6376 const Decl *D = getCursorDecl(C);
6377 ASTContext &Context = getCursorContext(C);
6378 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6379 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6380 StringRef();
6381
6382 // Don't duplicate the string because RawText points directly into source
6383 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006384 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006385}
6386
6387CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6388 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006389 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006390
6391 const Decl *D = getCursorDecl(C);
6392 const ASTContext &Context = getCursorContext(C);
6393 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6394
6395 if (RC) {
6396 StringRef BriefText = RC->getBriefText(Context);
6397
6398 // Don't duplicate the string because RawComment ensures that this memory
6399 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006400 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 }
6402
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006403 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006404}
6405
Guy Benyei11169dd2012-12-18 14:30:41 +00006406CXModule clang_Cursor_getModule(CXCursor C) {
6407 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006408 if (const ImportDecl *ImportD =
6409 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006410 return ImportD->getImportedModule();
6411 }
6412
Craig Topper69186e72014-06-08 08:38:04 +00006413 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006414}
6415
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006416CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6417 if (isNotUsableTU(TU)) {
6418 LOG_BAD_TU(TU);
6419 return nullptr;
6420 }
6421 if (!File)
6422 return nullptr;
6423 FileEntry *FE = static_cast<FileEntry *>(File);
6424
6425 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6426 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6427 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6428
6429 if (Module *Mod = Header.getModule()) {
6430 if (Header.getRole() != ModuleMap::ExcludedHeader)
6431 return Mod;
6432 }
6433 return nullptr;
6434}
6435
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006436CXFile clang_Module_getASTFile(CXModule CXMod) {
6437 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006438 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006439 Module *Mod = static_cast<Module*>(CXMod);
6440 return const_cast<FileEntry *>(Mod->getASTFile());
6441}
6442
Guy Benyei11169dd2012-12-18 14:30:41 +00006443CXModule clang_Module_getParent(CXModule CXMod) {
6444 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006445 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 Module *Mod = static_cast<Module*>(CXMod);
6447 return Mod->Parent;
6448}
6449
6450CXString clang_Module_getName(CXModule CXMod) {
6451 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006452 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006454 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006455}
6456
6457CXString clang_Module_getFullName(CXModule CXMod) {
6458 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006459 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006461 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006462}
6463
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006464int clang_Module_isSystem(CXModule CXMod) {
6465 if (!CXMod)
6466 return 0;
6467 Module *Mod = static_cast<Module*>(CXMod);
6468 return Mod->IsSystem;
6469}
6470
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006471unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6472 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006473 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006474 LOG_BAD_TU(TU);
6475 return 0;
6476 }
6477 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 return 0;
6479 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006480 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6481 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6482 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006483}
6484
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006485CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6486 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006487 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006488 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006489 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006490 }
6491 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006492 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006494 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006495
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006496 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6497 if (Index < TopHeaders.size())
6498 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006499
Craig Topper69186e72014-06-08 08:38:04 +00006500 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006501}
6502
6503} // end: extern "C"
6504
6505//===----------------------------------------------------------------------===//
6506// C++ AST instrospection.
6507//===----------------------------------------------------------------------===//
6508
6509extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006510unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6511 if (!clang_isDeclaration(C.kind))
6512 return 0;
6513
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006514 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006515 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006516 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006517 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6518}
6519
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006520unsigned clang_CXXMethod_isConst(CXCursor C) {
6521 if (!clang_isDeclaration(C.kind))
6522 return 0;
6523
6524 const Decl *D = cxcursor::getCursorDecl(C);
6525 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006526 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006527 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6528}
6529
Guy Benyei11169dd2012-12-18 14:30:41 +00006530unsigned clang_CXXMethod_isStatic(CXCursor C) {
6531 if (!clang_isDeclaration(C.kind))
6532 return 0;
6533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006534 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006535 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006536 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 return (Method && Method->isStatic()) ? 1 : 0;
6538}
6539
6540unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6541 if (!clang_isDeclaration(C.kind))
6542 return 0;
6543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006544 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006545 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006546 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006547 return (Method && Method->isVirtual()) ? 1 : 0;
6548}
6549} // end: extern "C"
6550
6551//===----------------------------------------------------------------------===//
6552// Attribute introspection.
6553//===----------------------------------------------------------------------===//
6554
6555extern "C" {
6556CXType clang_getIBOutletCollectionType(CXCursor C) {
6557 if (C.kind != CXCursor_IBOutletCollectionAttr)
6558 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6559
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006560 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006561 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6562
6563 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6564}
6565} // end: extern "C"
6566
6567//===----------------------------------------------------------------------===//
6568// Inspecting memory usage.
6569//===----------------------------------------------------------------------===//
6570
6571typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6572
6573static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6574 enum CXTUResourceUsageKind k,
6575 unsigned long amount) {
6576 CXTUResourceUsageEntry entry = { k, amount };
6577 entries.push_back(entry);
6578}
6579
6580extern "C" {
6581
6582const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6583 const char *str = "";
6584 switch (kind) {
6585 case CXTUResourceUsage_AST:
6586 str = "ASTContext: expressions, declarations, and types";
6587 break;
6588 case CXTUResourceUsage_Identifiers:
6589 str = "ASTContext: identifiers";
6590 break;
6591 case CXTUResourceUsage_Selectors:
6592 str = "ASTContext: selectors";
6593 break;
6594 case CXTUResourceUsage_GlobalCompletionResults:
6595 str = "Code completion: cached global results";
6596 break;
6597 case CXTUResourceUsage_SourceManagerContentCache:
6598 str = "SourceManager: content cache allocator";
6599 break;
6600 case CXTUResourceUsage_AST_SideTables:
6601 str = "ASTContext: side tables";
6602 break;
6603 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6604 str = "SourceManager: malloc'ed memory buffers";
6605 break;
6606 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6607 str = "SourceManager: mmap'ed memory buffers";
6608 break;
6609 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6610 str = "ExternalASTSource: malloc'ed memory buffers";
6611 break;
6612 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6613 str = "ExternalASTSource: mmap'ed memory buffers";
6614 break;
6615 case CXTUResourceUsage_Preprocessor:
6616 str = "Preprocessor: malloc'ed memory";
6617 break;
6618 case CXTUResourceUsage_PreprocessingRecord:
6619 str = "Preprocessor: PreprocessingRecord";
6620 break;
6621 case CXTUResourceUsage_SourceManager_DataStructures:
6622 str = "SourceManager: data structures and tables";
6623 break;
6624 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6625 str = "Preprocessor: header search tables";
6626 break;
6627 }
6628 return str;
6629}
6630
6631CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006632 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006633 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006634 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006635 return usage;
6636 }
6637
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006638 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006639 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006640 ASTContext &astContext = astUnit->getASTContext();
6641
6642 // How much memory is used by AST nodes and types?
6643 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6644 (unsigned long) astContext.getASTAllocatedMemory());
6645
6646 // How much memory is used by identifiers?
6647 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6648 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6649
6650 // How much memory is used for selectors?
6651 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6652 (unsigned long) astContext.Selectors.getTotalMemory());
6653
6654 // How much memory is used by ASTContext's side tables?
6655 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6656 (unsigned long) astContext.getSideTableAllocatedMemory());
6657
6658 // How much memory is used for caching global code completion results?
6659 unsigned long completionBytes = 0;
6660 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006661 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006662 completionBytes = completionAllocator->getTotalMemory();
6663 }
6664 createCXTUResourceUsageEntry(*entries,
6665 CXTUResourceUsage_GlobalCompletionResults,
6666 completionBytes);
6667
6668 // How much memory is being used by SourceManager's content cache?
6669 createCXTUResourceUsageEntry(*entries,
6670 CXTUResourceUsage_SourceManagerContentCache,
6671 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6672
6673 // How much memory is being used by the MemoryBuffer's in SourceManager?
6674 const SourceManager::MemoryBufferSizes &srcBufs =
6675 astUnit->getSourceManager().getMemoryBufferSizes();
6676
6677 createCXTUResourceUsageEntry(*entries,
6678 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6679 (unsigned long) srcBufs.malloc_bytes);
6680 createCXTUResourceUsageEntry(*entries,
6681 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6682 (unsigned long) srcBufs.mmap_bytes);
6683 createCXTUResourceUsageEntry(*entries,
6684 CXTUResourceUsage_SourceManager_DataStructures,
6685 (unsigned long) astContext.getSourceManager()
6686 .getDataStructureSizes());
6687
6688 // How much memory is being used by the ExternalASTSource?
6689 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6690 const ExternalASTSource::MemoryBufferSizes &sizes =
6691 esrc->getMemoryBufferSizes();
6692
6693 createCXTUResourceUsageEntry(*entries,
6694 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6695 (unsigned long) sizes.malloc_bytes);
6696 createCXTUResourceUsageEntry(*entries,
6697 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6698 (unsigned long) sizes.mmap_bytes);
6699 }
6700
6701 // How much memory is being used by the Preprocessor?
6702 Preprocessor &pp = astUnit->getPreprocessor();
6703 createCXTUResourceUsageEntry(*entries,
6704 CXTUResourceUsage_Preprocessor,
6705 pp.getTotalMemory());
6706
6707 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6708 createCXTUResourceUsageEntry(*entries,
6709 CXTUResourceUsage_PreprocessingRecord,
6710 pRec->getTotalMemory());
6711 }
6712
6713 createCXTUResourceUsageEntry(*entries,
6714 CXTUResourceUsage_Preprocessor_HeaderSearch,
6715 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006716
Guy Benyei11169dd2012-12-18 14:30:41 +00006717 CXTUResourceUsage usage = { (void*) entries.get(),
6718 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006719 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006720 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 return usage;
6722}
6723
6724void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6725 if (usage.data)
6726 delete (MemUsageEntries*) usage.data;
6727}
6728
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006729CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6730 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006731 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006732 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006733
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006734 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006735 LOG_BAD_TU(TU);
6736 return skipped;
6737 }
6738
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006739 if (!file)
6740 return skipped;
6741
6742 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6743 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6744 if (!ppRec)
6745 return skipped;
6746
6747 ASTContext &Ctx = astUnit->getASTContext();
6748 SourceManager &sm = Ctx.getSourceManager();
6749 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6750 FileID wantedFileID = sm.translateFile(fileEntry);
6751
6752 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6753 std::vector<SourceRange> wantedRanges;
6754 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6755 i != ei; ++i) {
6756 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6757 wantedRanges.push_back(*i);
6758 }
6759
6760 skipped->count = wantedRanges.size();
6761 skipped->ranges = new CXSourceRange[skipped->count];
6762 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6763 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6764
6765 return skipped;
6766}
6767
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006768void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6769 if (ranges) {
6770 delete[] ranges->ranges;
6771 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006772 }
6773}
6774
Guy Benyei11169dd2012-12-18 14:30:41 +00006775} // end extern "C"
6776
6777void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6778 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6779 for (unsigned I = 0; I != Usage.numEntries; ++I)
6780 fprintf(stderr, " %s: %lu\n",
6781 clang_getTUResourceUsageName(Usage.entries[I].kind),
6782 Usage.entries[I].amount);
6783
6784 clang_disposeCXTUResourceUsage(Usage);
6785}
6786
6787//===----------------------------------------------------------------------===//
6788// Misc. utility functions.
6789//===----------------------------------------------------------------------===//
6790
6791/// Default to using an 8 MB stack size on "safety" threads.
6792static unsigned SafetyStackThreadSize = 8 << 20;
6793
6794namespace clang {
6795
6796bool RunSafely(llvm::CrashRecoveryContext &CRC,
6797 void (*Fn)(void*), void *UserData,
6798 unsigned Size) {
6799 if (!Size)
6800 Size = GetSafetyThreadStackSize();
6801 if (Size)
6802 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6803 return CRC.RunSafely(Fn, UserData);
6804}
6805
6806unsigned GetSafetyThreadStackSize() {
6807 return SafetyStackThreadSize;
6808}
6809
6810void SetSafetyThreadStackSize(unsigned Value) {
6811 SafetyStackThreadSize = Value;
6812}
6813
6814}
6815
6816void clang::setThreadBackgroundPriority() {
6817 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6818 return;
6819
Alp Toker1a86ad22014-07-06 06:24:00 +00006820#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006821 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6822#endif
6823}
6824
6825void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6826 if (!Unit)
6827 return;
6828
6829 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6830 DEnd = Unit->stored_diag_end();
6831 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006832 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006833 CXString Msg = clang_formatDiagnostic(&Diag,
6834 clang_defaultDiagnosticDisplayOptions());
6835 fprintf(stderr, "%s\n", clang_getCString(Msg));
6836 clang_disposeString(Msg);
6837 }
6838#ifdef LLVM_ON_WIN32
6839 // On Windows, force a flush, since there may be multiple copies of
6840 // stderr and stdout in the file system, all with different buffers
6841 // but writing to the same device.
6842 fflush(stderr);
6843#endif
6844}
6845
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006846MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6847 SourceLocation MacroDefLoc,
6848 CXTranslationUnit TU){
6849 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006852 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006853
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006854 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006855 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006856 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006857 if (MD) {
6858 for (MacroDirective::DefInfo
6859 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6860 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6861 return Def.getMacroInfo();
6862 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006863 }
6864
Craig Topper69186e72014-06-08 08:38:04 +00006865 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866}
6867
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006868const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6869 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006870 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006871 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006872 const IdentifierInfo *II = MacroDef->getName();
6873 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006874 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006875
6876 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6877}
6878
6879MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6880 const Token &Tok,
6881 CXTranslationUnit TU) {
6882 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006885 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006886
6887 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006888 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006889 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6890 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006891 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006892
6893 // Check that the token is inside the definition and not its argument list.
6894 SourceManager &SM = Unit->getSourceManager();
6895 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006896 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006897 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006898 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006899
6900 Preprocessor &PP = Unit->getPreprocessor();
6901 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6902 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006903 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006904
Alp Toker2d57cea2014-05-17 04:53:25 +00006905 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006906 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006908
6909 // Check that the identifier is not one of the macro arguments.
6910 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006912
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006913 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6914 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006916
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006917 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006918}
6919
6920MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6921 SourceLocation Loc,
6922 CXTranslationUnit TU) {
6923 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006924 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006925
6926 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006927 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006928 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006929 Preprocessor &PP = Unit->getPreprocessor();
6930 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006931 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006932 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6933 Token Tok;
6934 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006936
6937 return checkForMacroInMacroDefinition(MI, Tok, TU);
6938}
6939
Guy Benyei11169dd2012-12-18 14:30:41 +00006940extern "C" {
6941
6942CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006943 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006944}
6945
6946} // end: extern "C"
6947
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006948Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6949 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006950 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006951 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006952 if (Unit->isMainFileAST())
6953 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006954 return *this;
6955 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006956 } else {
6957 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006958 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006959 return *this;
6960}
6961
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006962Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6963 *this << FE->getName();
6964 return *this;
6965}
6966
6967Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6968 CXString cursorName = clang_getCursorDisplayName(cursor);
6969 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6970 clang_disposeString(cursorName);
6971 return *this;
6972}
6973
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006974Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6975 CXFile File;
6976 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006977 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006978 CXString FileName = clang_getFileName(File);
6979 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6980 clang_disposeString(FileName);
6981 return *this;
6982}
6983
6984Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6985 CXSourceLocation BLoc = clang_getRangeStart(range);
6986 CXSourceLocation ELoc = clang_getRangeEnd(range);
6987
6988 CXFile BFile;
6989 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006990 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006991
6992 CXFile EFile;
6993 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006994 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006995
6996 CXString BFileName = clang_getFileName(BFile);
6997 if (BFile == EFile) {
6998 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6999 BLine, BColumn, ELine, EColumn);
7000 } else {
7001 CXString EFileName = clang_getFileName(EFile);
7002 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7003 BLine, BColumn)
7004 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7005 ELine, EColumn);
7006 clang_disposeString(EFileName);
7007 }
7008 clang_disposeString(BFileName);
7009 return *this;
7010}
7011
7012Logger &cxindex::Logger::operator<<(CXString Str) {
7013 *this << clang_getCString(Str);
7014 return *this;
7015}
7016
7017Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7018 LogOS << Fmt;
7019 return *this;
7020}
7021
Chandler Carruth37ad2582014-06-27 15:14:39 +00007022static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7023
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007024cxindex::Logger::~Logger() {
7025 LogOS.flush();
7026
Chandler Carruth37ad2582014-06-27 15:14:39 +00007027 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007028
7029 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7030
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007031 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007032 OS << "[libclang:" << Name << ':';
7033
Alp Toker1a86ad22014-07-06 06:24:00 +00007034#ifdef USE_DARWIN_THREADS
7035 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007036 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7037 OS << tid << ':';
7038#endif
7039
7040 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7041 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7042 OS << Msg.str() << '\n';
7043
7044 if (Trace) {
7045 llvm::sys::PrintStackTrace(stderr);
7046 OS << "--------------------------------------------------\n";
7047 }
7048}