blob: 56d761f3a0fdf3c9d5dfd7ed44b67e500635c8a6 [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);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001865 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866
Guy Benyei11169dd2012-12-18 14:30:41 +00001867private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1870 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1872 void AddStmt(const Stmt *S);
1873 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001874 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001876 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001877};
1878} // end anonyous namespace
1879
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 // 'S' should always be non-null, since it comes from the
1882 // statement we are visiting.
1883 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1884}
1885
1886void
1887EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1888 if (Qualifier)
1889 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1890}
1891
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001893 if (S)
1894 WL.push_back(StmtVisit(S, Parent));
1895}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 if (D)
1898 WL.push_back(DeclVisit(D, Parent, isFirst));
1899}
1900void EnqueueVisitor::
1901 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1902 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001904}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 if (D)
1907 WL.push_back(MemberRefVisit(D, L, Parent));
1908}
1909void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1910 if (TI)
1911 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1912 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001915 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001916 AddStmt(*Child);
1917 }
1918 if (size == WL.size())
1919 return;
1920 // Now reverse the entries we just added. This will match the DFS
1921 // ordering performed by the worklist.
1922 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1923 std::reverse(I, E);
1924}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001925namespace {
1926class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1927 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001928 /// \brief Process clauses with list of variables.
1929 template <typename T>
1930 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001931public:
1932 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1933#define OPENMP_CLAUSE(Name, Class) \
1934 void Visit##Class(const Class *C);
1935#include "clang/Basic/OpenMPKinds.def"
1936};
1937
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001938void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1939 Visitor->AddStmt(C->getCondition());
1940}
1941
Alexey Bataev568a8332014-03-06 06:15:19 +00001942void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1943 Visitor->AddStmt(C->getNumThreads());
1944}
1945
Alexey Bataev62c87d22014-03-21 04:51:18 +00001946void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1947 Visitor->AddStmt(C->getSafelen());
1948}
1949
Alexander Musman8bd31e62014-05-27 15:12:19 +00001950void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1951 Visitor->AddStmt(C->getNumForLoops());
1952}
1953
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001955
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001956void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1957
Alexey Bataev56dafe82014-06-20 07:16:17 +00001958void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1959 Visitor->AddStmt(C->getChunkSize());
1960}
1961
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001962void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1963
Alexey Bataev236070f2014-06-20 11:19:47 +00001964void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1965
Alexey Bataev756c1962013-09-24 03:17:45 +00001966template<typename T>
1967void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001968 for (const auto *I : Node->varlists())
1969 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001970}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001971
1972void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001973 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001974}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001975void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1976 const OMPFirstprivateClause *C) {
1977 VisitOMPClauseList(C);
1978}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001979void OMPClauseEnqueue::VisitOMPLastprivateClause(
1980 const OMPLastprivateClause *C) {
1981 VisitOMPClauseList(C);
1982}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001983void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001984 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001985}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001986void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1987 VisitOMPClauseList(C);
1988}
Alexander Musman8dba6642014-04-22 13:09:42 +00001989void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1990 VisitOMPClauseList(C);
1991 Visitor->AddStmt(C->getStep());
1992}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001993void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1994 VisitOMPClauseList(C);
1995 Visitor->AddStmt(C->getAlignment());
1996}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001997void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1998 VisitOMPClauseList(C);
1999}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002000void
2001OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2002 VisitOMPClauseList(C);
2003}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002004}
Alexey Bataev756c1962013-09-24 03:17:45 +00002005
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002006void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2007 unsigned size = WL.size();
2008 OMPClauseEnqueue Visitor(this);
2009 Visitor.Visit(S);
2010 if (size == WL.size())
2011 return;
2012 // Now reverse the entries we just added. This will match the DFS
2013 // ordering performed by the worklist.
2014 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2015 std::reverse(I, E);
2016}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002017void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002018 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 AddDecl(B->getBlockDecl());
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 EnqueueChildren(E);
2025 AddTypeLoc(E->getTypeSourceInfo());
2026}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002027void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2028 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 E = S->body_rend(); I != E; ++I) {
2030 AddStmt(*I);
2031 }
2032}
2033void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 AddStmt(S->getSubStmt());
2036 AddDeclarationNameInfo(S);
2037 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2038 AddNestedNameSpecifierLoc(QualifierLoc);
2039}
2040
2041void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2044 AddDeclarationNameInfo(E);
2045 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2046 AddNestedNameSpecifierLoc(QualifierLoc);
2047 if (!E->isImplicitAccess())
2048 AddStmt(E->getBase());
2049}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 // Enqueue the initializer , if any.
2052 AddStmt(E->getInitializer());
2053 // Enqueue the array size, if any.
2054 AddStmt(E->getArraySize());
2055 // Enqueue the allocated type.
2056 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2057 // Enqueue the placement arguments.
2058 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2059 AddStmt(E->getPlacementArg(I-1));
2060}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2063 AddStmt(CE->getArg(I-1));
2064 AddStmt(CE->getCallee());
2065 AddStmt(CE->getArg(0));
2066}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2068 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002069 // Visit the name of the type being destroyed.
2070 AddTypeLoc(E->getDestroyedTypeInfo());
2071 // Visit the scope type that looks disturbingly like the nested-name-specifier
2072 // but isn't.
2073 AddTypeLoc(E->getScopeTypeInfo());
2074 // Visit the nested-name-specifier.
2075 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2076 AddNestedNameSpecifierLoc(QualifierLoc);
2077 // Visit base expression.
2078 AddStmt(E->getBase());
2079}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2081 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 AddTypeLoc(E->getTypeSourceInfo());
2083}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2085 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 EnqueueChildren(E);
2087 AddTypeLoc(E->getTypeSourceInfo());
2088}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 EnqueueChildren(E);
2091 if (E->isTypeOperand())
2092 AddTypeLoc(E->getTypeOperandSourceInfo());
2093}
2094
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2096 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 AddTypeLoc(E->getTypeSourceInfo());
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 EnqueueChildren(E);
2102 if (E->isTypeOperand())
2103 AddTypeLoc(E->getTypeOperandSourceInfo());
2104}
2105
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 EnqueueChildren(S);
2108 AddDecl(S->getExceptionDecl());
2109}
2110
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 if (DR->hasExplicitTemplateArgs()) {
2113 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2114 }
2115 WL.push_back(DeclRefExprParts(DR, Parent));
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2118 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2120 AddDeclarationNameInfo(E);
2121 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 unsigned size = WL.size();
2125 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002126 for (const auto *D : S->decls()) {
2127 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 isFirst = false;
2129 }
2130 if (size == WL.size())
2131 return;
2132 // Now reverse the entries we just added. This will match the DFS
2133 // ordering performed by the worklist.
2134 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2135 std::reverse(I, E);
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 D = E->designators_rbegin(), DEnd = E->designators_rend();
2141 D != DEnd; ++D) {
2142 if (D->isFieldDesignator()) {
2143 if (FieldDecl *Field = D->getField())
2144 AddMemberRef(Field, D->getFieldLoc());
2145 continue;
2146 }
2147 if (D->isArrayDesignator()) {
2148 AddStmt(E->getArrayIndex(*D));
2149 continue;
2150 }
2151 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2152 AddStmt(E->getArrayRangeEnd(*D));
2153 AddStmt(E->getArrayRangeStart(*D));
2154 }
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 EnqueueChildren(E);
2158 AddTypeLoc(E->getTypeInfoAsWritten());
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 AddStmt(FS->getBody());
2162 AddStmt(FS->getInc());
2163 AddStmt(FS->getCond());
2164 AddDecl(FS->getConditionVariable());
2165 AddStmt(FS->getInit());
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2169}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 AddStmt(If->getElse());
2172 AddStmt(If->getThen());
2173 AddStmt(If->getCond());
2174 AddDecl(If->getConditionVariable());
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 // We care about the syntactic form of the initializer list, only.
2178 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2179 IE = Syntactic;
2180 EnqueueChildren(IE);
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 WL.push_back(MemberExprParts(M, Parent));
2184
2185 // If the base of the member access expression is an implicit 'this', don't
2186 // visit it.
2187 // FIXME: If we ever want to show these implicit accesses, this will be
2188 // unfortunate. However, clang_getCursor() relies on this behavior.
2189 if (!M->isImplicitAccess())
2190 AddStmt(M->getBase());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddTypeLoc(E->getEncodedTypeSourceInfo());
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 EnqueueChildren(M);
2197 AddTypeLoc(M->getClassReceiverTypeInfo());
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 // Visit the components of the offsetof expression.
2201 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2202 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2203 const OffsetOfNode &Node = E->getComponent(I-1);
2204 switch (Node.getKind()) {
2205 case OffsetOfNode::Array:
2206 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2207 break;
2208 case OffsetOfNode::Field:
2209 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2210 break;
2211 case OffsetOfNode::Identifier:
2212 case OffsetOfNode::Base:
2213 continue;
2214 }
2215 }
2216 // Visit the type into which we're computing the offset.
2217 AddTypeLoc(E->getTypeSourceInfo());
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2221 WL.push_back(OverloadExprParts(E, Parent));
2222}
2223void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 EnqueueChildren(E);
2226 if (E->isArgumentType())
2227 AddTypeLoc(E->getArgumentTypeInfo());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 EnqueueChildren(S);
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 AddStmt(S->getBody());
2234 AddStmt(S->getCond());
2235 AddDecl(S->getConditionVariable());
2236}
2237
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddStmt(W->getBody());
2240 AddStmt(W->getCond());
2241 AddDecl(W->getConditionVariable());
2242}
2243
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 for (unsigned I = E->getNumArgs(); I > 0; --I)
2246 AddTypeLoc(E->getArg(I-1));
2247}
2248
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 AddTypeLoc(E->getQueriedTypeSourceInfo());
2251}
2252
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 VisitOverloadExpr(U);
2259 if (!U->isImplicitAccess())
2260 AddStmt(U->getBase());
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 AddStmt(E->getSubExpr());
2264 AddTypeLoc(E->getWrittenTypeInfo());
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 WL.push_back(SizeOfPackExprParts(E, Parent));
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 // If the opaque value has a source expression, just transparently
2271 // visit that. This is useful for (e.g.) pseudo-object expressions.
2272 if (Expr *SourceExpr = E->getSourceExpr())
2273 return Visit(SourceExpr);
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 AddStmt(E->getBody());
2277 WL.push_back(LambdaExprParts(E, Parent));
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 // Treat the expression like its syntactic form.
2281 Visit(E->getSyntacticForm());
2282}
2283
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002284void EnqueueVisitor::VisitOMPExecutableDirective(
2285 const OMPExecutableDirective *D) {
2286 EnqueueChildren(D);
2287 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2288 E = D->clauses().end();
2289 I != E; ++I)
2290 EnqueueChildren(*I);
2291}
2292
2293void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2294 VisitOMPExecutableDirective(D);
2295}
2296
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002297void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2298 VisitOMPExecutableDirective(D);
2299}
2300
Alexey Bataevf29276e2014-06-18 04:14:57 +00002301void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2302 VisitOMPExecutableDirective(D);
2303}
2304
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002305void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2306 VisitOMPExecutableDirective(D);
2307}
2308
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002309void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2310 VisitOMPExecutableDirective(D);
2311}
2312
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002313void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2314 VisitOMPExecutableDirective(D);
2315}
2316
Alexey Bataev4acb8592014-07-07 13:01:15 +00002317void
2318EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2319 VisitOMPExecutableDirective(D);
2320}
2321
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002322void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2323 const OMPParallelSectionsDirective *D) {
2324 VisitOMPExecutableDirective(D);
2325}
2326
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002327void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2328 VisitOMPExecutableDirective(D);
2329}
2330
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2333}
2334
2335bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2336 if (RegionOfInterest.isValid()) {
2337 SourceRange Range = getRawCursorExtent(C);
2338 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2339 return false;
2340 }
2341 return true;
2342}
2343
2344bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2345 while (!WL.empty()) {
2346 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002347 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002348
2349 // Set the Parent field, then back to its old value once we're done.
2350 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2351
2352 switch (LI.getKind()) {
2353 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 if (!D)
2356 continue;
2357
2358 // For now, perform default visitation for Decls.
2359 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2360 cast<DeclVisit>(&LI)->isFirst())))
2361 return true;
2362
2363 continue;
2364 }
2365 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2366 const ASTTemplateArgumentListInfo *ArgList =
2367 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2368 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2369 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2370 Arg != ArgEnd; ++Arg) {
2371 if (VisitTemplateArgumentLoc(*Arg))
2372 return true;
2373 }
2374 continue;
2375 }
2376 case VisitorJob::TypeLocVisitKind: {
2377 // Perform default visitation for TypeLocs.
2378 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2379 return true;
2380 continue;
2381 }
2382 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 if (LabelStmt *stmt = LS->getStmt()) {
2385 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2386 TU))) {
2387 return true;
2388 }
2389 }
2390 continue;
2391 }
2392
2393 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2394 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2395 if (VisitNestedNameSpecifierLoc(V->get()))
2396 return true;
2397 continue;
2398 }
2399
2400 case VisitorJob::DeclarationNameInfoVisitKind: {
2401 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2402 ->get()))
2403 return true;
2404 continue;
2405 }
2406 case VisitorJob::MemberRefVisitKind: {
2407 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2408 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2409 return true;
2410 continue;
2411 }
2412 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 if (!S)
2415 continue;
2416
2417 // Update the current cursor.
2418 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2419 if (!IsInRegionOfInterest(Cursor))
2420 continue;
2421 switch (Visitor(Cursor, Parent, ClientData)) {
2422 case CXChildVisit_Break: return true;
2423 case CXChildVisit_Continue: break;
2424 case CXChildVisit_Recurse:
2425 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002426 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 EnqueueWorkList(WL, S);
2428 break;
2429 }
2430 continue;
2431 }
2432 case VisitorJob::MemberExprPartsKind: {
2433 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002435
2436 // Visit the nested-name-specifier
2437 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2438 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2439 return true;
2440
2441 // Visit the declaration name.
2442 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2443 return true;
2444
2445 // Visit the explicitly-specified template arguments, if any.
2446 if (M->hasExplicitTemplateArgs()) {
2447 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2448 *ArgEnd = Arg + M->getNumTemplateArgs();
2449 Arg != ArgEnd; ++Arg) {
2450 if (VisitTemplateArgumentLoc(*Arg))
2451 return true;
2452 }
2453 }
2454 continue;
2455 }
2456 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002457 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 // Visit nested-name-specifier, if present.
2459 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2460 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2461 return true;
2462 // Visit declaration name.
2463 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2464 return true;
2465 continue;
2466 }
2467 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002468 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 // Visit the nested-name-specifier.
2470 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2471 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2472 return true;
2473 // Visit the declaration name.
2474 if (VisitDeclarationNameInfo(O->getNameInfo()))
2475 return true;
2476 // Visit the overloaded declaration reference.
2477 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2478 return true;
2479 continue;
2480 }
2481 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002482 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002483 NamedDecl *Pack = E->getPack();
2484 if (isa<TemplateTypeParmDecl>(Pack)) {
2485 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2486 E->getPackLoc(), TU)))
2487 return true;
2488
2489 continue;
2490 }
2491
2492 if (isa<TemplateTemplateParmDecl>(Pack)) {
2493 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2494 E->getPackLoc(), TU)))
2495 return true;
2496
2497 continue;
2498 }
2499
2500 // Non-type template parameter packs and function parameter packs are
2501 // treated like DeclRefExpr cursors.
2502 continue;
2503 }
2504
2505 case VisitorJob::LambdaExprPartsKind: {
2506 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002507 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2509 CEnd = E->explicit_capture_end();
2510 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002511 // FIXME: Lambda init-captures.
2512 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002513 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002514
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2516 C->getLocation(),
2517 TU)))
2518 return true;
2519 }
2520
2521 // Visit parameters and return type, if present.
2522 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2523 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2524 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2525 // Visit the whole type.
2526 if (Visit(TL))
2527 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002528 } else if (FunctionProtoTypeLoc Proto =
2529 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002530 if (E->hasExplicitParameters()) {
2531 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002532 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2533 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 return true;
2535 } else {
2536 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002537 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 return true;
2539 }
2540 }
2541 }
2542 break;
2543 }
2544
2545 case VisitorJob::PostChildrenVisitKind:
2546 if (PostChildrenVisitor(Parent, ClientData))
2547 return true;
2548 break;
2549 }
2550 }
2551 return false;
2552}
2553
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002554bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002555 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 if (!WorkListFreeList.empty()) {
2557 WL = WorkListFreeList.back();
2558 WL->clear();
2559 WorkListFreeList.pop_back();
2560 }
2561 else {
2562 WL = new VisitorWorkList();
2563 WorkListCache.push_back(WL);
2564 }
2565 EnqueueWorkList(*WL, S);
2566 bool result = RunVisitorWorkList(*WL);
2567 WorkListFreeList.push_back(WL);
2568 return result;
2569}
2570
2571namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002572typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002573RefNamePieces
2574buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2575 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2576 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2578 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2579 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2580
2581 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2582
2583 RefNamePieces Pieces;
2584
2585 if (WantQualifier && QLoc.isValid())
2586 Pieces.push_back(QLoc);
2587
2588 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2589 Pieces.push_back(NI.getLoc());
2590
2591 if (WantTemplateArgs && TemplateArgs)
2592 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2593 TemplateArgs->RAngleLoc));
2594
2595 if (Kind == DeclarationName::CXXOperatorName) {
2596 Pieces.push_back(SourceLocation::getFromRawEncoding(
2597 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2598 Pieces.push_back(SourceLocation::getFromRawEncoding(
2599 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2600 }
2601
2602 if (WantSinglePiece) {
2603 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2604 Pieces.clear();
2605 Pieces.push_back(R);
2606 }
2607
2608 return Pieces;
2609}
2610}
2611
2612//===----------------------------------------------------------------------===//
2613// Misc. API hooks.
2614//===----------------------------------------------------------------------===//
2615
Chad Rosier05c71aa2013-03-27 18:28:23 +00002616static void fatal_error_handler(void *user_data, const std::string& reason,
2617 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002618 // Write the result out to stderr avoiding errs() because raw_ostreams can
2619 // call report_fatal_error.
2620 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2621 ::abort();
2622}
2623
Chandler Carruth66660742014-06-27 16:37:27 +00002624namespace {
2625struct RegisterFatalErrorHandler {
2626 RegisterFatalErrorHandler() {
2627 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2628 }
2629};
2630}
2631
2632static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2633
Guy Benyei11169dd2012-12-18 14:30:41 +00002634extern "C" {
2635CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2636 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 // We use crash recovery to make some of our APIs more reliable, implicitly
2638 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002639 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2640 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002641
Chandler Carruth66660742014-06-27 16:37:27 +00002642 // Look through the managed static to trigger construction of the managed
2643 // static which registers our fatal error handler. This ensures it is only
2644 // registered once.
2645 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002646
2647 CIndexer *CIdxr = new CIndexer();
2648 if (excludeDeclarationsFromPCH)
2649 CIdxr->setOnlyLocalDecls();
2650 if (displayDiagnostics)
2651 CIdxr->setDisplayDiagnostics();
2652
2653 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2654 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2655 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2656 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2657 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2658 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2659
2660 return CIdxr;
2661}
2662
2663void clang_disposeIndex(CXIndex CIdx) {
2664 if (CIdx)
2665 delete static_cast<CIndexer *>(CIdx);
2666}
2667
2668void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2669 if (CIdx)
2670 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2671}
2672
2673unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2674 if (CIdx)
2675 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2676 return 0;
2677}
2678
2679void clang_toggleCrashRecovery(unsigned isEnabled) {
2680 if (isEnabled)
2681 llvm::CrashRecoveryContext::Enable();
2682 else
2683 llvm::CrashRecoveryContext::Disable();
2684}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002685
Guy Benyei11169dd2012-12-18 14:30:41 +00002686CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2687 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002688 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002689 enum CXErrorCode Result =
2690 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002691 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002692 assert((TU && Result == CXError_Success) ||
2693 (!TU && Result != CXError_Success));
2694 return TU;
2695}
2696
2697enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2698 const char *ast_filename,
2699 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002700 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002701 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002702
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703 if (!CIdx || !ast_filename || !out_TU)
2704 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002705
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002706 LOG_FUNC_SECTION {
2707 *Log << ast_filename;
2708 }
2709
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2711 FileSystemOptions FileSystemOpts;
2712
2713 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002714 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002715 CXXIdx->getOnlyLocalDecls(), None,
2716 /*CaptureDiagnostics=*/true,
2717 /*AllowPCHWithCompilerErrors=*/true,
2718 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002719 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2720 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002721}
2722
2723unsigned clang_defaultEditingTranslationUnitOptions() {
2724 return CXTranslationUnit_PrecompiledPreamble |
2725 CXTranslationUnit_CacheCompletionResults;
2726}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002727
Guy Benyei11169dd2012-12-18 14:30:41 +00002728CXTranslationUnit
2729clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2730 const char *source_filename,
2731 int num_command_line_args,
2732 const char * const *command_line_args,
2733 unsigned num_unsaved_files,
2734 struct CXUnsavedFile *unsaved_files) {
2735 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2736 return clang_parseTranslationUnit(CIdx, source_filename,
2737 command_line_args, num_command_line_args,
2738 unsaved_files, num_unsaved_files,
2739 Options);
2740}
2741
2742struct ParseTranslationUnitInfo {
2743 CXIndex CIdx;
2744 const char *source_filename;
2745 const char *const *command_line_args;
2746 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002747 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002749 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002750 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002751};
2752static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002753 const ParseTranslationUnitInfo *PTUI =
2754 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 CXIndex CIdx = PTUI->CIdx;
2756 const char *source_filename = PTUI->source_filename;
2757 const char * const *command_line_args = PTUI->command_line_args;
2758 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002760 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002761
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002762 // Set up the initial return values.
2763 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002764 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002765
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002766 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002767 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002768 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002769 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002770 }
2771
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2773
2774 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2775 setThreadBackgroundPriority();
2776
2777 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2778 // FIXME: Add a flag for modules.
2779 TranslationUnitKind TUKind
2780 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002781 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002782 = options & CXTranslationUnit_CacheCompletionResults;
2783 bool IncludeBriefCommentsInCodeCompletion
2784 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2785 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2786 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2787
2788 // Configure the diagnostics.
2789 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002790 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002791
2792 // Recover resources if we crash before exiting this function.
2793 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2794 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002795 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002796
Ahmed Charlesb8984322014-03-07 20:03:18 +00002797 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2798 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002799
2800 // Recover resources if we crash before exiting this function.
2801 llvm::CrashRecoveryContextCleanupRegistrar<
2802 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2803
Alp Toker9d85b182014-07-07 01:23:14 +00002804 for (auto &UF : PTUI->unsaved_files) {
2805 llvm::MemoryBuffer *MB =
2806 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2807 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002808 }
2809
Ahmed Charlesb8984322014-03-07 20:03:18 +00002810 std::unique_ptr<std::vector<const char *>> Args(
2811 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002812
2813 // Recover resources if we crash before exiting this method.
2814 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2815 ArgsCleanup(Args.get());
2816
2817 // Since the Clang C library is primarily used by batch tools dealing with
2818 // (often very broken) source code, where spell-checking can have a
2819 // significant negative impact on performance (particularly when
2820 // precompiled headers are involved), we disable it by default.
2821 // Only do this if we haven't found a spell-checking-related argument.
2822 bool FoundSpellCheckingArgument = false;
2823 for (int I = 0; I != num_command_line_args; ++I) {
2824 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2825 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2826 FoundSpellCheckingArgument = true;
2827 break;
2828 }
2829 }
2830 if (!FoundSpellCheckingArgument)
2831 Args->push_back("-fno-spell-checking");
2832
2833 Args->insert(Args->end(), command_line_args,
2834 command_line_args + num_command_line_args);
2835
2836 // The 'source_filename' argument is optional. If the caller does not
2837 // specify it then it is assumed that the source file is specified
2838 // in the actual argument list.
2839 // Put the source file after command_line_args otherwise if '-x' flag is
2840 // present it will be unused.
2841 if (source_filename)
2842 Args->push_back(source_filename);
2843
2844 // Do we need the detailed preprocessing record?
2845 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2846 Args->push_back("-Xclang");
2847 Args->push_back("-detailed-preprocessing-record");
2848 }
2849
2850 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002851 std::unique_ptr<ASTUnit> ErrUnit;
2852 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002853 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002854 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2855 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2856 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2857 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2858 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2859 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002860
2861 if (NumErrors != Diags->getClient()->getNumErrors()) {
2862 // Make sure to check that 'Unit' is non-NULL.
2863 if (CXXIdx->getDisplayDiagnostics())
2864 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2865 }
2866
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002867 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2868 PTUI->result = CXError_ASTReadError;
2869 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002870 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002871 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2872 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002873}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874
2875CXTranslationUnit
2876clang_parseTranslationUnit(CXIndex CIdx,
2877 const char *source_filename,
2878 const char *const *command_line_args,
2879 int num_command_line_args,
2880 struct CXUnsavedFile *unsaved_files,
2881 unsigned num_unsaved_files,
2882 unsigned options) {
2883 CXTranslationUnit TU;
2884 enum CXErrorCode Result = clang_parseTranslationUnit2(
2885 CIdx, source_filename, command_line_args, num_command_line_args,
2886 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002887 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002888 assert((TU && Result == CXError_Success) ||
2889 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002890 return TU;
2891}
2892
2893enum CXErrorCode clang_parseTranslationUnit2(
2894 CXIndex CIdx,
2895 const char *source_filename,
2896 const char *const *command_line_args,
2897 int num_command_line_args,
2898 struct CXUnsavedFile *unsaved_files,
2899 unsigned num_unsaved_files,
2900 unsigned options,
2901 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002902 LOG_FUNC_SECTION {
2903 *Log << source_filename << ": ";
2904 for (int i = 0; i != num_command_line_args; ++i)
2905 *Log << command_line_args[i] << " ";
2906 }
2907
Alp Toker9d85b182014-07-07 01:23:14 +00002908 if (num_unsaved_files && !unsaved_files)
2909 return CXError_InvalidArguments;
2910
Alp Toker5c532982014-07-07 22:42:03 +00002911 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002912 ParseTranslationUnitInfo PTUI = {
2913 CIdx,
2914 source_filename,
2915 command_line_args,
2916 num_command_line_args,
2917 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2918 options,
2919 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002920 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002921 llvm::CrashRecoveryContext CRC;
2922
2923 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2924 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2925 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2926 fprintf(stderr, " 'command_line_args' : [");
2927 for (int i = 0; i != num_command_line_args; ++i) {
2928 if (i)
2929 fprintf(stderr, ", ");
2930 fprintf(stderr, "'%s'", command_line_args[i]);
2931 }
2932 fprintf(stderr, "],\n");
2933 fprintf(stderr, " 'unsaved_files' : [");
2934 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2935 if (i)
2936 fprintf(stderr, ", ");
2937 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2938 unsaved_files[i].Length);
2939 }
2940 fprintf(stderr, "],\n");
2941 fprintf(stderr, " 'options' : %d,\n", options);
2942 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002943
2944 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002945 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002946 if (CXTranslationUnit *TU = PTUI.out_TU)
2947 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002948 }
Alp Toker5c532982014-07-07 22:42:03 +00002949
2950 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002951}
2952
2953unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2954 return CXSaveTranslationUnit_None;
2955}
2956
2957namespace {
2958
2959struct SaveTranslationUnitInfo {
2960 CXTranslationUnit TU;
2961 const char *FileName;
2962 unsigned options;
2963 CXSaveError result;
2964};
2965
2966}
2967
2968static void clang_saveTranslationUnit_Impl(void *UserData) {
2969 SaveTranslationUnitInfo *STUI =
2970 static_cast<SaveTranslationUnitInfo*>(UserData);
2971
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002972 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2974 setThreadBackgroundPriority();
2975
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002976 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2978}
2979
2980int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2981 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002982 LOG_FUNC_SECTION {
2983 *Log << TU << ' ' << FileName;
2984 }
2985
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002987 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002989 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002991 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002992 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2993 if (!CXXUnit->hasSema())
2994 return CXSaveError_InvalidTU;
2995
2996 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2997
2998 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2999 getenv("LIBCLANG_NOTHREADS")) {
3000 clang_saveTranslationUnit_Impl(&STUI);
3001
3002 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3003 PrintLibclangResourceUsage(TU);
3004
3005 return STUI.result;
3006 }
3007
3008 // We have an AST that has invalid nodes due to compiler errors.
3009 // Use a crash recovery thread for protection.
3010
3011 llvm::CrashRecoveryContext CRC;
3012
3013 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3014 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3015 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3016 fprintf(stderr, " 'options' : %d,\n", options);
3017 fprintf(stderr, "}\n");
3018
3019 return CXSaveError_Unknown;
3020
3021 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3022 PrintLibclangResourceUsage(TU);
3023 }
3024
3025 return STUI.result;
3026}
3027
3028void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3029 if (CTUnit) {
3030 // If the translation unit has been marked as unsafe to free, just discard
3031 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003032 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3033 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003034 return;
3035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003036 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003037 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3039 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003040 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 delete CTUnit;
3042 }
3043}
3044
3045unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3046 return CXReparse_None;
3047}
3048
3049struct ReparseTranslationUnitInfo {
3050 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003051 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003053 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003054};
3055
3056static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003057 const ReparseTranslationUnitInfo *RTUI =
3058 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003059 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003060 unsigned options = RTUI->options;
3061 (void) options;
3062
3063 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003064 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003065 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003066 RTUI->result = CXError_InvalidArguments;
3067 return;
3068 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003069
3070 // Reset the associated diagnostics.
3071 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003072 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003073
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003074 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3076 setThreadBackgroundPriority();
3077
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003078 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003080
3081 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3082 new std::vector<ASTUnit::RemappedFile>());
3083
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 // Recover resources if we crash before exiting this function.
3085 llvm::CrashRecoveryContextCleanupRegistrar<
3086 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003087
3088 for (auto &UF : RTUI->unsaved_files) {
3089 llvm::MemoryBuffer *MB =
3090 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3091 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003093
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003094 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003095 RTUI->result = CXError_Success;
3096 else if (isASTReadError(CXXUnit))
3097 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003098}
3099
3100int clang_reparseTranslationUnit(CXTranslationUnit TU,
3101 unsigned num_unsaved_files,
3102 struct CXUnsavedFile *unsaved_files,
3103 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003104 LOG_FUNC_SECTION {
3105 *Log << TU;
3106 }
3107
Alp Toker9d85b182014-07-07 01:23:14 +00003108 if (num_unsaved_files && !unsaved_files)
3109 return CXError_InvalidArguments;
3110
Alp Toker5c532982014-07-07 22:42:03 +00003111 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003112 ReparseTranslationUnitInfo RTUI = {
3113 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003114 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003115
3116 if (getenv("LIBCLANG_NOTHREADS")) {
3117 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003118 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 }
3120
3121 llvm::CrashRecoveryContext CRC;
3122
3123 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3124 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003125 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003126 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3128 PrintLibclangResourceUsage(TU);
3129
Alp Toker5c532982014-07-07 22:42:03 +00003130 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003131}
3132
3133
3134CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003135 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003136 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003137 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003138 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003140 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003141 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003142}
3143
3144CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003145 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003146 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003147 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003148 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003149
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003150 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3152}
3153
3154} // end: extern "C"
3155
3156//===----------------------------------------------------------------------===//
3157// CXFile Operations.
3158//===----------------------------------------------------------------------===//
3159
3160extern "C" {
3161CXString clang_getFileName(CXFile SFile) {
3162 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003163 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003164
3165 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003166 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003167}
3168
3169time_t clang_getFileTime(CXFile SFile) {
3170 if (!SFile)
3171 return 0;
3172
3173 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3174 return FEnt->getModificationTime();
3175}
3176
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003177CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003178 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003179 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003180 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003181 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003182
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003183 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003184
3185 FileManager &FMgr = CXXUnit->getFileManager();
3186 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3187}
3188
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003189unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3190 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003191 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003192 LOG_BAD_TU(TU);
3193 return 0;
3194 }
3195
3196 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 return 0;
3198
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003199 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 FileEntry *FEnt = static_cast<FileEntry *>(file);
3201 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3202 .isFileMultipleIncludeGuarded(FEnt);
3203}
3204
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003205int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3206 if (!file || !outID)
3207 return 1;
3208
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003209 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003210 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3211 outID->data[0] = ID.getDevice();
3212 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003213 outID->data[2] = FEnt->getModificationTime();
3214 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003215}
3216
Guy Benyei11169dd2012-12-18 14:30:41 +00003217} // end: extern "C"
3218
3219//===----------------------------------------------------------------------===//
3220// CXCursor Operations.
3221//===----------------------------------------------------------------------===//
3222
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003223static const Decl *getDeclFromExpr(const Stmt *E) {
3224 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return getDeclFromExpr(CE->getSubExpr());
3226
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003227 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003229 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003231 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003233 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 if (PRE->isExplicitProperty())
3235 return PRE->getExplicitProperty();
3236 // It could be messaging both getter and setter as in:
3237 // ++myobj.myprop;
3238 // in which case prefer to associate the setter since it is less obvious
3239 // from inspecting the source that the setter is going to get called.
3240 if (PRE->isMessagingSetter())
3241 return PRE->getImplicitPropertySetter();
3242 return PRE->getImplicitPropertyGetter();
3243 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003244 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003246 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 if (Expr *Src = OVE->getSourceExpr())
3248 return getDeclFromExpr(Src);
3249
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003250 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003252 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 if (!CE->isElidable())
3254 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003255 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return OME->getMethodDecl();
3257
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003258 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003260 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3262 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003263 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3265 isa<ParmVarDecl>(SizeOfPack->getPack()))
3266 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003267
3268 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269}
3270
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003271static SourceLocation getLocationFromExpr(const Expr *E) {
3272 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 return getLocationFromExpr(CE->getSubExpr());
3274
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003275 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003277 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003279 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003281 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003283 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003285 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 return PropRef->getLocation();
3287
3288 return E->getLocStart();
3289}
3290
3291extern "C" {
3292
3293unsigned clang_visitChildren(CXCursor parent,
3294 CXCursorVisitor visitor,
3295 CXClientData client_data) {
3296 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3297 /*VisitPreprocessorLast=*/false);
3298 return CursorVis.VisitChildren(parent);
3299}
3300
3301#ifndef __has_feature
3302#define __has_feature(x) 0
3303#endif
3304#if __has_feature(blocks)
3305typedef enum CXChildVisitResult
3306 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3307
3308static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3309 CXClientData client_data) {
3310 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3311 return block(cursor, parent);
3312}
3313#else
3314// If we are compiled with a compiler that doesn't have native blocks support,
3315// define and call the block manually, so the
3316typedef struct _CXChildVisitResult
3317{
3318 void *isa;
3319 int flags;
3320 int reserved;
3321 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3322 CXCursor);
3323} *CXCursorVisitorBlock;
3324
3325static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3326 CXClientData client_data) {
3327 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3328 return block->invoke(block, cursor, parent);
3329}
3330#endif
3331
3332
3333unsigned clang_visitChildrenWithBlock(CXCursor parent,
3334 CXCursorVisitorBlock block) {
3335 return clang_visitChildren(parent, visitWithBlock, block);
3336}
3337
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003338static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003340 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003341
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003342 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003344 if (const ObjCPropertyImplDecl *PropImpl =
3345 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003351 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003352
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003353 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003356 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003357 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003359 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3361 // and returns different names. NamedDecl returns the class name and
3362 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003363 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364
3365 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003366 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003367
3368 SmallString<1024> S;
3369 llvm::raw_svector_ostream os(S);
3370 ND->printName(os);
3371
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373}
3374
3375CXString clang_getCursorSpelling(CXCursor C) {
3376 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003377 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003378
3379 if (clang_isReference(C.kind)) {
3380 switch (C.kind) {
3381 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003382 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003383 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 }
3385 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003386 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003387 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003390 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003392 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 }
3394 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003395 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003396 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003399 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 assert(Type && "Missing type decl");
3401
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003402 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 getAsString());
3404 }
3405 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003406 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 assert(Template && "Missing template decl");
3408
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003409 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 }
3411
3412 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003413 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 assert(NS && "Missing namespace decl");
3415
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003416 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418
3419 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003420 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 assert(Field && "Missing member decl");
3422
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003423 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 }
3425
3426 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003427 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 assert(Label && "Missing label");
3429
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003430 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
3433 case CXCursor_OverloadedDeclRef: {
3434 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3436 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003437 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003438 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003441 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 OverloadedTemplateStorage *Ovl
3443 = Storage.get<OverloadedTemplateStorage*>();
3444 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003445 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003446 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 }
3448
3449 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003450 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 assert(Var && "Missing variable decl");
3452
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 }
3455
3456 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003457 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 }
3459 }
3460
3461 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003462 const Expr *E = getCursorExpr(C);
3463
3464 if (C.kind == CXCursor_ObjCStringLiteral ||
3465 C.kind == CXCursor_StringLiteral) {
3466 const StringLiteral *SLit;
3467 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3468 SLit = OSL->getString();
3469 } else {
3470 SLit = cast<StringLiteral>(E);
3471 }
3472 SmallString<256> Buf;
3473 llvm::raw_svector_ostream OS(Buf);
3474 SLit->outputString(OS);
3475 return cxstring::createDup(OS.str());
3476 }
3477
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003478 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 if (D)
3480 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003481 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 }
3483
3484 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003485 const Stmt *S = getCursorStmt(C);
3486 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003487 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003488
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003489 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 }
3491
3492 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003493 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 ->getNameStart());
3495
3496 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003497 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 ->getNameStart());
3499
3500 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003501 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003502
3503 if (clang_isDeclaration(C.kind))
3504 return getDeclSpelling(getCursorDecl(C));
3505
3506 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003507 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 }
3510
3511 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003512 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003513 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 }
3515
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003516 if (C.kind == CXCursor_PackedAttr) {
3517 return cxstring::createRef("packed");
3518 }
3519
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003520 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003521}
3522
3523CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3524 unsigned pieceIndex,
3525 unsigned options) {
3526 if (clang_Cursor_isNull(C))
3527 return clang_getNullRange();
3528
3529 ASTContext &Ctx = getCursorContext(C);
3530
3531 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003532 const Stmt *S = getCursorStmt(C);
3533 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 if (pieceIndex > 0)
3535 return clang_getNullRange();
3536 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3537 }
3538
3539 return clang_getNullRange();
3540 }
3541
3542 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003543 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3545 if (pieceIndex >= ME->getNumSelectorLocs())
3546 return clang_getNullRange();
3547 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3548 }
3549 }
3550
3551 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3552 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003553 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3555 if (pieceIndex >= MD->getNumSelectorLocs())
3556 return clang_getNullRange();
3557 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3558 }
3559 }
3560
3561 if (C.kind == CXCursor_ObjCCategoryDecl ||
3562 C.kind == CXCursor_ObjCCategoryImplDecl) {
3563 if (pieceIndex > 0)
3564 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003565 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3567 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003568 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3570 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3571 }
3572
3573 if (C.kind == CXCursor_ModuleImportDecl) {
3574 if (pieceIndex > 0)
3575 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003576 if (const ImportDecl *ImportD =
3577 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3579 if (!Locs.empty())
3580 return cxloc::translateSourceRange(Ctx,
3581 SourceRange(Locs.front(), Locs.back()));
3582 }
3583 return clang_getNullRange();
3584 }
3585
3586 // FIXME: A CXCursor_InclusionDirective should give the location of the
3587 // filename, but we don't keep track of this.
3588
3589 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3590 // but we don't keep track of this.
3591
3592 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3593 // but we don't keep track of this.
3594
3595 // Default handling, give the location of the cursor.
3596
3597 if (pieceIndex > 0)
3598 return clang_getNullRange();
3599
3600 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3601 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3602 return cxloc::translateSourceRange(Ctx, Loc);
3603}
3604
3605CXString clang_getCursorDisplayName(CXCursor C) {
3606 if (!clang_isDeclaration(C.kind))
3607 return clang_getCursorSpelling(C);
3608
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003609 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003611 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003612
3613 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003614 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 D = FunTmpl->getTemplatedDecl();
3616
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003617 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 SmallString<64> Str;
3619 llvm::raw_svector_ostream OS(Str);
3620 OS << *Function;
3621 if (Function->getPrimaryTemplate())
3622 OS << "<>";
3623 OS << "(";
3624 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3625 if (I)
3626 OS << ", ";
3627 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3628 }
3629
3630 if (Function->isVariadic()) {
3631 if (Function->getNumParams())
3632 OS << ", ";
3633 OS << "...";
3634 }
3635 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003636 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 }
3638
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003639 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 SmallString<64> Str;
3641 llvm::raw_svector_ostream OS(Str);
3642 OS << *ClassTemplate;
3643 OS << "<";
3644 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3645 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3646 if (I)
3647 OS << ", ";
3648
3649 NamedDecl *Param = Params->getParam(I);
3650 if (Param->getIdentifier()) {
3651 OS << Param->getIdentifier()->getName();
3652 continue;
3653 }
3654
3655 // There is no parameter name, which makes this tricky. Try to come up
3656 // with something useful that isn't too long.
3657 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3658 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3659 else if (NonTypeTemplateParmDecl *NTTP
3660 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3661 OS << NTTP->getType().getAsString(Policy);
3662 else
3663 OS << "template<...> class";
3664 }
3665
3666 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003667 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 }
3669
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003670 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3672 // If the type was explicitly written, use that.
3673 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003674 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003675
Benjamin Kramer9170e912013-02-22 15:46:01 +00003676 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 llvm::raw_svector_ostream OS(Str);
3678 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003679 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 ClassSpec->getTemplateArgs().data(),
3681 ClassSpec->getTemplateArgs().size(),
3682 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003683 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 }
3685
3686 return clang_getCursorSpelling(C);
3687}
3688
3689CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3690 switch (Kind) {
3691 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003819 case CXCursor_ObjCSelfExpr:
3820 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003909 case CXCursor_SEHLeaveStmt:
3910 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003939 case CXCursor_PackedAttr:
3940 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003941 case CXCursor_PureAttr:
3942 return cxstring::createRef("attribute(pure)");
3943 case CXCursor_ConstAttr:
3944 return cxstring::createRef("attribute(const)");
3945 case CXCursor_NoDuplicateAttr:
3946 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003947 case CXCursor_CUDAConstantAttr:
3948 return cxstring::createRef("attribute(constant)");
3949 case CXCursor_CUDADeviceAttr:
3950 return cxstring::createRef("attribute(device)");
3951 case CXCursor_CUDAGlobalAttr:
3952 return cxstring::createRef("attribute(global)");
3953 case CXCursor_CUDAHostAttr:
3954 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004003 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004004 return cxstring::createRef("OMPParallelDirective");
4005 case CXCursor_OMPSimdDirective:
4006 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004007 case CXCursor_OMPForDirective:
4008 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004009 case CXCursor_OMPSectionsDirective:
4010 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004011 case CXCursor_OMPSectionDirective:
4012 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004013 case CXCursor_OMPSingleDirective:
4014 return cxstring::createRef("OMPSingleDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004015 case CXCursor_OMPParallelForDirective:
4016 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004017 case CXCursor_OMPParallelSectionsDirective:
4018 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004019 case CXCursor_OMPTaskDirective:
4020 return cxstring::createRef("OMPTaskDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 }
4022
4023 llvm_unreachable("Unhandled CXCursorKind");
4024}
4025
4026struct GetCursorData {
4027 SourceLocation TokenBeginLoc;
4028 bool PointsAtMacroArgExpansion;
4029 bool VisitedObjCPropertyImplDecl;
4030 SourceLocation VisitedDeclaratorDeclStartLoc;
4031 CXCursor &BestCursor;
4032
4033 GetCursorData(SourceManager &SM,
4034 SourceLocation tokenBegin, CXCursor &outputCursor)
4035 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4036 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4037 VisitedObjCPropertyImplDecl = false;
4038 }
4039};
4040
4041static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4042 CXCursor parent,
4043 CXClientData client_data) {
4044 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4045 CXCursor *BestCursor = &Data->BestCursor;
4046
4047 // If we point inside a macro argument we should provide info of what the
4048 // token is so use the actual cursor, don't replace it with a macro expansion
4049 // cursor.
4050 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4051 return CXChildVisit_Recurse;
4052
4053 if (clang_isDeclaration(cursor.kind)) {
4054 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004055 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4057 if (MD->isImplicit())
4058 return CXChildVisit_Break;
4059
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004060 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4062 // Check that when we have multiple @class references in the same line,
4063 // that later ones do not override the previous ones.
4064 // If we have:
4065 // @class Foo, Bar;
4066 // source ranges for both start at '@', so 'Bar' will end up overriding
4067 // 'Foo' even though the cursor location was at 'Foo'.
4068 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4069 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004070 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4072 if (PrevID != ID &&
4073 !PrevID->isThisDeclarationADefinition() &&
4074 !ID->isThisDeclarationADefinition())
4075 return CXChildVisit_Break;
4076 }
4077
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004078 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4080 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4081 // Check that when we have multiple declarators in the same line,
4082 // that later ones do not override the previous ones.
4083 // If we have:
4084 // int Foo, Bar;
4085 // source ranges for both start at 'int', so 'Bar' will end up overriding
4086 // 'Foo' even though the cursor location was at 'Foo'.
4087 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4088 return CXChildVisit_Break;
4089 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4090
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004091 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4093 (void)PropImp;
4094 // Check that when we have multiple @synthesize in the same line,
4095 // that later ones do not override the previous ones.
4096 // If we have:
4097 // @synthesize Foo, Bar;
4098 // source ranges for both start at '@', so 'Bar' will end up overriding
4099 // 'Foo' even though the cursor location was at 'Foo'.
4100 if (Data->VisitedObjCPropertyImplDecl)
4101 return CXChildVisit_Break;
4102 Data->VisitedObjCPropertyImplDecl = true;
4103 }
4104 }
4105
4106 if (clang_isExpression(cursor.kind) &&
4107 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004108 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 // Avoid having the cursor of an expression replace the declaration cursor
4110 // when the expression source range overlaps the declaration range.
4111 // This can happen for C++ constructor expressions whose range generally
4112 // include the variable declaration, e.g.:
4113 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4114 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4115 D->getLocation() == Data->TokenBeginLoc)
4116 return CXChildVisit_Break;
4117 }
4118 }
4119
4120 // If our current best cursor is the construction of a temporary object,
4121 // don't replace that cursor with a type reference, because we want
4122 // clang_getCursor() to point at the constructor.
4123 if (clang_isExpression(BestCursor->kind) &&
4124 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4125 cursor.kind == CXCursor_TypeRef) {
4126 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4127 // as having the actual point on the type reference.
4128 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4129 return CXChildVisit_Recurse;
4130 }
4131
4132 *BestCursor = cursor;
4133 return CXChildVisit_Recurse;
4134}
4135
4136CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004137 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004138 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004140 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004141
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004142 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4144
4145 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4146 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4147
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004148 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 CXFile SearchFile;
4150 unsigned SearchLine, SearchColumn;
4151 CXFile ResultFile;
4152 unsigned ResultLine, ResultColumn;
4153 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4154 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4155 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004156
4157 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4158 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004159 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004160 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 SearchFileName = clang_getFileName(SearchFile);
4162 ResultFileName = clang_getFileName(ResultFile);
4163 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4164 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004165 *Log << llvm::format("(%s:%d:%d) = %s",
4166 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4167 clang_getCString(KindSpelling))
4168 << llvm::format("(%s:%d:%d):%s%s",
4169 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4170 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 clang_disposeString(SearchFileName);
4172 clang_disposeString(ResultFileName);
4173 clang_disposeString(KindSpelling);
4174 clang_disposeString(USR);
4175
4176 CXCursor Definition = clang_getCursorDefinition(Result);
4177 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4178 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4179 CXString DefinitionKindSpelling
4180 = clang_getCursorKindSpelling(Definition.kind);
4181 CXFile DefinitionFile;
4182 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004183 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004184 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004186 *Log << llvm::format(" -> %s(%s:%d:%d)",
4187 clang_getCString(DefinitionKindSpelling),
4188 clang_getCString(DefinitionFileName),
4189 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 clang_disposeString(DefinitionFileName);
4191 clang_disposeString(DefinitionKindSpelling);
4192 }
4193 }
4194
4195 return Result;
4196}
4197
4198CXCursor clang_getNullCursor(void) {
4199 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4200}
4201
4202unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004203 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4204 // can't set consistently. For example, when visiting a DeclStmt we will set
4205 // it but we don't set it on the result of clang_getCursorDefinition for
4206 // a reference of the same declaration.
4207 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4208 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4209 // to provide that kind of info.
4210 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004211 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004212 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004213 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004214
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 return X == Y;
4216}
4217
4218unsigned clang_hashCursor(CXCursor C) {
4219 unsigned Index = 0;
4220 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4221 Index = 1;
4222
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004223 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 std::make_pair(C.kind, C.data[Index]));
4225}
4226
4227unsigned clang_isInvalid(enum CXCursorKind K) {
4228 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4229}
4230
4231unsigned clang_isDeclaration(enum CXCursorKind K) {
4232 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4233 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4234}
4235
4236unsigned clang_isReference(enum CXCursorKind K) {
4237 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4238}
4239
4240unsigned clang_isExpression(enum CXCursorKind K) {
4241 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4242}
4243
4244unsigned clang_isStatement(enum CXCursorKind K) {
4245 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4246}
4247
4248unsigned clang_isAttribute(enum CXCursorKind K) {
4249 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4250}
4251
4252unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4253 return K == CXCursor_TranslationUnit;
4254}
4255
4256unsigned clang_isPreprocessing(enum CXCursorKind K) {
4257 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4258}
4259
4260unsigned clang_isUnexposed(enum CXCursorKind K) {
4261 switch (K) {
4262 case CXCursor_UnexposedDecl:
4263 case CXCursor_UnexposedExpr:
4264 case CXCursor_UnexposedStmt:
4265 case CXCursor_UnexposedAttr:
4266 return true;
4267 default:
4268 return false;
4269 }
4270}
4271
4272CXCursorKind clang_getCursorKind(CXCursor C) {
4273 return C.kind;
4274}
4275
4276CXSourceLocation clang_getCursorLocation(CXCursor C) {
4277 if (clang_isReference(C.kind)) {
4278 switch (C.kind) {
4279 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004280 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 = getCursorObjCSuperClassRef(C);
4282 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4283 }
4284
4285 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004286 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 = getCursorObjCProtocolRef(C);
4288 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4289 }
4290
4291 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004292 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 = getCursorObjCClassRef(C);
4294 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4295 }
4296
4297 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004298 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4300 }
4301
4302 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004303 std::pair<const TemplateDecl *, SourceLocation> P =
4304 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4306 }
4307
4308 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004309 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4311 }
4312
4313 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004314 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4316 }
4317
4318 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004319 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4321 }
4322
4323 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004324 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 if (!BaseSpec)
4326 return clang_getNullLocation();
4327
4328 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4329 return cxloc::translateSourceLocation(getCursorContext(C),
4330 TSInfo->getTypeLoc().getBeginLoc());
4331
4332 return cxloc::translateSourceLocation(getCursorContext(C),
4333 BaseSpec->getLocStart());
4334 }
4335
4336 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004337 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4339 }
4340
4341 case CXCursor_OverloadedDeclRef:
4342 return cxloc::translateSourceLocation(getCursorContext(C),
4343 getCursorOverloadedDeclRef(C).second);
4344
4345 default:
4346 // FIXME: Need a way to enumerate all non-reference cases.
4347 llvm_unreachable("Missed a reference kind");
4348 }
4349 }
4350
4351 if (clang_isExpression(C.kind))
4352 return cxloc::translateSourceLocation(getCursorContext(C),
4353 getLocationFromExpr(getCursorExpr(C)));
4354
4355 if (clang_isStatement(C.kind))
4356 return cxloc::translateSourceLocation(getCursorContext(C),
4357 getCursorStmt(C)->getLocStart());
4358
4359 if (C.kind == CXCursor_PreprocessingDirective) {
4360 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4361 return cxloc::translateSourceLocation(getCursorContext(C), L);
4362 }
4363
4364 if (C.kind == CXCursor_MacroExpansion) {
4365 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004366 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 return cxloc::translateSourceLocation(getCursorContext(C), L);
4368 }
4369
4370 if (C.kind == CXCursor_MacroDefinition) {
4371 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4372 return cxloc::translateSourceLocation(getCursorContext(C), L);
4373 }
4374
4375 if (C.kind == CXCursor_InclusionDirective) {
4376 SourceLocation L
4377 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4378 return cxloc::translateSourceLocation(getCursorContext(C), L);
4379 }
4380
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004381 if (clang_isAttribute(C.kind)) {
4382 SourceLocation L
4383 = cxcursor::getCursorAttr(C)->getLocation();
4384 return cxloc::translateSourceLocation(getCursorContext(C), L);
4385 }
4386
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 if (!clang_isDeclaration(C.kind))
4388 return clang_getNullLocation();
4389
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004390 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 if (!D)
4392 return clang_getNullLocation();
4393
4394 SourceLocation Loc = D->getLocation();
4395 // FIXME: Multiple variables declared in a single declaration
4396 // currently lack the information needed to correctly determine their
4397 // ranges when accounting for the type-specifier. We use context
4398 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4399 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004400 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 if (!cxcursor::isFirstInDeclGroup(C))
4402 Loc = VD->getLocation();
4403 }
4404
4405 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 Loc = MD->getSelectorStartLoc();
4408
4409 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4410}
4411
4412} // end extern "C"
4413
4414CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4415 assert(TU);
4416
4417 // Guard against an invalid SourceLocation, or we may assert in one
4418 // of the following calls.
4419 if (SLoc.isInvalid())
4420 return clang_getNullCursor();
4421
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004422 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004423
4424 // Translate the given source location to make it point at the beginning of
4425 // the token under the cursor.
4426 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4427 CXXUnit->getASTContext().getLangOpts());
4428
4429 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4430 if (SLoc.isValid()) {
4431 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4432 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4433 /*VisitPreprocessorLast=*/true,
4434 /*VisitIncludedEntities=*/false,
4435 SourceLocation(SLoc));
4436 CursorVis.visitFileRegion();
4437 }
4438
4439 return Result;
4440}
4441
4442static SourceRange getRawCursorExtent(CXCursor C) {
4443 if (clang_isReference(C.kind)) {
4444 switch (C.kind) {
4445 case CXCursor_ObjCSuperClassRef:
4446 return getCursorObjCSuperClassRef(C).second;
4447
4448 case CXCursor_ObjCProtocolRef:
4449 return getCursorObjCProtocolRef(C).second;
4450
4451 case CXCursor_ObjCClassRef:
4452 return getCursorObjCClassRef(C).second;
4453
4454 case CXCursor_TypeRef:
4455 return getCursorTypeRef(C).second;
4456
4457 case CXCursor_TemplateRef:
4458 return getCursorTemplateRef(C).second;
4459
4460 case CXCursor_NamespaceRef:
4461 return getCursorNamespaceRef(C).second;
4462
4463 case CXCursor_MemberRef:
4464 return getCursorMemberRef(C).second;
4465
4466 case CXCursor_CXXBaseSpecifier:
4467 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4468
4469 case CXCursor_LabelRef:
4470 return getCursorLabelRef(C).second;
4471
4472 case CXCursor_OverloadedDeclRef:
4473 return getCursorOverloadedDeclRef(C).second;
4474
4475 case CXCursor_VariableRef:
4476 return getCursorVariableRef(C).second;
4477
4478 default:
4479 // FIXME: Need a way to enumerate all non-reference cases.
4480 llvm_unreachable("Missed a reference kind");
4481 }
4482 }
4483
4484 if (clang_isExpression(C.kind))
4485 return getCursorExpr(C)->getSourceRange();
4486
4487 if (clang_isStatement(C.kind))
4488 return getCursorStmt(C)->getSourceRange();
4489
4490 if (clang_isAttribute(C.kind))
4491 return getCursorAttr(C)->getRange();
4492
4493 if (C.kind == CXCursor_PreprocessingDirective)
4494 return cxcursor::getCursorPreprocessingDirective(C);
4495
4496 if (C.kind == CXCursor_MacroExpansion) {
4497 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004498 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 return TU->mapRangeFromPreamble(Range);
4500 }
4501
4502 if (C.kind == CXCursor_MacroDefinition) {
4503 ASTUnit *TU = getCursorASTUnit(C);
4504 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4505 return TU->mapRangeFromPreamble(Range);
4506 }
4507
4508 if (C.kind == CXCursor_InclusionDirective) {
4509 ASTUnit *TU = getCursorASTUnit(C);
4510 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4511 return TU->mapRangeFromPreamble(Range);
4512 }
4513
4514 if (C.kind == CXCursor_TranslationUnit) {
4515 ASTUnit *TU = getCursorASTUnit(C);
4516 FileID MainID = TU->getSourceManager().getMainFileID();
4517 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4518 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4519 return SourceRange(Start, End);
4520 }
4521
4522 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 if (!D)
4525 return SourceRange();
4526
4527 SourceRange R = D->getSourceRange();
4528 // FIXME: Multiple variables declared in a single declaration
4529 // currently lack the information needed to correctly determine their
4530 // ranges when accounting for the type-specifier. We use context
4531 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4532 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004533 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 if (!cxcursor::isFirstInDeclGroup(C))
4535 R.setBegin(VD->getLocation());
4536 }
4537 return R;
4538 }
4539 return SourceRange();
4540}
4541
4542/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4543/// the decl-specifier-seq for declarations.
4544static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4545 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 if (!D)
4548 return SourceRange();
4549
4550 SourceRange R = D->getSourceRange();
4551
4552 // Adjust the start of the location for declarations preceded by
4553 // declaration specifiers.
4554 SourceLocation StartLoc;
4555 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4556 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4557 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004558 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4560 StartLoc = TI->getTypeLoc().getLocStart();
4561 }
4562
4563 if (StartLoc.isValid() && R.getBegin().isValid() &&
4564 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4565 R.setBegin(StartLoc);
4566
4567 // FIXME: Multiple variables declared in a single declaration
4568 // currently lack the information needed to correctly determine their
4569 // ranges when accounting for the type-specifier. We use context
4570 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4571 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004572 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 if (!cxcursor::isFirstInDeclGroup(C))
4574 R.setBegin(VD->getLocation());
4575 }
4576
4577 return R;
4578 }
4579
4580 return getRawCursorExtent(C);
4581}
4582
4583extern "C" {
4584
4585CXSourceRange clang_getCursorExtent(CXCursor C) {
4586 SourceRange R = getRawCursorExtent(C);
4587 if (R.isInvalid())
4588 return clang_getNullRange();
4589
4590 return cxloc::translateSourceRange(getCursorContext(C), R);
4591}
4592
4593CXCursor clang_getCursorReferenced(CXCursor C) {
4594 if (clang_isInvalid(C.kind))
4595 return clang_getNullCursor();
4596
4597 CXTranslationUnit tu = getCursorTU(C);
4598 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004599 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 if (!D)
4601 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004602 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004604 if (const ObjCPropertyImplDecl *PropImpl =
4605 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4607 return MakeCXCursor(Property, tu);
4608
4609 return C;
4610 }
4611
4612 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004613 const Expr *E = getCursorExpr(C);
4614 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 if (D) {
4616 CXCursor declCursor = MakeCXCursor(D, tu);
4617 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4618 declCursor);
4619 return declCursor;
4620 }
4621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004622 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 return MakeCursorOverloadedDeclRef(Ovl, tu);
4624
4625 return clang_getNullCursor();
4626 }
4627
4628 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004629 const Stmt *S = getCursorStmt(C);
4630 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 if (LabelDecl *label = Goto->getLabel())
4632 if (LabelStmt *labelS = label->getStmt())
4633 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4634
4635 return clang_getNullCursor();
4636 }
4637
4638 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004639 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 return MakeMacroDefinitionCursor(Def, tu);
4641 }
4642
4643 if (!clang_isReference(C.kind))
4644 return clang_getNullCursor();
4645
4646 switch (C.kind) {
4647 case CXCursor_ObjCSuperClassRef:
4648 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4649
4650 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004651 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4652 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 return MakeCXCursor(Def, tu);
4654
4655 return MakeCXCursor(Prot, tu);
4656 }
4657
4658 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004659 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4660 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 return MakeCXCursor(Def, tu);
4662
4663 return MakeCXCursor(Class, tu);
4664 }
4665
4666 case CXCursor_TypeRef:
4667 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4668
4669 case CXCursor_TemplateRef:
4670 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4671
4672 case CXCursor_NamespaceRef:
4673 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4674
4675 case CXCursor_MemberRef:
4676 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4677
4678 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004679 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4681 tu ));
4682 }
4683
4684 case CXCursor_LabelRef:
4685 // FIXME: We end up faking the "parent" declaration here because we
4686 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004687 return MakeCXCursor(getCursorLabelRef(C).first,
4688 cxtu::getASTUnit(tu)->getASTContext()
4689 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 tu);
4691
4692 case CXCursor_OverloadedDeclRef:
4693 return C;
4694
4695 case CXCursor_VariableRef:
4696 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4697
4698 default:
4699 // We would prefer to enumerate all non-reference cursor kinds here.
4700 llvm_unreachable("Unhandled reference cursor kind");
4701 }
4702}
4703
4704CXCursor clang_getCursorDefinition(CXCursor C) {
4705 if (clang_isInvalid(C.kind))
4706 return clang_getNullCursor();
4707
4708 CXTranslationUnit TU = getCursorTU(C);
4709
4710 bool WasReference = false;
4711 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4712 C = clang_getCursorReferenced(C);
4713 WasReference = true;
4714 }
4715
4716 if (C.kind == CXCursor_MacroExpansion)
4717 return clang_getCursorReferenced(C);
4718
4719 if (!clang_isDeclaration(C.kind))
4720 return clang_getNullCursor();
4721
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004722 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 if (!D)
4724 return clang_getNullCursor();
4725
4726 switch (D->getKind()) {
4727 // Declaration kinds that don't really separate the notions of
4728 // declaration and definition.
4729 case Decl::Namespace:
4730 case Decl::Typedef:
4731 case Decl::TypeAlias:
4732 case Decl::TypeAliasTemplate:
4733 case Decl::TemplateTypeParm:
4734 case Decl::EnumConstant:
4735 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004736 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case Decl::IndirectField:
4738 case Decl::ObjCIvar:
4739 case Decl::ObjCAtDefsField:
4740 case Decl::ImplicitParam:
4741 case Decl::ParmVar:
4742 case Decl::NonTypeTemplateParm:
4743 case Decl::TemplateTemplateParm:
4744 case Decl::ObjCCategoryImpl:
4745 case Decl::ObjCImplementation:
4746 case Decl::AccessSpec:
4747 case Decl::LinkageSpec:
4748 case Decl::ObjCPropertyImpl:
4749 case Decl::FileScopeAsm:
4750 case Decl::StaticAssert:
4751 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004752 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case Decl::Label: // FIXME: Is this right??
4754 case Decl::ClassScopeFunctionSpecialization:
4755 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004756 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 return C;
4758
4759 // Declaration kinds that don't make any sense here, but are
4760 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004761 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 case Decl::TranslationUnit:
4763 break;
4764
4765 // Declaration kinds for which the definition is not resolvable.
4766 case Decl::UnresolvedUsingTypename:
4767 case Decl::UnresolvedUsingValue:
4768 break;
4769
4770 case Decl::UsingDirective:
4771 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4772 TU);
4773
4774 case Decl::NamespaceAlias:
4775 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4776
4777 case Decl::Enum:
4778 case Decl::Record:
4779 case Decl::CXXRecord:
4780 case Decl::ClassTemplateSpecialization:
4781 case Decl::ClassTemplatePartialSpecialization:
4782 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4783 return MakeCXCursor(Def, TU);
4784 return clang_getNullCursor();
4785
4786 case Decl::Function:
4787 case Decl::CXXMethod:
4788 case Decl::CXXConstructor:
4789 case Decl::CXXDestructor:
4790 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004791 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004793 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return clang_getNullCursor();
4795 }
4796
Larisse Voufo39a1e502013-08-06 01:03:05 +00004797 case Decl::Var:
4798 case Decl::VarTemplateSpecialization:
4799 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004801 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004802 return MakeCXCursor(Def, TU);
4803 return clang_getNullCursor();
4804 }
4805
4806 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004807 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4809 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4810 return clang_getNullCursor();
4811 }
4812
4813 case Decl::ClassTemplate: {
4814 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4815 ->getDefinition())
4816 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4817 TU);
4818 return clang_getNullCursor();
4819 }
4820
Larisse Voufo39a1e502013-08-06 01:03:05 +00004821 case Decl::VarTemplate: {
4822 if (VarDecl *Def =
4823 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4824 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4825 return clang_getNullCursor();
4826 }
4827
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 case Decl::Using:
4829 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4830 D->getLocation(), TU);
4831
4832 case Decl::UsingShadow:
4833 return clang_getCursorDefinition(
4834 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4835 TU));
4836
4837 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004838 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 if (Method->isThisDeclarationADefinition())
4840 return C;
4841
4842 // Dig out the method definition in the associated
4843 // @implementation, if we have it.
4844 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004845 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4847 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4848 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4849 Method->isInstanceMethod()))
4850 if (Def->isThisDeclarationADefinition())
4851 return MakeCXCursor(Def, TU);
4852
4853 return clang_getNullCursor();
4854 }
4855
4856 case Decl::ObjCCategory:
4857 if (ObjCCategoryImplDecl *Impl
4858 = cast<ObjCCategoryDecl>(D)->getImplementation())
4859 return MakeCXCursor(Impl, TU);
4860 return clang_getNullCursor();
4861
4862 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004863 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 return MakeCXCursor(Def, TU);
4865 return clang_getNullCursor();
4866
4867 case Decl::ObjCInterface: {
4868 // There are two notions of a "definition" for an Objective-C
4869 // class: the interface and its implementation. When we resolved a
4870 // reference to an Objective-C class, produce the @interface as
4871 // the definition; when we were provided with the interface,
4872 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004873 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCXCursor(Def, TU);
4877 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4878 return MakeCXCursor(Impl, TU);
4879 return clang_getNullCursor();
4880 }
4881
4882 case Decl::ObjCProperty:
4883 // FIXME: We don't really know where to find the
4884 // ObjCPropertyImplDecls that implement this property.
4885 return clang_getNullCursor();
4886
4887 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004890 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004891 return MakeCXCursor(Def, TU);
4892
4893 return clang_getNullCursor();
4894
4895 case Decl::Friend:
4896 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4897 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4898 return clang_getNullCursor();
4899
4900 case Decl::FriendTemplate:
4901 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4902 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4903 return clang_getNullCursor();
4904 }
4905
4906 return clang_getNullCursor();
4907}
4908
4909unsigned clang_isCursorDefinition(CXCursor C) {
4910 if (!clang_isDeclaration(C.kind))
4911 return 0;
4912
4913 return clang_getCursorDefinition(C) == C;
4914}
4915
4916CXCursor clang_getCanonicalCursor(CXCursor C) {
4917 if (!clang_isDeclaration(C.kind))
4918 return C;
4919
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004920 if (const Decl *D = getCursorDecl(C)) {
4921 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4923 return MakeCXCursor(CatD, getCursorTU(C));
4924
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004925 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4926 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 return MakeCXCursor(IFD, getCursorTU(C));
4928
4929 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4930 }
4931
4932 return C;
4933}
4934
4935int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4936 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4937}
4938
4939unsigned clang_getNumOverloadedDecls(CXCursor C) {
4940 if (C.kind != CXCursor_OverloadedDeclRef)
4941 return 0;
4942
4943 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004944 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 return E->getNumDecls();
4946
4947 if (OverloadedTemplateStorage *S
4948 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4949 return S->size();
4950
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004951 const Decl *D = Storage.get<const Decl *>();
4952 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 return Using->shadow_size();
4954
4955 return 0;
4956}
4957
4958CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4959 if (cursor.kind != CXCursor_OverloadedDeclRef)
4960 return clang_getNullCursor();
4961
4962 if (index >= clang_getNumOverloadedDecls(cursor))
4963 return clang_getNullCursor();
4964
4965 CXTranslationUnit TU = getCursorTU(cursor);
4966 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004967 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004968 return MakeCXCursor(E->decls_begin()[index], TU);
4969
4970 if (OverloadedTemplateStorage *S
4971 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4972 return MakeCXCursor(S->begin()[index], TU);
4973
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004974 const Decl *D = Storage.get<const Decl *>();
4975 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 // FIXME: This is, unfortunately, linear time.
4977 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4978 std::advance(Pos, index);
4979 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4980 }
4981
4982 return clang_getNullCursor();
4983}
4984
4985void clang_getDefinitionSpellingAndExtent(CXCursor C,
4986 const char **startBuf,
4987 const char **endBuf,
4988 unsigned *startLine,
4989 unsigned *startColumn,
4990 unsigned *endLine,
4991 unsigned *endColumn) {
4992 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004993 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4995
4996 SourceManager &SM = FD->getASTContext().getSourceManager();
4997 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4998 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4999 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5000 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5001 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5002 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5003}
5004
5005
5006CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5007 unsigned PieceIndex) {
5008 RefNamePieces Pieces;
5009
5010 switch (C.kind) {
5011 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005012 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5014 E->getQualifierLoc().getSourceRange());
5015 break;
5016
5017 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005018 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5020 E->getQualifierLoc().getSourceRange(),
5021 E->getOptionalExplicitTemplateArgs());
5022 break;
5023
5024 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005025 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005027 const Expr *Callee = OCE->getCallee();
5028 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 Callee = ICE->getSubExpr();
5030
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005031 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5033 DRE->getQualifierLoc().getSourceRange());
5034 }
5035 break;
5036
5037 default:
5038 break;
5039 }
5040
5041 if (Pieces.empty()) {
5042 if (PieceIndex == 0)
5043 return clang_getCursorExtent(C);
5044 } else if (PieceIndex < Pieces.size()) {
5045 SourceRange R = Pieces[PieceIndex];
5046 if (R.isValid())
5047 return cxloc::translateSourceRange(getCursorContext(C), R);
5048 }
5049
5050 return clang_getNullRange();
5051}
5052
5053void clang_enableStackTraces(void) {
5054 llvm::sys::PrintStackTraceOnErrorSignal();
5055}
5056
5057void clang_executeOnThread(void (*fn)(void*), void *user_data,
5058 unsigned stack_size) {
5059 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5060}
5061
5062} // end: extern "C"
5063
5064//===----------------------------------------------------------------------===//
5065// Token-based Operations.
5066//===----------------------------------------------------------------------===//
5067
5068/* CXToken layout:
5069 * int_data[0]: a CXTokenKind
5070 * int_data[1]: starting token location
5071 * int_data[2]: token length
5072 * int_data[3]: reserved
5073 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5074 * otherwise unused.
5075 */
5076extern "C" {
5077
5078CXTokenKind clang_getTokenKind(CXToken CXTok) {
5079 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5080}
5081
5082CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5083 switch (clang_getTokenKind(CXTok)) {
5084 case CXToken_Identifier:
5085 case CXToken_Keyword:
5086 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005087 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 ->getNameStart());
5089
5090 case CXToken_Literal: {
5091 // We have stashed the starting pointer in the ptr_data field. Use it.
5092 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005093 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 }
5095
5096 case CXToken_Punctuation:
5097 case CXToken_Comment:
5098 break;
5099 }
5100
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005101 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005102 LOG_BAD_TU(TU);
5103 return cxstring::createEmpty();
5104 }
5105
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 // We have to find the starting buffer pointer the hard way, by
5107 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005108 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005110 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005111
5112 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5113 std::pair<FileID, unsigned> LocInfo
5114 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5115 bool Invalid = false;
5116 StringRef Buffer
5117 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5118 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005119 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005120
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005121 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005122}
5123
5124CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005125 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005126 LOG_BAD_TU(TU);
5127 return clang_getNullLocation();
5128 }
5129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 if (!CXXUnit)
5132 return clang_getNullLocation();
5133
5134 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5135 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5136}
5137
5138CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005139 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005140 LOG_BAD_TU(TU);
5141 return clang_getNullRange();
5142 }
5143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005144 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 if (!CXXUnit)
5146 return clang_getNullRange();
5147
5148 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5149 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5150}
5151
5152static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5153 SmallVectorImpl<CXToken> &CXTokens) {
5154 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5155 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005156 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005157 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005158 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005159
5160 // Cannot tokenize across files.
5161 if (BeginLocInfo.first != EndLocInfo.first)
5162 return;
5163
5164 // Create a lexer
5165 bool Invalid = false;
5166 StringRef Buffer
5167 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5168 if (Invalid)
5169 return;
5170
5171 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5172 CXXUnit->getASTContext().getLangOpts(),
5173 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5174 Lex.SetCommentRetentionState(true);
5175
5176 // Lex tokens until we hit the end of the range.
5177 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5178 Token Tok;
5179 bool previousWasAt = false;
5180 do {
5181 // Lex the next token
5182 Lex.LexFromRawLexer(Tok);
5183 if (Tok.is(tok::eof))
5184 break;
5185
5186 // Initialize the CXToken.
5187 CXToken CXTok;
5188
5189 // - Common fields
5190 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5191 CXTok.int_data[2] = Tok.getLength();
5192 CXTok.int_data[3] = 0;
5193
5194 // - Kind-specific fields
5195 if (Tok.isLiteral()) {
5196 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005197 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 } else if (Tok.is(tok::raw_identifier)) {
5199 // Lookup the identifier to determine whether we have a keyword.
5200 IdentifierInfo *II
5201 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5202
5203 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5204 CXTok.int_data[0] = CXToken_Keyword;
5205 }
5206 else {
5207 CXTok.int_data[0] = Tok.is(tok::identifier)
5208 ? CXToken_Identifier
5209 : CXToken_Keyword;
5210 }
5211 CXTok.ptr_data = II;
5212 } else if (Tok.is(tok::comment)) {
5213 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005214 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 } else {
5216 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005217 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 }
5219 CXTokens.push_back(CXTok);
5220 previousWasAt = Tok.is(tok::at);
5221 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5222}
5223
5224void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5225 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005226 LOG_FUNC_SECTION {
5227 *Log << TU << ' ' << Range;
5228 }
5229
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005231 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 if (NumTokens)
5233 *NumTokens = 0;
5234
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005235 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005236 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005237 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005238 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005239
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005240 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 if (!CXXUnit || !Tokens || !NumTokens)
5242 return;
5243
5244 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5245
5246 SourceRange R = cxloc::translateCXSourceRange(Range);
5247 if (R.isInvalid())
5248 return;
5249
5250 SmallVector<CXToken, 32> CXTokens;
5251 getTokens(CXXUnit, R, CXTokens);
5252
5253 if (CXTokens.empty())
5254 return;
5255
5256 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5257 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5258 *NumTokens = CXTokens.size();
5259}
5260
5261void clang_disposeTokens(CXTranslationUnit TU,
5262 CXToken *Tokens, unsigned NumTokens) {
5263 free(Tokens);
5264}
5265
5266} // end: extern "C"
5267
5268//===----------------------------------------------------------------------===//
5269// Token annotation APIs.
5270//===----------------------------------------------------------------------===//
5271
Guy Benyei11169dd2012-12-18 14:30:41 +00005272static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5273 CXCursor parent,
5274 CXClientData client_data);
5275static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5276 CXClientData client_data);
5277
5278namespace {
5279class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 CXToken *Tokens;
5281 CXCursor *Cursors;
5282 unsigned NumTokens;
5283 unsigned TokIdx;
5284 unsigned PreprocessingTokIdx;
5285 CursorVisitor AnnotateVis;
5286 SourceManager &SrcMgr;
5287 bool HasContextSensitiveKeywords;
5288
5289 struct PostChildrenInfo {
5290 CXCursor Cursor;
5291 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005292 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 unsigned BeforeChildrenTokenIdx;
5294 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005295 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005296
5297 CXToken &getTok(unsigned Idx) {
5298 assert(Idx < NumTokens);
5299 return Tokens[Idx];
5300 }
5301 const CXToken &getTok(unsigned Idx) const {
5302 assert(Idx < NumTokens);
5303 return Tokens[Idx];
5304 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 bool MoreTokens() const { return TokIdx < NumTokens; }
5306 unsigned NextToken() const { return TokIdx; }
5307 void AdvanceToken() { ++TokIdx; }
5308 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005309 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 }
5311 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005312 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 }
5314 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005315 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 }
5317
5318 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005319 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 SourceRange);
5321
5322public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005323 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005324 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005325 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005327 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 AnnotateTokensVisitor, this,
5329 /*VisitPreprocessorLast=*/true,
5330 /*VisitIncludedEntities=*/false,
5331 RegionOfInterest,
5332 /*VisitDeclsOnly=*/false,
5333 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005334 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 HasContextSensitiveKeywords(false) { }
5336
5337 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5338 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5339 bool postVisitChildren(CXCursor cursor);
5340 void AnnotateTokens();
5341
5342 /// \brief Determine whether the annotator saw any cursors that have
5343 /// context-sensitive keywords.
5344 bool hasContextSensitiveKeywords() const {
5345 return HasContextSensitiveKeywords;
5346 }
5347
5348 ~AnnotateTokensWorker() {
5349 assert(PostChildrenInfos.empty());
5350 }
5351};
5352}
5353
5354void AnnotateTokensWorker::AnnotateTokens() {
5355 // Walk the AST within the region of interest, annotating tokens
5356 // along the way.
5357 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005358}
Guy Benyei11169dd2012-12-18 14:30:41 +00005359
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005360static inline void updateCursorAnnotation(CXCursor &Cursor,
5361 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005362 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005364 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005365}
5366
5367/// \brief It annotates and advances tokens with a cursor until the comparison
5368//// between the cursor location and the source range is the same as
5369/// \arg compResult.
5370///
5371/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5372/// Pass RangeOverlap to annotate tokens inside a range.
5373void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5374 RangeComparisonResult compResult,
5375 SourceRange range) {
5376 while (MoreTokens()) {
5377 const unsigned I = NextToken();
5378 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005379 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5380 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005381
5382 SourceLocation TokLoc = GetTokenLoc(I);
5383 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005384 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 AdvanceToken();
5386 continue;
5387 }
5388 break;
5389 }
5390}
5391
5392/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005393/// \returns true if it advanced beyond all macro tokens, false otherwise.
5394bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 CXCursor updateC,
5396 RangeComparisonResult compResult,
5397 SourceRange range) {
5398 assert(MoreTokens());
5399 assert(isFunctionMacroToken(NextToken()) &&
5400 "Should be called only for macro arg tokens");
5401
5402 // This works differently than annotateAndAdvanceTokens; because expanded
5403 // macro arguments can have arbitrary translation-unit source order, we do not
5404 // advance the token index one by one until a token fails the range test.
5405 // We only advance once past all of the macro arg tokens if all of them
5406 // pass the range test. If one of them fails we keep the token index pointing
5407 // at the start of the macro arg tokens so that the failing token will be
5408 // annotated by a subsequent annotation try.
5409
5410 bool atLeastOneCompFail = false;
5411
5412 unsigned I = NextToken();
5413 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5414 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5415 if (TokLoc.isFileID())
5416 continue; // not macro arg token, it's parens or comma.
5417 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5418 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5419 Cursors[I] = updateC;
5420 } else
5421 atLeastOneCompFail = true;
5422 }
5423
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005424 if (atLeastOneCompFail)
5425 return false;
5426
5427 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5428 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005429}
5430
5431enum CXChildVisitResult
5432AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 SourceRange cursorRange = getRawCursorExtent(cursor);
5434 if (cursorRange.isInvalid())
5435 return CXChildVisit_Recurse;
5436
5437 if (!HasContextSensitiveKeywords) {
5438 // Objective-C properties can have context-sensitive keywords.
5439 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005440 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5442 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5443 }
5444 // Objective-C methods can have context-sensitive keywords.
5445 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5446 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005447 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5449 if (Method->getObjCDeclQualifier())
5450 HasContextSensitiveKeywords = true;
5451 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005452 for (const auto *P : Method->params()) {
5453 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 HasContextSensitiveKeywords = true;
5455 break;
5456 }
5457 }
5458 }
5459 }
5460 }
5461 // C++ methods can have context-sensitive keywords.
5462 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005463 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5465 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5466 HasContextSensitiveKeywords = true;
5467 }
5468 }
5469 // C++ classes can have context-sensitive keywords.
5470 else if (cursor.kind == CXCursor_StructDecl ||
5471 cursor.kind == CXCursor_ClassDecl ||
5472 cursor.kind == CXCursor_ClassTemplate ||
5473 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005474 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 if (D->hasAttr<FinalAttr>())
5476 HasContextSensitiveKeywords = true;
5477 }
5478 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005479
5480 // Don't override a property annotation with its getter/setter method.
5481 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5482 parent.kind == CXCursor_ObjCPropertyDecl)
5483 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005484
5485 if (clang_isPreprocessing(cursor.kind)) {
5486 // Items in the preprocessing record are kept separate from items in
5487 // declarations, so we keep a separate token index.
5488 unsigned SavedTokIdx = TokIdx;
5489 TokIdx = PreprocessingTokIdx;
5490
5491 // Skip tokens up until we catch up to the beginning of the preprocessing
5492 // entry.
5493 while (MoreTokens()) {
5494 const unsigned I = NextToken();
5495 SourceLocation TokLoc = GetTokenLoc(I);
5496 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5497 case RangeBefore:
5498 AdvanceToken();
5499 continue;
5500 case RangeAfter:
5501 case RangeOverlap:
5502 break;
5503 }
5504 break;
5505 }
5506
5507 // Look at all of the tokens within this range.
5508 while (MoreTokens()) {
5509 const unsigned I = NextToken();
5510 SourceLocation TokLoc = GetTokenLoc(I);
5511 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5512 case RangeBefore:
5513 llvm_unreachable("Infeasible");
5514 case RangeAfter:
5515 break;
5516 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005517 // For macro expansions, just note where the beginning of the macro
5518 // expansion occurs.
5519 if (cursor.kind == CXCursor_MacroExpansion) {
5520 if (TokLoc == cursorRange.getBegin())
5521 Cursors[I] = cursor;
5522 AdvanceToken();
5523 break;
5524 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005525 // We may have already annotated macro names inside macro definitions.
5526 if (Cursors[I].kind != CXCursor_MacroExpansion)
5527 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 continue;
5530 }
5531 break;
5532 }
5533
5534 // Save the preprocessing token index; restore the non-preprocessing
5535 // token index.
5536 PreprocessingTokIdx = TokIdx;
5537 TokIdx = SavedTokIdx;
5538 return CXChildVisit_Recurse;
5539 }
5540
5541 if (cursorRange.isInvalid())
5542 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005543
5544 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 const enum CXCursorKind K = clang_getCursorKind(parent);
5547 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005548 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5549 // Attributes are annotated out-of-order, skip tokens until we reach it.
5550 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005551 ? clang_getNullCursor() : parent;
5552
5553 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5554
5555 // Avoid having the cursor of an expression "overwrite" the annotation of the
5556 // variable declaration that it belongs to.
5557 // This can happen for C++ constructor expressions whose range generally
5558 // include the variable declaration, e.g.:
5559 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005560 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005561 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005562 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005563 const unsigned I = NextToken();
5564 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5565 E->getLocStart() == D->getLocation() &&
5566 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005567 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 AdvanceToken();
5569 }
5570 }
5571 }
5572
5573 // Before recursing into the children keep some state that we are going
5574 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5575 // extra work after the child nodes are visited.
5576 // Note that we don't call VisitChildren here to avoid traversing statements
5577 // code-recursively which can blow the stack.
5578
5579 PostChildrenInfo Info;
5580 Info.Cursor = cursor;
5581 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005582 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 Info.BeforeChildrenTokenIdx = NextToken();
5584 PostChildrenInfos.push_back(Info);
5585
5586 return CXChildVisit_Recurse;
5587}
5588
5589bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5590 if (PostChildrenInfos.empty())
5591 return false;
5592 const PostChildrenInfo &Info = PostChildrenInfos.back();
5593 if (!clang_equalCursors(Info.Cursor, cursor))
5594 return false;
5595
5596 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5597 const unsigned AfterChildren = NextToken();
5598 SourceRange cursorRange = Info.CursorRange;
5599
5600 // Scan the tokens that are at the end of the cursor, but are not captured
5601 // but the child cursors.
5602 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5603
5604 // Scan the tokens that are at the beginning of the cursor, but are not
5605 // capture by the child cursors.
5606 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5607 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5608 break;
5609
5610 Cursors[I] = cursor;
5611 }
5612
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005613 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5614 // encountered the attribute cursor.
5615 if (clang_isAttribute(cursor.kind))
5616 TokIdx = Info.BeforeReachingCursorIdx;
5617
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 PostChildrenInfos.pop_back();
5619 return false;
5620}
5621
5622static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5623 CXCursor parent,
5624 CXClientData client_data) {
5625 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5626}
5627
5628static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5629 CXClientData client_data) {
5630 return static_cast<AnnotateTokensWorker*>(client_data)->
5631 postVisitChildren(cursor);
5632}
5633
5634namespace {
5635
5636/// \brief Uses the macro expansions in the preprocessing record to find
5637/// and mark tokens that are macro arguments. This info is used by the
5638/// AnnotateTokensWorker.
5639class MarkMacroArgTokensVisitor {
5640 SourceManager &SM;
5641 CXToken *Tokens;
5642 unsigned NumTokens;
5643 unsigned CurIdx;
5644
5645public:
5646 MarkMacroArgTokensVisitor(SourceManager &SM,
5647 CXToken *tokens, unsigned numTokens)
5648 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5649
5650 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5651 if (cursor.kind != CXCursor_MacroExpansion)
5652 return CXChildVisit_Continue;
5653
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005654 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 if (macroRange.getBegin() == macroRange.getEnd())
5656 return CXChildVisit_Continue; // it's not a function macro.
5657
5658 for (; CurIdx < NumTokens; ++CurIdx) {
5659 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5660 macroRange.getBegin()))
5661 break;
5662 }
5663
5664 if (CurIdx == NumTokens)
5665 return CXChildVisit_Break;
5666
5667 for (; CurIdx < NumTokens; ++CurIdx) {
5668 SourceLocation tokLoc = getTokenLoc(CurIdx);
5669 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5670 break;
5671
5672 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5673 }
5674
5675 if (CurIdx == NumTokens)
5676 return CXChildVisit_Break;
5677
5678 return CXChildVisit_Continue;
5679 }
5680
5681private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005682 CXToken &getTok(unsigned Idx) {
5683 assert(Idx < NumTokens);
5684 return Tokens[Idx];
5685 }
5686 const CXToken &getTok(unsigned Idx) const {
5687 assert(Idx < NumTokens);
5688 return Tokens[Idx];
5689 }
5690
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005692 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 }
5694
5695 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5696 // The third field is reserved and currently not used. Use it here
5697 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005698 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 }
5700};
5701
5702} // end anonymous namespace
5703
5704static CXChildVisitResult
5705MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5706 CXClientData client_data) {
5707 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5708 parent);
5709}
5710
5711namespace {
5712 struct clang_annotateTokens_Data {
5713 CXTranslationUnit TU;
5714 ASTUnit *CXXUnit;
5715 CXToken *Tokens;
5716 unsigned NumTokens;
5717 CXCursor *Cursors;
5718 };
5719}
5720
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005721/// \brief Used by \c annotatePreprocessorTokens.
5722/// \returns true if lexing was finished, false otherwise.
5723static bool lexNext(Lexer &Lex, Token &Tok,
5724 unsigned &NextIdx, unsigned NumTokens) {
5725 if (NextIdx >= NumTokens)
5726 return true;
5727
5728 ++NextIdx;
5729 Lex.LexFromRawLexer(Tok);
5730 if (Tok.is(tok::eof))
5731 return true;
5732
5733 return false;
5734}
5735
Guy Benyei11169dd2012-12-18 14:30:41 +00005736static void annotatePreprocessorTokens(CXTranslationUnit TU,
5737 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005738 CXCursor *Cursors,
5739 CXToken *Tokens,
5740 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005741 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005742
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005743 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5745 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005746 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005748 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005749
5750 if (BeginLocInfo.first != EndLocInfo.first)
5751 return;
5752
5753 StringRef Buffer;
5754 bool Invalid = false;
5755 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5756 if (Buffer.empty() || Invalid)
5757 return;
5758
5759 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5760 CXXUnit->getASTContext().getLangOpts(),
5761 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5762 Buffer.end());
5763 Lex.SetCommentRetentionState(true);
5764
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005765 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 // Lex tokens in raw mode until we hit the end of the range, to avoid
5767 // entering #includes or expanding macros.
5768 while (true) {
5769 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005770 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5771 break;
5772 unsigned TokIdx = NextIdx-1;
5773 assert(Tok.getLocation() ==
5774 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005775
5776 reprocess:
5777 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005778 // We have found a preprocessing directive. Annotate the tokens
5779 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 //
5781 // FIXME: Some simple tests here could identify macro definitions and
5782 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005783
5784 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005785 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5786 break;
5787
Craig Topper69186e72014-06-08 08:38:04 +00005788 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005789 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005790 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5791 break;
5792
5793 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005794 IdentifierInfo &II =
5795 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005796 SourceLocation MappedTokLoc =
5797 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5798 MI = getMacroInfo(II, MappedTokLoc, TU);
5799 }
5800 }
5801
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005802 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005804 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5805 finished = true;
5806 break;
5807 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005808 // If we are in a macro definition, check if the token was ever a
5809 // macro name and annotate it if that's the case.
5810 if (MI) {
5811 SourceLocation SaveLoc = Tok.getLocation();
5812 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5813 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5814 Tok.setLocation(SaveLoc);
5815 if (MacroDef)
5816 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5817 Tok.getLocation(), TU);
5818 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005819 } while (!Tok.isAtStartOfLine());
5820
5821 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5822 assert(TokIdx <= LastIdx);
5823 SourceLocation EndLoc =
5824 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5825 CXCursor Cursor =
5826 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5827
5828 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005829 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005830
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005831 if (finished)
5832 break;
5833 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005834 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005835 }
5836}
5837
5838// This gets run a separate thread to avoid stack blowout.
5839static void clang_annotateTokensImpl(void *UserData) {
5840 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5841 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5842 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5843 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5844 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5845
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005846 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5848 setThreadBackgroundPriority();
5849
5850 // Determine the region of interest, which contains all of the tokens.
5851 SourceRange RegionOfInterest;
5852 RegionOfInterest.setBegin(
5853 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5854 RegionOfInterest.setEnd(
5855 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5856 Tokens[NumTokens-1])));
5857
Guy Benyei11169dd2012-12-18 14:30:41 +00005858 // Relex the tokens within the source range to look for preprocessing
5859 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005860 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005861
5862 // If begin location points inside a macro argument, set it to the expansion
5863 // location so we can have the full context when annotating semantically.
5864 {
5865 SourceManager &SM = CXXUnit->getSourceManager();
5866 SourceLocation Loc =
5867 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5868 if (Loc.isMacroID())
5869 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5870 }
5871
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5873 // Search and mark tokens that are macro argument expansions.
5874 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5875 Tokens, NumTokens);
5876 CursorVisitor MacroArgMarker(TU,
5877 MarkMacroArgTokensVisitorDelegate, &Visitor,
5878 /*VisitPreprocessorLast=*/true,
5879 /*VisitIncludedEntities=*/false,
5880 RegionOfInterest);
5881 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5882 }
5883
5884 // Annotate all of the source locations in the region of interest that map to
5885 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005886 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005887
5888 // FIXME: We use a ridiculous stack size here because the data-recursion
5889 // algorithm uses a large stack frame than the non-data recursive version,
5890 // and AnnotationTokensWorker currently transforms the data-recursion
5891 // algorithm back into a traditional recursion by explicitly calling
5892 // VisitChildren(). We will need to remove this explicit recursive call.
5893 W.AnnotateTokens();
5894
5895 // If we ran into any entities that involve context-sensitive keywords,
5896 // take another pass through the tokens to mark them as such.
5897 if (W.hasContextSensitiveKeywords()) {
5898 for (unsigned I = 0; I != NumTokens; ++I) {
5899 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5900 continue;
5901
5902 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5903 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005904 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5906 if (Property->getPropertyAttributesAsWritten() != 0 &&
5907 llvm::StringSwitch<bool>(II->getName())
5908 .Case("readonly", true)
5909 .Case("assign", true)
5910 .Case("unsafe_unretained", true)
5911 .Case("readwrite", true)
5912 .Case("retain", true)
5913 .Case("copy", true)
5914 .Case("nonatomic", true)
5915 .Case("atomic", true)
5916 .Case("getter", true)
5917 .Case("setter", true)
5918 .Case("strong", true)
5919 .Case("weak", true)
5920 .Default(false))
5921 Tokens[I].int_data[0] = CXToken_Keyword;
5922 }
5923 continue;
5924 }
5925
5926 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5927 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5928 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5929 if (llvm::StringSwitch<bool>(II->getName())
5930 .Case("in", true)
5931 .Case("out", true)
5932 .Case("inout", true)
5933 .Case("oneway", true)
5934 .Case("bycopy", true)
5935 .Case("byref", true)
5936 .Default(false))
5937 Tokens[I].int_data[0] = CXToken_Keyword;
5938 continue;
5939 }
5940
5941 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5942 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5943 Tokens[I].int_data[0] = CXToken_Keyword;
5944 continue;
5945 }
5946 }
5947 }
5948}
5949
5950extern "C" {
5951
5952void clang_annotateTokens(CXTranslationUnit TU,
5953 CXToken *Tokens, unsigned NumTokens,
5954 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005955 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005956 LOG_BAD_TU(TU);
5957 return;
5958 }
5959 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005960 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005961 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005962 }
5963
5964 LOG_FUNC_SECTION {
5965 *Log << TU << ' ';
5966 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5967 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5968 *Log << clang_getRange(bloc, eloc);
5969 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005970
5971 // Any token we don't specifically annotate will have a NULL cursor.
5972 CXCursor C = clang_getNullCursor();
5973 for (unsigned I = 0; I != NumTokens; ++I)
5974 Cursors[I] = C;
5975
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005976 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 if (!CXXUnit)
5978 return;
5979
5980 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5981
5982 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5983 llvm::CrashRecoveryContext CRC;
5984 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5985 GetSafetyThreadStackSize() * 2)) {
5986 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5987 }
5988}
5989
5990} // end: extern "C"
5991
5992//===----------------------------------------------------------------------===//
5993// Operations for querying linkage of a cursor.
5994//===----------------------------------------------------------------------===//
5995
5996extern "C" {
5997CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5998 if (!clang_isDeclaration(cursor.kind))
5999 return CXLinkage_Invalid;
6000
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006001 const Decl *D = cxcursor::getCursorDecl(cursor);
6002 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006003 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006004 case NoLinkage:
6005 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 case InternalLinkage: return CXLinkage_Internal;
6007 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6008 case ExternalLinkage: return CXLinkage_External;
6009 };
6010
6011 return CXLinkage_Invalid;
6012}
6013} // end: extern "C"
6014
6015//===----------------------------------------------------------------------===//
6016// Operations for querying language of a cursor.
6017//===----------------------------------------------------------------------===//
6018
6019static CXLanguageKind getDeclLanguage(const Decl *D) {
6020 if (!D)
6021 return CXLanguage_C;
6022
6023 switch (D->getKind()) {
6024 default:
6025 break;
6026 case Decl::ImplicitParam:
6027 case Decl::ObjCAtDefsField:
6028 case Decl::ObjCCategory:
6029 case Decl::ObjCCategoryImpl:
6030 case Decl::ObjCCompatibleAlias:
6031 case Decl::ObjCImplementation:
6032 case Decl::ObjCInterface:
6033 case Decl::ObjCIvar:
6034 case Decl::ObjCMethod:
6035 case Decl::ObjCProperty:
6036 case Decl::ObjCPropertyImpl:
6037 case Decl::ObjCProtocol:
6038 return CXLanguage_ObjC;
6039 case Decl::CXXConstructor:
6040 case Decl::CXXConversion:
6041 case Decl::CXXDestructor:
6042 case Decl::CXXMethod:
6043 case Decl::CXXRecord:
6044 case Decl::ClassTemplate:
6045 case Decl::ClassTemplatePartialSpecialization:
6046 case Decl::ClassTemplateSpecialization:
6047 case Decl::Friend:
6048 case Decl::FriendTemplate:
6049 case Decl::FunctionTemplate:
6050 case Decl::LinkageSpec:
6051 case Decl::Namespace:
6052 case Decl::NamespaceAlias:
6053 case Decl::NonTypeTemplateParm:
6054 case Decl::StaticAssert:
6055 case Decl::TemplateTemplateParm:
6056 case Decl::TemplateTypeParm:
6057 case Decl::UnresolvedUsingTypename:
6058 case Decl::UnresolvedUsingValue:
6059 case Decl::Using:
6060 case Decl::UsingDirective:
6061 case Decl::UsingShadow:
6062 return CXLanguage_CPlusPlus;
6063 }
6064
6065 return CXLanguage_C;
6066}
6067
6068extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006069
6070static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6071 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6072 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006073
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006074 switch (D->getAvailability()) {
6075 case AR_Available:
6076 case AR_NotYetIntroduced:
6077 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006078 return getCursorAvailabilityForDecl(
6079 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006080 return CXAvailability_Available;
6081
6082 case AR_Deprecated:
6083 return CXAvailability_Deprecated;
6084
6085 case AR_Unavailable:
6086 return CXAvailability_NotAvailable;
6087 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006088
6089 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006090}
6091
Guy Benyei11169dd2012-12-18 14:30:41 +00006092enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6093 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006094 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6095 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006096
6097 return CXAvailability_Available;
6098}
6099
6100static CXVersion convertVersion(VersionTuple In) {
6101 CXVersion Out = { -1, -1, -1 };
6102 if (In.empty())
6103 return Out;
6104
6105 Out.Major = In.getMajor();
6106
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006107 Optional<unsigned> Minor = In.getMinor();
6108 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006109 Out.Minor = *Minor;
6110 else
6111 return Out;
6112
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006113 Optional<unsigned> Subminor = In.getSubminor();
6114 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006115 Out.Subminor = *Subminor;
6116
6117 return Out;
6118}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006119
6120static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6121 int *always_deprecated,
6122 CXString *deprecated_message,
6123 int *always_unavailable,
6124 CXString *unavailable_message,
6125 CXPlatformAvailability *availability,
6126 int availability_size) {
6127 bool HadAvailAttr = false;
6128 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006129 for (auto A : D->attrs()) {
6130 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006131 HadAvailAttr = true;
6132 if (always_deprecated)
6133 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006134 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006135 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006136 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006137 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006138 continue;
6139 }
6140
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006141 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006142 HadAvailAttr = true;
6143 if (always_unavailable)
6144 *always_unavailable = 1;
6145 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006146 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006147 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6148 }
6149 continue;
6150 }
6151
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006152 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006153 HadAvailAttr = true;
6154 if (N < availability_size) {
6155 availability[N].Platform
6156 = cxstring::createDup(Avail->getPlatform()->getName());
6157 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6158 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6159 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6160 availability[N].Unavailable = Avail->getUnavailable();
6161 availability[N].Message = cxstring::createDup(Avail->getMessage());
6162 }
6163 ++N;
6164 }
6165 }
6166
6167 if (!HadAvailAttr)
6168 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6169 return getCursorPlatformAvailabilityForDecl(
6170 cast<Decl>(EnumConst->getDeclContext()),
6171 always_deprecated,
6172 deprecated_message,
6173 always_unavailable,
6174 unavailable_message,
6175 availability,
6176 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006177
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006178 return N;
6179}
6180
Guy Benyei11169dd2012-12-18 14:30:41 +00006181int clang_getCursorPlatformAvailability(CXCursor cursor,
6182 int *always_deprecated,
6183 CXString *deprecated_message,
6184 int *always_unavailable,
6185 CXString *unavailable_message,
6186 CXPlatformAvailability *availability,
6187 int availability_size) {
6188 if (always_deprecated)
6189 *always_deprecated = 0;
6190 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006191 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 if (always_unavailable)
6193 *always_unavailable = 0;
6194 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006195 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006196
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 if (!clang_isDeclaration(cursor.kind))
6198 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006199
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006200 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 if (!D)
6202 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006203
6204 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6205 deprecated_message,
6206 always_unavailable,
6207 unavailable_message,
6208 availability,
6209 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006210}
6211
6212void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6213 clang_disposeString(availability->Platform);
6214 clang_disposeString(availability->Message);
6215}
6216
6217CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6218 if (clang_isDeclaration(cursor.kind))
6219 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6220
6221 return CXLanguage_Invalid;
6222}
6223
6224 /// \brief If the given cursor is the "templated" declaration
6225 /// descibing a class or function template, return the class or
6226 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006227static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006229 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006230
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006231 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006232 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6233 return FunTmpl;
6234
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006235 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006236 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6237 return ClassTmpl;
6238
6239 return D;
6240}
6241
6242CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6243 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006244 if (const Decl *D = getCursorDecl(cursor)) {
6245 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 if (!DC)
6247 return clang_getNullCursor();
6248
6249 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6250 getCursorTU(cursor));
6251 }
6252 }
6253
6254 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006255 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006256 return MakeCXCursor(D, getCursorTU(cursor));
6257 }
6258
6259 return clang_getNullCursor();
6260}
6261
6262CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6263 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006264 if (const Decl *D = getCursorDecl(cursor)) {
6265 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006266 if (!DC)
6267 return clang_getNullCursor();
6268
6269 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6270 getCursorTU(cursor));
6271 }
6272 }
6273
6274 // FIXME: Note that we can't easily compute the lexical context of a
6275 // statement or expression, so we return nothing.
6276 return clang_getNullCursor();
6277}
6278
6279CXFile clang_getIncludedFile(CXCursor cursor) {
6280 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006281 return nullptr;
6282
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006283 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006284 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006285}
6286
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006287unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6288 if (C.kind != CXCursor_ObjCPropertyDecl)
6289 return CXObjCPropertyAttr_noattr;
6290
6291 unsigned Result = CXObjCPropertyAttr_noattr;
6292 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6293 ObjCPropertyDecl::PropertyAttributeKind Attr =
6294 PD->getPropertyAttributesAsWritten();
6295
6296#define SET_CXOBJCPROP_ATTR(A) \
6297 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6298 Result |= CXObjCPropertyAttr_##A
6299 SET_CXOBJCPROP_ATTR(readonly);
6300 SET_CXOBJCPROP_ATTR(getter);
6301 SET_CXOBJCPROP_ATTR(assign);
6302 SET_CXOBJCPROP_ATTR(readwrite);
6303 SET_CXOBJCPROP_ATTR(retain);
6304 SET_CXOBJCPROP_ATTR(copy);
6305 SET_CXOBJCPROP_ATTR(nonatomic);
6306 SET_CXOBJCPROP_ATTR(setter);
6307 SET_CXOBJCPROP_ATTR(atomic);
6308 SET_CXOBJCPROP_ATTR(weak);
6309 SET_CXOBJCPROP_ATTR(strong);
6310 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6311#undef SET_CXOBJCPROP_ATTR
6312
6313 return Result;
6314}
6315
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006316unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6317 if (!clang_isDeclaration(C.kind))
6318 return CXObjCDeclQualifier_None;
6319
6320 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6321 const Decl *D = getCursorDecl(C);
6322 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6323 QT = MD->getObjCDeclQualifier();
6324 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6325 QT = PD->getObjCDeclQualifier();
6326 if (QT == Decl::OBJC_TQ_None)
6327 return CXObjCDeclQualifier_None;
6328
6329 unsigned Result = CXObjCDeclQualifier_None;
6330 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6331 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6332 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6333 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6334 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6335 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6336
6337 return Result;
6338}
6339
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006340unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6341 if (!clang_isDeclaration(C.kind))
6342 return 0;
6343
6344 const Decl *D = getCursorDecl(C);
6345 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6346 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6347 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6348 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6349
6350 return 0;
6351}
6352
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006353unsigned clang_Cursor_isVariadic(CXCursor C) {
6354 if (!clang_isDeclaration(C.kind))
6355 return 0;
6356
6357 const Decl *D = getCursorDecl(C);
6358 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6359 return FD->isVariadic();
6360 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6361 return MD->isVariadic();
6362
6363 return 0;
6364}
6365
Guy Benyei11169dd2012-12-18 14:30:41 +00006366CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6367 if (!clang_isDeclaration(C.kind))
6368 return clang_getNullRange();
6369
6370 const Decl *D = getCursorDecl(C);
6371 ASTContext &Context = getCursorContext(C);
6372 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6373 if (!RC)
6374 return clang_getNullRange();
6375
6376 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6377}
6378
6379CXString clang_Cursor_getRawCommentText(CXCursor C) {
6380 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006381 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382
6383 const Decl *D = getCursorDecl(C);
6384 ASTContext &Context = getCursorContext(C);
6385 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6386 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6387 StringRef();
6388
6389 // Don't duplicate the string because RawText points directly into source
6390 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006391 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006392}
6393
6394CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6395 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006396 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006397
6398 const Decl *D = getCursorDecl(C);
6399 const ASTContext &Context = getCursorContext(C);
6400 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6401
6402 if (RC) {
6403 StringRef BriefText = RC->getBriefText(Context);
6404
6405 // Don't duplicate the string because RawComment ensures that this memory
6406 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006407 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006408 }
6409
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006410 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006411}
6412
Guy Benyei11169dd2012-12-18 14:30:41 +00006413CXModule clang_Cursor_getModule(CXCursor C) {
6414 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006415 if (const ImportDecl *ImportD =
6416 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 return ImportD->getImportedModule();
6418 }
6419
Craig Topper69186e72014-06-08 08:38:04 +00006420 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421}
6422
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006423CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6424 if (isNotUsableTU(TU)) {
6425 LOG_BAD_TU(TU);
6426 return nullptr;
6427 }
6428 if (!File)
6429 return nullptr;
6430 FileEntry *FE = static_cast<FileEntry *>(File);
6431
6432 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6433 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6434 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6435
6436 if (Module *Mod = Header.getModule()) {
6437 if (Header.getRole() != ModuleMap::ExcludedHeader)
6438 return Mod;
6439 }
6440 return nullptr;
6441}
6442
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006443CXFile clang_Module_getASTFile(CXModule CXMod) {
6444 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006445 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006446 Module *Mod = static_cast<Module*>(CXMod);
6447 return const_cast<FileEntry *>(Mod->getASTFile());
6448}
6449
Guy Benyei11169dd2012-12-18 14:30:41 +00006450CXModule clang_Module_getParent(CXModule CXMod) {
6451 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006452 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 Module *Mod = static_cast<Module*>(CXMod);
6454 return Mod->Parent;
6455}
6456
6457CXString clang_Module_getName(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->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006462}
6463
6464CXString clang_Module_getFullName(CXModule CXMod) {
6465 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006466 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006467 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006468 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006469}
6470
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006471int clang_Module_isSystem(CXModule CXMod) {
6472 if (!CXMod)
6473 return 0;
6474 Module *Mod = static_cast<Module*>(CXMod);
6475 return Mod->IsSystem;
6476}
6477
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006478unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6479 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006480 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006481 LOG_BAD_TU(TU);
6482 return 0;
6483 }
6484 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 return 0;
6486 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006487 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6488 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6489 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006490}
6491
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006492CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6493 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006494 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006495 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006496 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006497 }
6498 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006499 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006500 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006501 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006502
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006503 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6504 if (Index < TopHeaders.size())
6505 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006506
Craig Topper69186e72014-06-08 08:38:04 +00006507 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006508}
6509
6510} // end: extern "C"
6511
6512//===----------------------------------------------------------------------===//
6513// C++ AST instrospection.
6514//===----------------------------------------------------------------------===//
6515
6516extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006517unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6518 if (!clang_isDeclaration(C.kind))
6519 return 0;
6520
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006521 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006522 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006523 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006524 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6525}
6526
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006527unsigned clang_CXXMethod_isConst(CXCursor C) {
6528 if (!clang_isDeclaration(C.kind))
6529 return 0;
6530
6531 const Decl *D = cxcursor::getCursorDecl(C);
6532 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006533 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006534 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6535}
6536
Guy Benyei11169dd2012-12-18 14:30:41 +00006537unsigned clang_CXXMethod_isStatic(CXCursor C) {
6538 if (!clang_isDeclaration(C.kind))
6539 return 0;
6540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006541 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006542 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006543 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006544 return (Method && Method->isStatic()) ? 1 : 0;
6545}
6546
6547unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6548 if (!clang_isDeclaration(C.kind))
6549 return 0;
6550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006551 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006552 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006553 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 return (Method && Method->isVirtual()) ? 1 : 0;
6555}
6556} // end: extern "C"
6557
6558//===----------------------------------------------------------------------===//
6559// Attribute introspection.
6560//===----------------------------------------------------------------------===//
6561
6562extern "C" {
6563CXType clang_getIBOutletCollectionType(CXCursor C) {
6564 if (C.kind != CXCursor_IBOutletCollectionAttr)
6565 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6566
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006567 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6569
6570 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6571}
6572} // end: extern "C"
6573
6574//===----------------------------------------------------------------------===//
6575// Inspecting memory usage.
6576//===----------------------------------------------------------------------===//
6577
6578typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6579
6580static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6581 enum CXTUResourceUsageKind k,
6582 unsigned long amount) {
6583 CXTUResourceUsageEntry entry = { k, amount };
6584 entries.push_back(entry);
6585}
6586
6587extern "C" {
6588
6589const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6590 const char *str = "";
6591 switch (kind) {
6592 case CXTUResourceUsage_AST:
6593 str = "ASTContext: expressions, declarations, and types";
6594 break;
6595 case CXTUResourceUsage_Identifiers:
6596 str = "ASTContext: identifiers";
6597 break;
6598 case CXTUResourceUsage_Selectors:
6599 str = "ASTContext: selectors";
6600 break;
6601 case CXTUResourceUsage_GlobalCompletionResults:
6602 str = "Code completion: cached global results";
6603 break;
6604 case CXTUResourceUsage_SourceManagerContentCache:
6605 str = "SourceManager: content cache allocator";
6606 break;
6607 case CXTUResourceUsage_AST_SideTables:
6608 str = "ASTContext: side tables";
6609 break;
6610 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6611 str = "SourceManager: malloc'ed memory buffers";
6612 break;
6613 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6614 str = "SourceManager: mmap'ed memory buffers";
6615 break;
6616 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6617 str = "ExternalASTSource: malloc'ed memory buffers";
6618 break;
6619 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6620 str = "ExternalASTSource: mmap'ed memory buffers";
6621 break;
6622 case CXTUResourceUsage_Preprocessor:
6623 str = "Preprocessor: malloc'ed memory";
6624 break;
6625 case CXTUResourceUsage_PreprocessingRecord:
6626 str = "Preprocessor: PreprocessingRecord";
6627 break;
6628 case CXTUResourceUsage_SourceManager_DataStructures:
6629 str = "SourceManager: data structures and tables";
6630 break;
6631 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6632 str = "Preprocessor: header search tables";
6633 break;
6634 }
6635 return str;
6636}
6637
6638CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006639 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006640 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006641 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006642 return usage;
6643 }
6644
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006645 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006646 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 ASTContext &astContext = astUnit->getASTContext();
6648
6649 // How much memory is used by AST nodes and types?
6650 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6651 (unsigned long) astContext.getASTAllocatedMemory());
6652
6653 // How much memory is used by identifiers?
6654 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6655 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6656
6657 // How much memory is used for selectors?
6658 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6659 (unsigned long) astContext.Selectors.getTotalMemory());
6660
6661 // How much memory is used by ASTContext's side tables?
6662 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6663 (unsigned long) astContext.getSideTableAllocatedMemory());
6664
6665 // How much memory is used for caching global code completion results?
6666 unsigned long completionBytes = 0;
6667 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006668 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006669 completionBytes = completionAllocator->getTotalMemory();
6670 }
6671 createCXTUResourceUsageEntry(*entries,
6672 CXTUResourceUsage_GlobalCompletionResults,
6673 completionBytes);
6674
6675 // How much memory is being used by SourceManager's content cache?
6676 createCXTUResourceUsageEntry(*entries,
6677 CXTUResourceUsage_SourceManagerContentCache,
6678 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6679
6680 // How much memory is being used by the MemoryBuffer's in SourceManager?
6681 const SourceManager::MemoryBufferSizes &srcBufs =
6682 astUnit->getSourceManager().getMemoryBufferSizes();
6683
6684 createCXTUResourceUsageEntry(*entries,
6685 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6686 (unsigned long) srcBufs.malloc_bytes);
6687 createCXTUResourceUsageEntry(*entries,
6688 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6689 (unsigned long) srcBufs.mmap_bytes);
6690 createCXTUResourceUsageEntry(*entries,
6691 CXTUResourceUsage_SourceManager_DataStructures,
6692 (unsigned long) astContext.getSourceManager()
6693 .getDataStructureSizes());
6694
6695 // How much memory is being used by the ExternalASTSource?
6696 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6697 const ExternalASTSource::MemoryBufferSizes &sizes =
6698 esrc->getMemoryBufferSizes();
6699
6700 createCXTUResourceUsageEntry(*entries,
6701 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6702 (unsigned long) sizes.malloc_bytes);
6703 createCXTUResourceUsageEntry(*entries,
6704 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6705 (unsigned long) sizes.mmap_bytes);
6706 }
6707
6708 // How much memory is being used by the Preprocessor?
6709 Preprocessor &pp = astUnit->getPreprocessor();
6710 createCXTUResourceUsageEntry(*entries,
6711 CXTUResourceUsage_Preprocessor,
6712 pp.getTotalMemory());
6713
6714 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6715 createCXTUResourceUsageEntry(*entries,
6716 CXTUResourceUsage_PreprocessingRecord,
6717 pRec->getTotalMemory());
6718 }
6719
6720 createCXTUResourceUsageEntry(*entries,
6721 CXTUResourceUsage_Preprocessor_HeaderSearch,
6722 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006723
Guy Benyei11169dd2012-12-18 14:30:41 +00006724 CXTUResourceUsage usage = { (void*) entries.get(),
6725 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006726 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006727 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006728 return usage;
6729}
6730
6731void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6732 if (usage.data)
6733 delete (MemUsageEntries*) usage.data;
6734}
6735
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006736CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6737 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006738 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006739 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006740
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006741 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006742 LOG_BAD_TU(TU);
6743 return skipped;
6744 }
6745
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006746 if (!file)
6747 return skipped;
6748
6749 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6750 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6751 if (!ppRec)
6752 return skipped;
6753
6754 ASTContext &Ctx = astUnit->getASTContext();
6755 SourceManager &sm = Ctx.getSourceManager();
6756 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6757 FileID wantedFileID = sm.translateFile(fileEntry);
6758
6759 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6760 std::vector<SourceRange> wantedRanges;
6761 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6762 i != ei; ++i) {
6763 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6764 wantedRanges.push_back(*i);
6765 }
6766
6767 skipped->count = wantedRanges.size();
6768 skipped->ranges = new CXSourceRange[skipped->count];
6769 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6770 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6771
6772 return skipped;
6773}
6774
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006775void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6776 if (ranges) {
6777 delete[] ranges->ranges;
6778 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006779 }
6780}
6781
Guy Benyei11169dd2012-12-18 14:30:41 +00006782} // end extern "C"
6783
6784void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6785 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6786 for (unsigned I = 0; I != Usage.numEntries; ++I)
6787 fprintf(stderr, " %s: %lu\n",
6788 clang_getTUResourceUsageName(Usage.entries[I].kind),
6789 Usage.entries[I].amount);
6790
6791 clang_disposeCXTUResourceUsage(Usage);
6792}
6793
6794//===----------------------------------------------------------------------===//
6795// Misc. utility functions.
6796//===----------------------------------------------------------------------===//
6797
6798/// Default to using an 8 MB stack size on "safety" threads.
6799static unsigned SafetyStackThreadSize = 8 << 20;
6800
6801namespace clang {
6802
6803bool RunSafely(llvm::CrashRecoveryContext &CRC,
6804 void (*Fn)(void*), void *UserData,
6805 unsigned Size) {
6806 if (!Size)
6807 Size = GetSafetyThreadStackSize();
6808 if (Size)
6809 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6810 return CRC.RunSafely(Fn, UserData);
6811}
6812
6813unsigned GetSafetyThreadStackSize() {
6814 return SafetyStackThreadSize;
6815}
6816
6817void SetSafetyThreadStackSize(unsigned Value) {
6818 SafetyStackThreadSize = Value;
6819}
6820
6821}
6822
6823void clang::setThreadBackgroundPriority() {
6824 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6825 return;
6826
Alp Toker1a86ad22014-07-06 06:24:00 +00006827#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6829#endif
6830}
6831
6832void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6833 if (!Unit)
6834 return;
6835
6836 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6837 DEnd = Unit->stored_diag_end();
6838 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006839 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 CXString Msg = clang_formatDiagnostic(&Diag,
6841 clang_defaultDiagnosticDisplayOptions());
6842 fprintf(stderr, "%s\n", clang_getCString(Msg));
6843 clang_disposeString(Msg);
6844 }
6845#ifdef LLVM_ON_WIN32
6846 // On Windows, force a flush, since there may be multiple copies of
6847 // stderr and stdout in the file system, all with different buffers
6848 // but writing to the same device.
6849 fflush(stderr);
6850#endif
6851}
6852
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006853MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6854 SourceLocation MacroDefLoc,
6855 CXTranslationUnit TU){
6856 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006860
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006861 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006862 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006863 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006864 if (MD) {
6865 for (MacroDirective::DefInfo
6866 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6867 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6868 return Def.getMacroInfo();
6869 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006870 }
6871
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873}
6874
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006875const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6876 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006878 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006879 const IdentifierInfo *II = MacroDef->getName();
6880 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006881 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882
6883 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6884}
6885
6886MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6887 const Token &Tok,
6888 CXTranslationUnit TU) {
6889 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006890 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006891 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006892 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006893
6894 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006895 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006896 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6897 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006898 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006899
6900 // Check that the token is inside the definition and not its argument list.
6901 SourceManager &SM = Unit->getSourceManager();
6902 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006903 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006904 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006905 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006906
6907 Preprocessor &PP = Unit->getPreprocessor();
6908 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6909 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006910 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006911
Alp Toker2d57cea2014-05-17 04:53:25 +00006912 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006913 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006914 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006915
6916 // Check that the identifier is not one of the macro arguments.
6917 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006918 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006919
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006920 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6921 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006922 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006923
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006924 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006925}
6926
6927MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6928 SourceLocation Loc,
6929 CXTranslationUnit TU) {
6930 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006931 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006932
6933 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006934 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006935 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006936 Preprocessor &PP = Unit->getPreprocessor();
6937 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006938 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006939 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6940 Token Tok;
6941 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006942 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006943
6944 return checkForMacroInMacroDefinition(MI, Tok, TU);
6945}
6946
Guy Benyei11169dd2012-12-18 14:30:41 +00006947extern "C" {
6948
6949CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006950 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006951}
6952
6953} // end: extern "C"
6954
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006955Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6956 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006957 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006958 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006959 if (Unit->isMainFileAST())
6960 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006961 return *this;
6962 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006963 } else {
6964 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006965 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006966 return *this;
6967}
6968
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006969Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6970 *this << FE->getName();
6971 return *this;
6972}
6973
6974Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6975 CXString cursorName = clang_getCursorDisplayName(cursor);
6976 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6977 clang_disposeString(cursorName);
6978 return *this;
6979}
6980
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006981Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6982 CXFile File;
6983 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006984 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006985 CXString FileName = clang_getFileName(File);
6986 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6987 clang_disposeString(FileName);
6988 return *this;
6989}
6990
6991Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6992 CXSourceLocation BLoc = clang_getRangeStart(range);
6993 CXSourceLocation ELoc = clang_getRangeEnd(range);
6994
6995 CXFile BFile;
6996 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006997 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006998
6999 CXFile EFile;
7000 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007001 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007002
7003 CXString BFileName = clang_getFileName(BFile);
7004 if (BFile == EFile) {
7005 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7006 BLine, BColumn, ELine, EColumn);
7007 } else {
7008 CXString EFileName = clang_getFileName(EFile);
7009 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7010 BLine, BColumn)
7011 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7012 ELine, EColumn);
7013 clang_disposeString(EFileName);
7014 }
7015 clang_disposeString(BFileName);
7016 return *this;
7017}
7018
7019Logger &cxindex::Logger::operator<<(CXString Str) {
7020 *this << clang_getCString(Str);
7021 return *this;
7022}
7023
7024Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7025 LogOS << Fmt;
7026 return *this;
7027}
7028
Chandler Carruth37ad2582014-06-27 15:14:39 +00007029static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7030
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007031cxindex::Logger::~Logger() {
7032 LogOS.flush();
7033
Chandler Carruth37ad2582014-06-27 15:14:39 +00007034 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007035
7036 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7037
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007038 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007039 OS << "[libclang:" << Name << ':';
7040
Alp Toker1a86ad22014-07-06 06:24:00 +00007041#ifdef USE_DARWIN_THREADS
7042 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007043 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7044 OS << tid << ':';
7045#endif
7046
7047 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7048 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7049 OS << Msg.str() << '\n';
7050
7051 if (Trace) {
7052 llvm::sys::PrintStackTrace(stderr);
7053 OS << "--------------------------------------------------\n";
7054 }
7055}