blob: e83a659b1f2f129b8a5329a0e514fd8ae6ab8bda [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);
Alexander Musman80c22892014-07-17 08:54:58 +00001863 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001864 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001865 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001866 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867
Guy Benyei11169dd2012-12-18 14:30:41 +00001868private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1871 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1873 void AddStmt(const Stmt *S);
1874 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001875 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001877 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001878};
1879} // end anonyous namespace
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 // 'S' should always be non-null, since it comes from the
1883 // statement we are visiting.
1884 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1885}
1886
1887void
1888EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1889 if (Qualifier)
1890 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1891}
1892
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (S)
1895 WL.push_back(StmtVisit(S, Parent));
1896}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 if (D)
1899 WL.push_back(DeclVisit(D, Parent, isFirst));
1900}
1901void EnqueueVisitor::
1902 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1903 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001905}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (D)
1908 WL.push_back(MemberRefVisit(D, L, Parent));
1909}
1910void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1911 if (TI)
1912 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1913 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001916 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001917 AddStmt(*Child);
1918 }
1919 if (size == WL.size())
1920 return;
1921 // Now reverse the entries we just added. This will match the DFS
1922 // ordering performed by the worklist.
1923 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1924 std::reverse(I, E);
1925}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001926namespace {
1927class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1928 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001929 /// \brief Process clauses with list of variables.
1930 template <typename T>
1931 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932public:
1933 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1934#define OPENMP_CLAUSE(Name, Class) \
1935 void Visit##Class(const Class *C);
1936#include "clang/Basic/OpenMPKinds.def"
1937};
1938
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001939void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1940 Visitor->AddStmt(C->getCondition());
1941}
1942
Alexey Bataev3778b602014-07-17 07:32:53 +00001943void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1944 Visitor->AddStmt(C->getCondition());
1945}
1946
Alexey Bataev568a8332014-03-06 06:15:19 +00001947void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1948 Visitor->AddStmt(C->getNumThreads());
1949}
1950
Alexey Bataev62c87d22014-03-21 04:51:18 +00001951void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1952 Visitor->AddStmt(C->getSafelen());
1953}
1954
Alexander Musman8bd31e62014-05-27 15:12:19 +00001955void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1956 Visitor->AddStmt(C->getNumForLoops());
1957}
1958
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001960
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001961void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1962
Alexey Bataev56dafe82014-06-20 07:16:17 +00001963void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1964 Visitor->AddStmt(C->getChunkSize());
1965}
1966
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001967void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1968
Alexey Bataev236070f2014-06-20 11:19:47 +00001969void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1970
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001971void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1972
Alexey Bataev756c1962013-09-24 03:17:45 +00001973template<typename T>
1974void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001975 for (const auto *I : Node->varlists())
1976 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001977}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001978
1979void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001980 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001981}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001982void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1983 const OMPFirstprivateClause *C) {
1984 VisitOMPClauseList(C);
1985}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001986void OMPClauseEnqueue::VisitOMPLastprivateClause(
1987 const OMPLastprivateClause *C) {
1988 VisitOMPClauseList(C);
1989}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001990void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001991 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001992}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001993void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1994 VisitOMPClauseList(C);
1995}
Alexander Musman8dba6642014-04-22 13:09:42 +00001996void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1997 VisitOMPClauseList(C);
1998 Visitor->AddStmt(C->getStep());
1999}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002000void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2001 VisitOMPClauseList(C);
2002 Visitor->AddStmt(C->getAlignment());
2003}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002004void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2005 VisitOMPClauseList(C);
2006}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002007void
2008OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2009 VisitOMPClauseList(C);
2010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011}
Alexey Bataev756c1962013-09-24 03:17:45 +00002012
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2014 unsigned size = WL.size();
2015 OMPClauseEnqueue Visitor(this);
2016 Visitor.Visit(S);
2017 if (size == WL.size())
2018 return;
2019 // Now reverse the entries we just added. This will match the DFS
2020 // ordering performed by the worklist.
2021 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2022 std::reverse(I, E);
2023}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002024void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2026}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002027void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 AddDecl(B->getBlockDecl());
2029}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 EnqueueChildren(E);
2032 AddTypeLoc(E->getTypeSourceInfo());
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2035 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 E = S->body_rend(); I != E; ++I) {
2037 AddStmt(*I);
2038 }
2039}
2040void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 AddStmt(S->getSubStmt());
2043 AddDeclarationNameInfo(S);
2044 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2045 AddNestedNameSpecifierLoc(QualifierLoc);
2046}
2047
2048void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2051 AddDeclarationNameInfo(E);
2052 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2053 AddNestedNameSpecifierLoc(QualifierLoc);
2054 if (!E->isImplicitAccess())
2055 AddStmt(E->getBase());
2056}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 // Enqueue the initializer , if any.
2059 AddStmt(E->getInitializer());
2060 // Enqueue the array size, if any.
2061 AddStmt(E->getArraySize());
2062 // Enqueue the allocated type.
2063 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2064 // Enqueue the placement arguments.
2065 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2066 AddStmt(E->getPlacementArg(I-1));
2067}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002069 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2070 AddStmt(CE->getArg(I-1));
2071 AddStmt(CE->getCallee());
2072 AddStmt(CE->getArg(0));
2073}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2075 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 // Visit the name of the type being destroyed.
2077 AddTypeLoc(E->getDestroyedTypeInfo());
2078 // Visit the scope type that looks disturbingly like the nested-name-specifier
2079 // but isn't.
2080 AddTypeLoc(E->getScopeTypeInfo());
2081 // Visit the nested-name-specifier.
2082 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2083 AddNestedNameSpecifierLoc(QualifierLoc);
2084 // Visit base expression.
2085 AddStmt(E->getBase());
2086}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2088 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 AddTypeLoc(E->getTypeSourceInfo());
2090}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2092 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 EnqueueChildren(E);
2094 AddTypeLoc(E->getTypeSourceInfo());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 if (E->isTypeOperand())
2099 AddTypeLoc(E->getTypeOperandSourceInfo());
2100}
2101
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2103 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 EnqueueChildren(E);
2105 AddTypeLoc(E->getTypeSourceInfo());
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 EnqueueChildren(E);
2109 if (E->isTypeOperand())
2110 AddTypeLoc(E->getTypeOperandSourceInfo());
2111}
2112
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 EnqueueChildren(S);
2115 AddDecl(S->getExceptionDecl());
2116}
2117
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 if (DR->hasExplicitTemplateArgs()) {
2120 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2121 }
2122 WL.push_back(DeclRefExprParts(DR, Parent));
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2125 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2127 AddDeclarationNameInfo(E);
2128 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 unsigned size = WL.size();
2132 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002133 for (const auto *D : S->decls()) {
2134 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 isFirst = false;
2136 }
2137 if (size == WL.size())
2138 return;
2139 // Now reverse the entries we just added. This will match the DFS
2140 // ordering performed by the worklist.
2141 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2142 std::reverse(I, E);
2143}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 D = E->designators_rbegin(), DEnd = E->designators_rend();
2148 D != DEnd; ++D) {
2149 if (D->isFieldDesignator()) {
2150 if (FieldDecl *Field = D->getField())
2151 AddMemberRef(Field, D->getFieldLoc());
2152 continue;
2153 }
2154 if (D->isArrayDesignator()) {
2155 AddStmt(E->getArrayIndex(*D));
2156 continue;
2157 }
2158 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2159 AddStmt(E->getArrayRangeEnd(*D));
2160 AddStmt(E->getArrayRangeStart(*D));
2161 }
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 EnqueueChildren(E);
2165 AddTypeLoc(E->getTypeInfoAsWritten());
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 AddStmt(FS->getBody());
2169 AddStmt(FS->getInc());
2170 AddStmt(FS->getCond());
2171 AddDecl(FS->getConditionVariable());
2172 AddStmt(FS->getInit());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2176}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 AddStmt(If->getElse());
2179 AddStmt(If->getThen());
2180 AddStmt(If->getCond());
2181 AddDecl(If->getConditionVariable());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 // We care about the syntactic form of the initializer list, only.
2185 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2186 IE = Syntactic;
2187 EnqueueChildren(IE);
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 WL.push_back(MemberExprParts(M, Parent));
2191
2192 // If the base of the member access expression is an implicit 'this', don't
2193 // visit it.
2194 // FIXME: If we ever want to show these implicit accesses, this will be
2195 // unfortunate. However, clang_getCursor() relies on this behavior.
2196 if (!M->isImplicitAccess())
2197 AddStmt(M->getBase());
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddTypeLoc(E->getEncodedTypeSourceInfo());
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(M);
2204 AddTypeLoc(M->getClassReceiverTypeInfo());
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 // Visit the components of the offsetof expression.
2208 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2209 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2210 const OffsetOfNode &Node = E->getComponent(I-1);
2211 switch (Node.getKind()) {
2212 case OffsetOfNode::Array:
2213 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2214 break;
2215 case OffsetOfNode::Field:
2216 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2217 break;
2218 case OffsetOfNode::Identifier:
2219 case OffsetOfNode::Base:
2220 continue;
2221 }
2222 }
2223 // Visit the type into which we're computing the offset.
2224 AddTypeLoc(E->getTypeSourceInfo());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2228 WL.push_back(OverloadExprParts(E, Parent));
2229}
2230void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 EnqueueChildren(E);
2233 if (E->isArgumentType())
2234 AddTypeLoc(E->getArgumentTypeInfo());
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 EnqueueChildren(S);
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 AddStmt(S->getBody());
2241 AddStmt(S->getCond());
2242 AddDecl(S->getConditionVariable());
2243}
2244
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 AddStmt(W->getBody());
2247 AddStmt(W->getCond());
2248 AddDecl(W->getConditionVariable());
2249}
2250
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 for (unsigned I = E->getNumArgs(); I > 0; --I)
2253 AddTypeLoc(E->getArg(I-1));
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 AddTypeLoc(E->getQueriedTypeSourceInfo());
2258}
2259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueChildren(E);
2262}
2263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 VisitOverloadExpr(U);
2266 if (!U->isImplicitAccess())
2267 AddStmt(U->getBase());
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 AddStmt(E->getSubExpr());
2271 AddTypeLoc(E->getWrittenTypeInfo());
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 WL.push_back(SizeOfPackExprParts(E, Parent));
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 // If the opaque value has a source expression, just transparently
2278 // visit that. This is useful for (e.g.) pseudo-object expressions.
2279 if (Expr *SourceExpr = E->getSourceExpr())
2280 return Visit(SourceExpr);
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 AddStmt(E->getBody());
2284 WL.push_back(LambdaExprParts(E, Parent));
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 // Treat the expression like its syntactic form.
2288 Visit(E->getSyntacticForm());
2289}
2290
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002291void EnqueueVisitor::VisitOMPExecutableDirective(
2292 const OMPExecutableDirective *D) {
2293 EnqueueChildren(D);
2294 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2295 E = D->clauses().end();
2296 I != E; ++I)
2297 EnqueueChildren(*I);
2298}
2299
2300void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2301 VisitOMPExecutableDirective(D);
2302}
2303
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002304void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2305 VisitOMPExecutableDirective(D);
2306}
2307
Alexey Bataevf29276e2014-06-18 04:14:57 +00002308void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2309 VisitOMPExecutableDirective(D);
2310}
2311
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002312void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2313 VisitOMPExecutableDirective(D);
2314}
2315
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002316void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002320void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2321 VisitOMPExecutableDirective(D);
2322}
2323
Alexander Musman80c22892014-07-17 08:54:58 +00002324void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2325 VisitOMPExecutableDirective(D);
2326}
2327
Alexey Bataev4acb8592014-07-07 13:01:15 +00002328void
2329EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2330 VisitOMPExecutableDirective(D);
2331}
2332
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002333void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2334 const OMPParallelSectionsDirective *D) {
2335 VisitOMPExecutableDirective(D);
2336}
2337
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002338void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2339 VisitOMPExecutableDirective(D);
2340}
2341
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2344}
2345
2346bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2347 if (RegionOfInterest.isValid()) {
2348 SourceRange Range = getRawCursorExtent(C);
2349 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2350 return false;
2351 }
2352 return true;
2353}
2354
2355bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2356 while (!WL.empty()) {
2357 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002358 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002359
2360 // Set the Parent field, then back to its old value once we're done.
2361 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2362
2363 switch (LI.getKind()) {
2364 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002366 if (!D)
2367 continue;
2368
2369 // For now, perform default visitation for Decls.
2370 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2371 cast<DeclVisit>(&LI)->isFirst())))
2372 return true;
2373
2374 continue;
2375 }
2376 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2377 const ASTTemplateArgumentListInfo *ArgList =
2378 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2379 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2380 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2381 Arg != ArgEnd; ++Arg) {
2382 if (VisitTemplateArgumentLoc(*Arg))
2383 return true;
2384 }
2385 continue;
2386 }
2387 case VisitorJob::TypeLocVisitKind: {
2388 // Perform default visitation for TypeLocs.
2389 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 if (LabelStmt *stmt = LS->getStmt()) {
2396 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2397 TU))) {
2398 return true;
2399 }
2400 }
2401 continue;
2402 }
2403
2404 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2405 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2406 if (VisitNestedNameSpecifierLoc(V->get()))
2407 return true;
2408 continue;
2409 }
2410
2411 case VisitorJob::DeclarationNameInfoVisitKind: {
2412 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2413 ->get()))
2414 return true;
2415 continue;
2416 }
2417 case VisitorJob::MemberRefVisitKind: {
2418 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2419 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2420 return true;
2421 continue;
2422 }
2423 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002424 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002425 if (!S)
2426 continue;
2427
2428 // Update the current cursor.
2429 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2430 if (!IsInRegionOfInterest(Cursor))
2431 continue;
2432 switch (Visitor(Cursor, Parent, ClientData)) {
2433 case CXChildVisit_Break: return true;
2434 case CXChildVisit_Continue: break;
2435 case CXChildVisit_Recurse:
2436 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002437 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 EnqueueWorkList(WL, S);
2439 break;
2440 }
2441 continue;
2442 }
2443 case VisitorJob::MemberExprPartsKind: {
2444 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002446
2447 // Visit the nested-name-specifier
2448 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2449 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2450 return true;
2451
2452 // Visit the declaration name.
2453 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2454 return true;
2455
2456 // Visit the explicitly-specified template arguments, if any.
2457 if (M->hasExplicitTemplateArgs()) {
2458 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2459 *ArgEnd = Arg + M->getNumTemplateArgs();
2460 Arg != ArgEnd; ++Arg) {
2461 if (VisitTemplateArgumentLoc(*Arg))
2462 return true;
2463 }
2464 }
2465 continue;
2466 }
2467 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002468 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 // Visit nested-name-specifier, if present.
2470 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2471 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2472 return true;
2473 // Visit declaration name.
2474 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2475 return true;
2476 continue;
2477 }
2478 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 // Visit the nested-name-specifier.
2481 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2482 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2483 return true;
2484 // Visit the declaration name.
2485 if (VisitDeclarationNameInfo(O->getNameInfo()))
2486 return true;
2487 // Visit the overloaded declaration reference.
2488 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2489 return true;
2490 continue;
2491 }
2492 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002493 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 NamedDecl *Pack = E->getPack();
2495 if (isa<TemplateTypeParmDecl>(Pack)) {
2496 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2497 E->getPackLoc(), TU)))
2498 return true;
2499
2500 continue;
2501 }
2502
2503 if (isa<TemplateTemplateParmDecl>(Pack)) {
2504 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2505 E->getPackLoc(), TU)))
2506 return true;
2507
2508 continue;
2509 }
2510
2511 // Non-type template parameter packs and function parameter packs are
2512 // treated like DeclRefExpr cursors.
2513 continue;
2514 }
2515
2516 case VisitorJob::LambdaExprPartsKind: {
2517 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002518 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2520 CEnd = E->explicit_capture_end();
2521 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002522 // FIXME: Lambda init-captures.
2523 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002525
Guy Benyei11169dd2012-12-18 14:30:41 +00002526 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2527 C->getLocation(),
2528 TU)))
2529 return true;
2530 }
2531
2532 // Visit parameters and return type, if present.
2533 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2534 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2535 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2536 // Visit the whole type.
2537 if (Visit(TL))
2538 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002539 } else if (FunctionProtoTypeLoc Proto =
2540 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002541 if (E->hasExplicitParameters()) {
2542 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002543 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2544 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 return true;
2546 } else {
2547 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002548 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 return true;
2550 }
2551 }
2552 }
2553 break;
2554 }
2555
2556 case VisitorJob::PostChildrenVisitKind:
2557 if (PostChildrenVisitor(Parent, ClientData))
2558 return true;
2559 break;
2560 }
2561 }
2562 return false;
2563}
2564
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002566 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002567 if (!WorkListFreeList.empty()) {
2568 WL = WorkListFreeList.back();
2569 WL->clear();
2570 WorkListFreeList.pop_back();
2571 }
2572 else {
2573 WL = new VisitorWorkList();
2574 WorkListCache.push_back(WL);
2575 }
2576 EnqueueWorkList(*WL, S);
2577 bool result = RunVisitorWorkList(*WL);
2578 WorkListFreeList.push_back(WL);
2579 return result;
2580}
2581
2582namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002583typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002584RefNamePieces
2585buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2586 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2587 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002588 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2589 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2590 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2591
2592 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2593
2594 RefNamePieces Pieces;
2595
2596 if (WantQualifier && QLoc.isValid())
2597 Pieces.push_back(QLoc);
2598
2599 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2600 Pieces.push_back(NI.getLoc());
2601
2602 if (WantTemplateArgs && TemplateArgs)
2603 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2604 TemplateArgs->RAngleLoc));
2605
2606 if (Kind == DeclarationName::CXXOperatorName) {
2607 Pieces.push_back(SourceLocation::getFromRawEncoding(
2608 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2609 Pieces.push_back(SourceLocation::getFromRawEncoding(
2610 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2611 }
2612
2613 if (WantSinglePiece) {
2614 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2615 Pieces.clear();
2616 Pieces.push_back(R);
2617 }
2618
2619 return Pieces;
2620}
2621}
2622
2623//===----------------------------------------------------------------------===//
2624// Misc. API hooks.
2625//===----------------------------------------------------------------------===//
2626
Chad Rosier05c71aa2013-03-27 18:28:23 +00002627static void fatal_error_handler(void *user_data, const std::string& reason,
2628 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002629 // Write the result out to stderr avoiding errs() because raw_ostreams can
2630 // call report_fatal_error.
2631 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2632 ::abort();
2633}
2634
Chandler Carruth66660742014-06-27 16:37:27 +00002635namespace {
2636struct RegisterFatalErrorHandler {
2637 RegisterFatalErrorHandler() {
2638 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2639 }
2640};
2641}
2642
2643static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2644
Guy Benyei11169dd2012-12-18 14:30:41 +00002645extern "C" {
2646CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2647 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002648 // We use crash recovery to make some of our APIs more reliable, implicitly
2649 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002650 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2651 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002652
Chandler Carruth66660742014-06-27 16:37:27 +00002653 // Look through the managed static to trigger construction of the managed
2654 // static which registers our fatal error handler. This ensures it is only
2655 // registered once.
2656 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002657
2658 CIndexer *CIdxr = new CIndexer();
2659 if (excludeDeclarationsFromPCH)
2660 CIdxr->setOnlyLocalDecls();
2661 if (displayDiagnostics)
2662 CIdxr->setDisplayDiagnostics();
2663
2664 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2665 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2666 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2667 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2668 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2669 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2670
2671 return CIdxr;
2672}
2673
2674void clang_disposeIndex(CXIndex CIdx) {
2675 if (CIdx)
2676 delete static_cast<CIndexer *>(CIdx);
2677}
2678
2679void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2680 if (CIdx)
2681 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2682}
2683
2684unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2685 if (CIdx)
2686 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2687 return 0;
2688}
2689
2690void clang_toggleCrashRecovery(unsigned isEnabled) {
2691 if (isEnabled)
2692 llvm::CrashRecoveryContext::Enable();
2693 else
2694 llvm::CrashRecoveryContext::Disable();
2695}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002696
Guy Benyei11169dd2012-12-18 14:30:41 +00002697CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2698 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002699 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002700 enum CXErrorCode Result =
2701 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002702 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703 assert((TU && Result == CXError_Success) ||
2704 (!TU && Result != CXError_Success));
2705 return TU;
2706}
2707
2708enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2709 const char *ast_filename,
2710 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002711 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002712 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002713
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002714 if (!CIdx || !ast_filename || !out_TU)
2715 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002716
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002717 LOG_FUNC_SECTION {
2718 *Log << ast_filename;
2719 }
2720
Guy Benyei11169dd2012-12-18 14:30:41 +00002721 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2722 FileSystemOptions FileSystemOpts;
2723
2724 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002725 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002726 CXXIdx->getOnlyLocalDecls(), None,
2727 /*CaptureDiagnostics=*/true,
2728 /*AllowPCHWithCompilerErrors=*/true,
2729 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002730 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2731 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002732}
2733
2734unsigned clang_defaultEditingTranslationUnitOptions() {
2735 return CXTranslationUnit_PrecompiledPreamble |
2736 CXTranslationUnit_CacheCompletionResults;
2737}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002738
Guy Benyei11169dd2012-12-18 14:30:41 +00002739CXTranslationUnit
2740clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2741 const char *source_filename,
2742 int num_command_line_args,
2743 const char * const *command_line_args,
2744 unsigned num_unsaved_files,
2745 struct CXUnsavedFile *unsaved_files) {
2746 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2747 return clang_parseTranslationUnit(CIdx, source_filename,
2748 command_line_args, num_command_line_args,
2749 unsaved_files, num_unsaved_files,
2750 Options);
2751}
2752
2753struct ParseTranslationUnitInfo {
2754 CXIndex CIdx;
2755 const char *source_filename;
2756 const char *const *command_line_args;
2757 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002758 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002760 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002761 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002762};
2763static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002764 const ParseTranslationUnitInfo *PTUI =
2765 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 CXIndex CIdx = PTUI->CIdx;
2767 const char *source_filename = PTUI->source_filename;
2768 const char * const *command_line_args = PTUI->command_line_args;
2769 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002771 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002772
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002773 // Set up the initial return values.
2774 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002775 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002776
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002777 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002778 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002779 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002780 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002781 }
2782
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2784
2785 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2786 setThreadBackgroundPriority();
2787
2788 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2789 // FIXME: Add a flag for modules.
2790 TranslationUnitKind TUKind
2791 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002792 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 = options & CXTranslationUnit_CacheCompletionResults;
2794 bool IncludeBriefCommentsInCodeCompletion
2795 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2796 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2797 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2798
2799 // Configure the diagnostics.
2800 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002801 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002802
2803 // Recover resources if we crash before exiting this function.
2804 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2805 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002806 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002807
Ahmed Charlesb8984322014-03-07 20:03:18 +00002808 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2809 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002810
2811 // Recover resources if we crash before exiting this function.
2812 llvm::CrashRecoveryContextCleanupRegistrar<
2813 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2814
Alp Toker9d85b182014-07-07 01:23:14 +00002815 for (auto &UF : PTUI->unsaved_files) {
2816 llvm::MemoryBuffer *MB =
2817 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2818 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002819 }
2820
Ahmed Charlesb8984322014-03-07 20:03:18 +00002821 std::unique_ptr<std::vector<const char *>> Args(
2822 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002823
2824 // Recover resources if we crash before exiting this method.
2825 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2826 ArgsCleanup(Args.get());
2827
2828 // Since the Clang C library is primarily used by batch tools dealing with
2829 // (often very broken) source code, where spell-checking can have a
2830 // significant negative impact on performance (particularly when
2831 // precompiled headers are involved), we disable it by default.
2832 // Only do this if we haven't found a spell-checking-related argument.
2833 bool FoundSpellCheckingArgument = false;
2834 for (int I = 0; I != num_command_line_args; ++I) {
2835 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2836 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2837 FoundSpellCheckingArgument = true;
2838 break;
2839 }
2840 }
2841 if (!FoundSpellCheckingArgument)
2842 Args->push_back("-fno-spell-checking");
2843
2844 Args->insert(Args->end(), command_line_args,
2845 command_line_args + num_command_line_args);
2846
2847 // The 'source_filename' argument is optional. If the caller does not
2848 // specify it then it is assumed that the source file is specified
2849 // in the actual argument list.
2850 // Put the source file after command_line_args otherwise if '-x' flag is
2851 // present it will be unused.
2852 if (source_filename)
2853 Args->push_back(source_filename);
2854
2855 // Do we need the detailed preprocessing record?
2856 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2857 Args->push_back("-Xclang");
2858 Args->push_back("-detailed-preprocessing-record");
2859 }
2860
2861 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002862 std::unique_ptr<ASTUnit> ErrUnit;
2863 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002864 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002865 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2866 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2867 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2868 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2869 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2870 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002871
2872 if (NumErrors != Diags->getClient()->getNumErrors()) {
2873 // Make sure to check that 'Unit' is non-NULL.
2874 if (CXXIdx->getDisplayDiagnostics())
2875 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2876 }
2877
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2879 PTUI->result = CXError_ASTReadError;
2880 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002881 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002882 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2883 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002884}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002885
2886CXTranslationUnit
2887clang_parseTranslationUnit(CXIndex CIdx,
2888 const char *source_filename,
2889 const char *const *command_line_args,
2890 int num_command_line_args,
2891 struct CXUnsavedFile *unsaved_files,
2892 unsigned num_unsaved_files,
2893 unsigned options) {
2894 CXTranslationUnit TU;
2895 enum CXErrorCode Result = clang_parseTranslationUnit2(
2896 CIdx, source_filename, command_line_args, num_command_line_args,
2897 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002898 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002899 assert((TU && Result == CXError_Success) ||
2900 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002901 return TU;
2902}
2903
2904enum CXErrorCode clang_parseTranslationUnit2(
2905 CXIndex CIdx,
2906 const char *source_filename,
2907 const char *const *command_line_args,
2908 int num_command_line_args,
2909 struct CXUnsavedFile *unsaved_files,
2910 unsigned num_unsaved_files,
2911 unsigned options,
2912 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002913 LOG_FUNC_SECTION {
2914 *Log << source_filename << ": ";
2915 for (int i = 0; i != num_command_line_args; ++i)
2916 *Log << command_line_args[i] << " ";
2917 }
2918
Alp Toker9d85b182014-07-07 01:23:14 +00002919 if (num_unsaved_files && !unsaved_files)
2920 return CXError_InvalidArguments;
2921
Alp Toker5c532982014-07-07 22:42:03 +00002922 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002923 ParseTranslationUnitInfo PTUI = {
2924 CIdx,
2925 source_filename,
2926 command_line_args,
2927 num_command_line_args,
2928 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2929 options,
2930 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002931 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002932 llvm::CrashRecoveryContext CRC;
2933
2934 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2935 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2936 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2937 fprintf(stderr, " 'command_line_args' : [");
2938 for (int i = 0; i != num_command_line_args; ++i) {
2939 if (i)
2940 fprintf(stderr, ", ");
2941 fprintf(stderr, "'%s'", command_line_args[i]);
2942 }
2943 fprintf(stderr, "],\n");
2944 fprintf(stderr, " 'unsaved_files' : [");
2945 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2946 if (i)
2947 fprintf(stderr, ", ");
2948 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2949 unsaved_files[i].Length);
2950 }
2951 fprintf(stderr, "],\n");
2952 fprintf(stderr, " 'options' : %d,\n", options);
2953 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002954
2955 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957 if (CXTranslationUnit *TU = PTUI.out_TU)
2958 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 }
Alp Toker5c532982014-07-07 22:42:03 +00002960
2961 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962}
2963
2964unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2965 return CXSaveTranslationUnit_None;
2966}
2967
2968namespace {
2969
2970struct SaveTranslationUnitInfo {
2971 CXTranslationUnit TU;
2972 const char *FileName;
2973 unsigned options;
2974 CXSaveError result;
2975};
2976
2977}
2978
2979static void clang_saveTranslationUnit_Impl(void *UserData) {
2980 SaveTranslationUnitInfo *STUI =
2981 static_cast<SaveTranslationUnitInfo*>(UserData);
2982
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002983 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002984 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2985 setThreadBackgroundPriority();
2986
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002987 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2989}
2990
2991int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2992 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002993 LOG_FUNC_SECTION {
2994 *Log << TU << ' ' << FileName;
2995 }
2996
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002997 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002998 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002999 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003000 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003001
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003002 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3004 if (!CXXUnit->hasSema())
3005 return CXSaveError_InvalidTU;
3006
3007 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3008
3009 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3010 getenv("LIBCLANG_NOTHREADS")) {
3011 clang_saveTranslationUnit_Impl(&STUI);
3012
3013 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3014 PrintLibclangResourceUsage(TU);
3015
3016 return STUI.result;
3017 }
3018
3019 // We have an AST that has invalid nodes due to compiler errors.
3020 // Use a crash recovery thread for protection.
3021
3022 llvm::CrashRecoveryContext CRC;
3023
3024 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3025 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3026 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3027 fprintf(stderr, " 'options' : %d,\n", options);
3028 fprintf(stderr, "}\n");
3029
3030 return CXSaveError_Unknown;
3031
3032 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3033 PrintLibclangResourceUsage(TU);
3034 }
3035
3036 return STUI.result;
3037}
3038
3039void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3040 if (CTUnit) {
3041 // If the translation unit has been marked as unsafe to free, just discard
3042 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3044 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003045 return;
3046
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003047 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003048 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003049 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3050 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003051 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 delete CTUnit;
3053 }
3054}
3055
3056unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3057 return CXReparse_None;
3058}
3059
3060struct ReparseTranslationUnitInfo {
3061 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003062 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003063 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003064 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003065};
3066
3067static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003068 const ReparseTranslationUnitInfo *RTUI =
3069 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 unsigned options = RTUI->options;
3072 (void) options;
3073
3074 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003075 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003076 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003077 RTUI->result = CXError_InvalidArguments;
3078 return;
3079 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003080
3081 // Reset the associated diagnostics.
3082 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003083 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003084
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003085 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3087 setThreadBackgroundPriority();
3088
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003089 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003091
3092 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3093 new std::vector<ASTUnit::RemappedFile>());
3094
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 // Recover resources if we crash before exiting this function.
3096 llvm::CrashRecoveryContextCleanupRegistrar<
3097 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003098
3099 for (auto &UF : RTUI->unsaved_files) {
3100 llvm::MemoryBuffer *MB =
3101 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3102 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003104
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003105 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003106 RTUI->result = CXError_Success;
3107 else if (isASTReadError(CXXUnit))
3108 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003109}
3110
3111int clang_reparseTranslationUnit(CXTranslationUnit TU,
3112 unsigned num_unsaved_files,
3113 struct CXUnsavedFile *unsaved_files,
3114 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003115 LOG_FUNC_SECTION {
3116 *Log << TU;
3117 }
3118
Alp Toker9d85b182014-07-07 01:23:14 +00003119 if (num_unsaved_files && !unsaved_files)
3120 return CXError_InvalidArguments;
3121
Alp Toker5c532982014-07-07 22:42:03 +00003122 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003123 ReparseTranslationUnitInfo RTUI = {
3124 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003125 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003126
3127 if (getenv("LIBCLANG_NOTHREADS")) {
3128 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003129 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 }
3131
3132 llvm::CrashRecoveryContext CRC;
3133
3134 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3135 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003136 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003137 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3139 PrintLibclangResourceUsage(TU);
3140
Alp Toker5c532982014-07-07 22:42:03 +00003141 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003142}
3143
3144
3145CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003146 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003147 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003148 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003149 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003150
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003151 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003152 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003153}
3154
3155CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003156 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003157 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003158 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003159 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003160
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003161 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3163}
3164
3165} // end: extern "C"
3166
3167//===----------------------------------------------------------------------===//
3168// CXFile Operations.
3169//===----------------------------------------------------------------------===//
3170
3171extern "C" {
3172CXString clang_getFileName(CXFile SFile) {
3173 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003174 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003175
3176 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003177 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003178}
3179
3180time_t clang_getFileTime(CXFile SFile) {
3181 if (!SFile)
3182 return 0;
3183
3184 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3185 return FEnt->getModificationTime();
3186}
3187
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003188CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003189 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003190 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003191 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003192 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003193
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003194 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003195
3196 FileManager &FMgr = CXXUnit->getFileManager();
3197 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3198}
3199
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003200unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3201 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003202 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003203 LOG_BAD_TU(TU);
3204 return 0;
3205 }
3206
3207 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return 0;
3209
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003210 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 FileEntry *FEnt = static_cast<FileEntry *>(file);
3212 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3213 .isFileMultipleIncludeGuarded(FEnt);
3214}
3215
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003216int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3217 if (!file || !outID)
3218 return 1;
3219
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003220 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003221 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3222 outID->data[0] = ID.getDevice();
3223 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003224 outID->data[2] = FEnt->getModificationTime();
3225 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003226}
3227
Guy Benyei11169dd2012-12-18 14:30:41 +00003228} // end: extern "C"
3229
3230//===----------------------------------------------------------------------===//
3231// CXCursor Operations.
3232//===----------------------------------------------------------------------===//
3233
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003234static const Decl *getDeclFromExpr(const Stmt *E) {
3235 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 return getDeclFromExpr(CE->getSubExpr());
3237
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003238 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003240 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003242 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003244 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 if (PRE->isExplicitProperty())
3246 return PRE->getExplicitProperty();
3247 // It could be messaging both getter and setter as in:
3248 // ++myobj.myprop;
3249 // in which case prefer to associate the setter since it is less obvious
3250 // from inspecting the source that the setter is going to get called.
3251 if (PRE->isMessagingSetter())
3252 return PRE->getImplicitPropertySetter();
3253 return PRE->getImplicitPropertyGetter();
3254 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003255 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003257 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 if (Expr *Src = OVE->getSourceExpr())
3259 return getDeclFromExpr(Src);
3260
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003261 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003263 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 if (!CE->isElidable())
3265 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003266 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 return OME->getMethodDecl();
3268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003269 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003271 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3273 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003274 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3276 isa<ParmVarDecl>(SizeOfPack->getPack()))
3277 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003278
3279 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003280}
3281
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003282static SourceLocation getLocationFromExpr(const Expr *E) {
3283 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 return getLocationFromExpr(CE->getSubExpr());
3285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003286 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003288 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003290 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003292 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003294 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003296 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 return PropRef->getLocation();
3298
3299 return E->getLocStart();
3300}
3301
3302extern "C" {
3303
3304unsigned clang_visitChildren(CXCursor parent,
3305 CXCursorVisitor visitor,
3306 CXClientData client_data) {
3307 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3308 /*VisitPreprocessorLast=*/false);
3309 return CursorVis.VisitChildren(parent);
3310}
3311
3312#ifndef __has_feature
3313#define __has_feature(x) 0
3314#endif
3315#if __has_feature(blocks)
3316typedef enum CXChildVisitResult
3317 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3318
3319static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3320 CXClientData client_data) {
3321 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3322 return block(cursor, parent);
3323}
3324#else
3325// If we are compiled with a compiler that doesn't have native blocks support,
3326// define and call the block manually, so the
3327typedef struct _CXChildVisitResult
3328{
3329 void *isa;
3330 int flags;
3331 int reserved;
3332 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3333 CXCursor);
3334} *CXCursorVisitorBlock;
3335
3336static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3337 CXClientData client_data) {
3338 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3339 return block->invoke(block, cursor, parent);
3340}
3341#endif
3342
3343
3344unsigned clang_visitChildrenWithBlock(CXCursor parent,
3345 CXCursorVisitorBlock block) {
3346 return clang_visitChildren(parent, visitWithBlock, block);
3347}
3348
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003351 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003352
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003353 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003355 if (const ObjCPropertyImplDecl *PropImpl =
3356 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003358 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003359
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003360 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003362 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003364 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 }
3366
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003370 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3372 // and returns different names. NamedDecl returns the class name and
3373 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003374 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375
3376 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003377 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003378
3379 SmallString<1024> S;
3380 llvm::raw_svector_ostream os(S);
3381 ND->printName(os);
3382
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003383 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003384}
3385
3386CXString clang_getCursorSpelling(CXCursor C) {
3387 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003388 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003389
3390 if (clang_isReference(C.kind)) {
3391 switch (C.kind) {
3392 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003393 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003394 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 }
3396 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003397 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003398 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003401 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003403 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 }
3405 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003406 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003407 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003410 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 assert(Type && "Missing type decl");
3412
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003413 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 getAsString());
3415 }
3416 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003417 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 assert(Template && "Missing template decl");
3419
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003420 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003424 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 assert(NS && "Missing namespace decl");
3426
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003427 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 }
3429
3430 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003431 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 assert(Field && "Missing member decl");
3433
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003434 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 }
3436
3437 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003438 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 assert(Label && "Missing label");
3440
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003441 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 }
3443
3444 case CXCursor_OverloadedDeclRef: {
3445 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003446 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3447 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003448 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003449 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003452 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 OverloadedTemplateStorage *Ovl
3454 = Storage.get<OverloadedTemplateStorage*>();
3455 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003456 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003457 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 }
3459
3460 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003461 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 assert(Var && "Missing variable decl");
3463
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003464 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 }
3466
3467 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003468 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 }
3470 }
3471
3472 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003473 const Expr *E = getCursorExpr(C);
3474
3475 if (C.kind == CXCursor_ObjCStringLiteral ||
3476 C.kind == CXCursor_StringLiteral) {
3477 const StringLiteral *SLit;
3478 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3479 SLit = OSL->getString();
3480 } else {
3481 SLit = cast<StringLiteral>(E);
3482 }
3483 SmallString<256> Buf;
3484 llvm::raw_svector_ostream OS(Buf);
3485 SLit->outputString(OS);
3486 return cxstring::createDup(OS.str());
3487 }
3488
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 if (D)
3491 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003492 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 }
3494
3495 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003496 const Stmt *S = getCursorStmt(C);
3497 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003498 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003499
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003500 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 }
3502
3503 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003504 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 ->getNameStart());
3506
3507 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003508 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 ->getNameStart());
3510
3511 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003512 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513
3514 if (clang_isDeclaration(C.kind))
3515 return getDeclSpelling(getCursorDecl(C));
3516
3517 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003518 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003519 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 }
3521
3522 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003523 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003524 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 }
3526
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003527 if (C.kind == CXCursor_PackedAttr) {
3528 return cxstring::createRef("packed");
3529 }
3530
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003531 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003532}
3533
3534CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3535 unsigned pieceIndex,
3536 unsigned options) {
3537 if (clang_Cursor_isNull(C))
3538 return clang_getNullRange();
3539
3540 ASTContext &Ctx = getCursorContext(C);
3541
3542 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003543 const Stmt *S = getCursorStmt(C);
3544 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 if (pieceIndex > 0)
3546 return clang_getNullRange();
3547 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3548 }
3549
3550 return clang_getNullRange();
3551 }
3552
3553 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003554 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3556 if (pieceIndex >= ME->getNumSelectorLocs())
3557 return clang_getNullRange();
3558 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3559 }
3560 }
3561
3562 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3563 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003564 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3566 if (pieceIndex >= MD->getNumSelectorLocs())
3567 return clang_getNullRange();
3568 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3569 }
3570 }
3571
3572 if (C.kind == CXCursor_ObjCCategoryDecl ||
3573 C.kind == CXCursor_ObjCCategoryImplDecl) {
3574 if (pieceIndex > 0)
3575 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003576 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3578 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003579 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3581 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3582 }
3583
3584 if (C.kind == CXCursor_ModuleImportDecl) {
3585 if (pieceIndex > 0)
3586 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const ImportDecl *ImportD =
3588 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3590 if (!Locs.empty())
3591 return cxloc::translateSourceRange(Ctx,
3592 SourceRange(Locs.front(), Locs.back()));
3593 }
3594 return clang_getNullRange();
3595 }
3596
3597 // FIXME: A CXCursor_InclusionDirective should give the location of the
3598 // filename, but we don't keep track of this.
3599
3600 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3601 // but we don't keep track of this.
3602
3603 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3604 // but we don't keep track of this.
3605
3606 // Default handling, give the location of the cursor.
3607
3608 if (pieceIndex > 0)
3609 return clang_getNullRange();
3610
3611 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3612 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3613 return cxloc::translateSourceRange(Ctx, Loc);
3614}
3615
3616CXString clang_getCursorDisplayName(CXCursor C) {
3617 if (!clang_isDeclaration(C.kind))
3618 return clang_getCursorSpelling(C);
3619
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003620 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003622 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003623
3624 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003625 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 D = FunTmpl->getTemplatedDecl();
3627
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003628 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 SmallString<64> Str;
3630 llvm::raw_svector_ostream OS(Str);
3631 OS << *Function;
3632 if (Function->getPrimaryTemplate())
3633 OS << "<>";
3634 OS << "(";
3635 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3636 if (I)
3637 OS << ", ";
3638 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3639 }
3640
3641 if (Function->isVariadic()) {
3642 if (Function->getNumParams())
3643 OS << ", ";
3644 OS << "...";
3645 }
3646 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003647 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 }
3649
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003650 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 SmallString<64> Str;
3652 llvm::raw_svector_ostream OS(Str);
3653 OS << *ClassTemplate;
3654 OS << "<";
3655 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3656 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3657 if (I)
3658 OS << ", ";
3659
3660 NamedDecl *Param = Params->getParam(I);
3661 if (Param->getIdentifier()) {
3662 OS << Param->getIdentifier()->getName();
3663 continue;
3664 }
3665
3666 // There is no parameter name, which makes this tricky. Try to come up
3667 // with something useful that isn't too long.
3668 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3669 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3670 else if (NonTypeTemplateParmDecl *NTTP
3671 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3672 OS << NTTP->getType().getAsString(Policy);
3673 else
3674 OS << "template<...> class";
3675 }
3676
3677 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003678 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003681 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3683 // If the type was explicitly written, use that.
3684 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003685 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003686
Benjamin Kramer9170e912013-02-22 15:46:01 +00003687 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 llvm::raw_svector_ostream OS(Str);
3689 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003690 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 ClassSpec->getTemplateArgs().data(),
3692 ClassSpec->getTemplateArgs().size(),
3693 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003694 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 }
3696
3697 return clang_getCursorSpelling(C);
3698}
3699
3700CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3701 switch (Kind) {
3702 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003830 case CXCursor_ObjCSelfExpr:
3831 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003920 case CXCursor_SEHLeaveStmt:
3921 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003950 case CXCursor_PackedAttr:
3951 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003952 case CXCursor_PureAttr:
3953 return cxstring::createRef("attribute(pure)");
3954 case CXCursor_ConstAttr:
3955 return cxstring::createRef("attribute(const)");
3956 case CXCursor_NoDuplicateAttr:
3957 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003958 case CXCursor_CUDAConstantAttr:
3959 return cxstring::createRef("attribute(constant)");
3960 case CXCursor_CUDADeviceAttr:
3961 return cxstring::createRef("attribute(device)");
3962 case CXCursor_CUDAGlobalAttr:
3963 return cxstring::createRef("attribute(global)");
3964 case CXCursor_CUDAHostAttr:
3965 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004014 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004015 return cxstring::createRef("OMPParallelDirective");
4016 case CXCursor_OMPSimdDirective:
4017 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004018 case CXCursor_OMPForDirective:
4019 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004020 case CXCursor_OMPSectionsDirective:
4021 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004022 case CXCursor_OMPSectionDirective:
4023 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004024 case CXCursor_OMPSingleDirective:
4025 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004026 case CXCursor_OMPMasterDirective:
4027 return cxstring::createRef("OMPMasterDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004028 case CXCursor_OMPParallelForDirective:
4029 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004030 case CXCursor_OMPParallelSectionsDirective:
4031 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004032 case CXCursor_OMPTaskDirective:
4033 return cxstring::createRef("OMPTaskDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 }
4035
4036 llvm_unreachable("Unhandled CXCursorKind");
4037}
4038
4039struct GetCursorData {
4040 SourceLocation TokenBeginLoc;
4041 bool PointsAtMacroArgExpansion;
4042 bool VisitedObjCPropertyImplDecl;
4043 SourceLocation VisitedDeclaratorDeclStartLoc;
4044 CXCursor &BestCursor;
4045
4046 GetCursorData(SourceManager &SM,
4047 SourceLocation tokenBegin, CXCursor &outputCursor)
4048 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4049 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4050 VisitedObjCPropertyImplDecl = false;
4051 }
4052};
4053
4054static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4055 CXCursor parent,
4056 CXClientData client_data) {
4057 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4058 CXCursor *BestCursor = &Data->BestCursor;
4059
4060 // If we point inside a macro argument we should provide info of what the
4061 // token is so use the actual cursor, don't replace it with a macro expansion
4062 // cursor.
4063 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4064 return CXChildVisit_Recurse;
4065
4066 if (clang_isDeclaration(cursor.kind)) {
4067 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004068 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4070 if (MD->isImplicit())
4071 return CXChildVisit_Break;
4072
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004073 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4075 // Check that when we have multiple @class references in the same line,
4076 // that later ones do not override the previous ones.
4077 // If we have:
4078 // @class Foo, Bar;
4079 // source ranges for both start at '@', so 'Bar' will end up overriding
4080 // 'Foo' even though the cursor location was at 'Foo'.
4081 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4082 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004083 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4085 if (PrevID != ID &&
4086 !PrevID->isThisDeclarationADefinition() &&
4087 !ID->isThisDeclarationADefinition())
4088 return CXChildVisit_Break;
4089 }
4090
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004091 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4093 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4094 // Check that when we have multiple declarators in the same line,
4095 // that later ones do not override the previous ones.
4096 // If we have:
4097 // int Foo, Bar;
4098 // source ranges for both start at 'int', so 'Bar' will end up overriding
4099 // 'Foo' even though the cursor location was at 'Foo'.
4100 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4101 return CXChildVisit_Break;
4102 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4103
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004104 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4106 (void)PropImp;
4107 // Check that when we have multiple @synthesize in the same line,
4108 // that later ones do not override the previous ones.
4109 // If we have:
4110 // @synthesize Foo, Bar;
4111 // source ranges for both start at '@', so 'Bar' will end up overriding
4112 // 'Foo' even though the cursor location was at 'Foo'.
4113 if (Data->VisitedObjCPropertyImplDecl)
4114 return CXChildVisit_Break;
4115 Data->VisitedObjCPropertyImplDecl = true;
4116 }
4117 }
4118
4119 if (clang_isExpression(cursor.kind) &&
4120 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004121 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 // Avoid having the cursor of an expression replace the declaration cursor
4123 // when the expression source range overlaps the declaration range.
4124 // This can happen for C++ constructor expressions whose range generally
4125 // include the variable declaration, e.g.:
4126 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4127 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4128 D->getLocation() == Data->TokenBeginLoc)
4129 return CXChildVisit_Break;
4130 }
4131 }
4132
4133 // If our current best cursor is the construction of a temporary object,
4134 // don't replace that cursor with a type reference, because we want
4135 // clang_getCursor() to point at the constructor.
4136 if (clang_isExpression(BestCursor->kind) &&
4137 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4138 cursor.kind == CXCursor_TypeRef) {
4139 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4140 // as having the actual point on the type reference.
4141 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4142 return CXChildVisit_Recurse;
4143 }
4144
4145 *BestCursor = cursor;
4146 return CXChildVisit_Recurse;
4147}
4148
4149CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004150 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004151 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004153 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004154
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004155 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4157
4158 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4159 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4160
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004161 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 CXFile SearchFile;
4163 unsigned SearchLine, SearchColumn;
4164 CXFile ResultFile;
4165 unsigned ResultLine, ResultColumn;
4166 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4167 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4168 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004169
4170 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4171 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004172 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004173 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 SearchFileName = clang_getFileName(SearchFile);
4175 ResultFileName = clang_getFileName(ResultFile);
4176 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4177 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004178 *Log << llvm::format("(%s:%d:%d) = %s",
4179 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4180 clang_getCString(KindSpelling))
4181 << llvm::format("(%s:%d:%d):%s%s",
4182 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4183 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 clang_disposeString(SearchFileName);
4185 clang_disposeString(ResultFileName);
4186 clang_disposeString(KindSpelling);
4187 clang_disposeString(USR);
4188
4189 CXCursor Definition = clang_getCursorDefinition(Result);
4190 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4191 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4192 CXString DefinitionKindSpelling
4193 = clang_getCursorKindSpelling(Definition.kind);
4194 CXFile DefinitionFile;
4195 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004196 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004197 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004199 *Log << llvm::format(" -> %s(%s:%d:%d)",
4200 clang_getCString(DefinitionKindSpelling),
4201 clang_getCString(DefinitionFileName),
4202 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 clang_disposeString(DefinitionFileName);
4204 clang_disposeString(DefinitionKindSpelling);
4205 }
4206 }
4207
4208 return Result;
4209}
4210
4211CXCursor clang_getNullCursor(void) {
4212 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4213}
4214
4215unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004216 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4217 // can't set consistently. For example, when visiting a DeclStmt we will set
4218 // it but we don't set it on the result of clang_getCursorDefinition for
4219 // a reference of the same declaration.
4220 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4221 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4222 // to provide that kind of info.
4223 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004224 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004225 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004226 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004227
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 return X == Y;
4229}
4230
4231unsigned clang_hashCursor(CXCursor C) {
4232 unsigned Index = 0;
4233 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4234 Index = 1;
4235
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004236 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 std::make_pair(C.kind, C.data[Index]));
4238}
4239
4240unsigned clang_isInvalid(enum CXCursorKind K) {
4241 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4242}
4243
4244unsigned clang_isDeclaration(enum CXCursorKind K) {
4245 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4246 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4247}
4248
4249unsigned clang_isReference(enum CXCursorKind K) {
4250 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4251}
4252
4253unsigned clang_isExpression(enum CXCursorKind K) {
4254 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4255}
4256
4257unsigned clang_isStatement(enum CXCursorKind K) {
4258 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4259}
4260
4261unsigned clang_isAttribute(enum CXCursorKind K) {
4262 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4263}
4264
4265unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4266 return K == CXCursor_TranslationUnit;
4267}
4268
4269unsigned clang_isPreprocessing(enum CXCursorKind K) {
4270 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4271}
4272
4273unsigned clang_isUnexposed(enum CXCursorKind K) {
4274 switch (K) {
4275 case CXCursor_UnexposedDecl:
4276 case CXCursor_UnexposedExpr:
4277 case CXCursor_UnexposedStmt:
4278 case CXCursor_UnexposedAttr:
4279 return true;
4280 default:
4281 return false;
4282 }
4283}
4284
4285CXCursorKind clang_getCursorKind(CXCursor C) {
4286 return C.kind;
4287}
4288
4289CXSourceLocation clang_getCursorLocation(CXCursor C) {
4290 if (clang_isReference(C.kind)) {
4291 switch (C.kind) {
4292 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004293 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 = getCursorObjCSuperClassRef(C);
4295 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4296 }
4297
4298 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004299 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 = getCursorObjCProtocolRef(C);
4301 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4302 }
4303
4304 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004305 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 = getCursorObjCClassRef(C);
4307 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4308 }
4309
4310 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004311 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4313 }
4314
4315 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004316 std::pair<const TemplateDecl *, SourceLocation> P =
4317 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4319 }
4320
4321 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004322 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4324 }
4325
4326 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004327 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4329 }
4330
4331 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004332 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4334 }
4335
4336 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004337 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 if (!BaseSpec)
4339 return clang_getNullLocation();
4340
4341 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4342 return cxloc::translateSourceLocation(getCursorContext(C),
4343 TSInfo->getTypeLoc().getBeginLoc());
4344
4345 return cxloc::translateSourceLocation(getCursorContext(C),
4346 BaseSpec->getLocStart());
4347 }
4348
4349 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004350 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4352 }
4353
4354 case CXCursor_OverloadedDeclRef:
4355 return cxloc::translateSourceLocation(getCursorContext(C),
4356 getCursorOverloadedDeclRef(C).second);
4357
4358 default:
4359 // FIXME: Need a way to enumerate all non-reference cases.
4360 llvm_unreachable("Missed a reference kind");
4361 }
4362 }
4363
4364 if (clang_isExpression(C.kind))
4365 return cxloc::translateSourceLocation(getCursorContext(C),
4366 getLocationFromExpr(getCursorExpr(C)));
4367
4368 if (clang_isStatement(C.kind))
4369 return cxloc::translateSourceLocation(getCursorContext(C),
4370 getCursorStmt(C)->getLocStart());
4371
4372 if (C.kind == CXCursor_PreprocessingDirective) {
4373 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4374 return cxloc::translateSourceLocation(getCursorContext(C), L);
4375 }
4376
4377 if (C.kind == CXCursor_MacroExpansion) {
4378 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004379 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 return cxloc::translateSourceLocation(getCursorContext(C), L);
4381 }
4382
4383 if (C.kind == CXCursor_MacroDefinition) {
4384 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4385 return cxloc::translateSourceLocation(getCursorContext(C), L);
4386 }
4387
4388 if (C.kind == CXCursor_InclusionDirective) {
4389 SourceLocation L
4390 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4391 return cxloc::translateSourceLocation(getCursorContext(C), L);
4392 }
4393
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004394 if (clang_isAttribute(C.kind)) {
4395 SourceLocation L
4396 = cxcursor::getCursorAttr(C)->getLocation();
4397 return cxloc::translateSourceLocation(getCursorContext(C), L);
4398 }
4399
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 if (!clang_isDeclaration(C.kind))
4401 return clang_getNullLocation();
4402
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 if (!D)
4405 return clang_getNullLocation();
4406
4407 SourceLocation Loc = D->getLocation();
4408 // FIXME: Multiple variables declared in a single declaration
4409 // currently lack the information needed to correctly determine their
4410 // ranges when accounting for the type-specifier. We use context
4411 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4412 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004413 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 if (!cxcursor::isFirstInDeclGroup(C))
4415 Loc = VD->getLocation();
4416 }
4417
4418 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004419 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 Loc = MD->getSelectorStartLoc();
4421
4422 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4423}
4424
4425} // end extern "C"
4426
4427CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4428 assert(TU);
4429
4430 // Guard against an invalid SourceLocation, or we may assert in one
4431 // of the following calls.
4432 if (SLoc.isInvalid())
4433 return clang_getNullCursor();
4434
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004435 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004436
4437 // Translate the given source location to make it point at the beginning of
4438 // the token under the cursor.
4439 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4440 CXXUnit->getASTContext().getLangOpts());
4441
4442 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4443 if (SLoc.isValid()) {
4444 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4445 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4446 /*VisitPreprocessorLast=*/true,
4447 /*VisitIncludedEntities=*/false,
4448 SourceLocation(SLoc));
4449 CursorVis.visitFileRegion();
4450 }
4451
4452 return Result;
4453}
4454
4455static SourceRange getRawCursorExtent(CXCursor C) {
4456 if (clang_isReference(C.kind)) {
4457 switch (C.kind) {
4458 case CXCursor_ObjCSuperClassRef:
4459 return getCursorObjCSuperClassRef(C).second;
4460
4461 case CXCursor_ObjCProtocolRef:
4462 return getCursorObjCProtocolRef(C).second;
4463
4464 case CXCursor_ObjCClassRef:
4465 return getCursorObjCClassRef(C).second;
4466
4467 case CXCursor_TypeRef:
4468 return getCursorTypeRef(C).second;
4469
4470 case CXCursor_TemplateRef:
4471 return getCursorTemplateRef(C).second;
4472
4473 case CXCursor_NamespaceRef:
4474 return getCursorNamespaceRef(C).second;
4475
4476 case CXCursor_MemberRef:
4477 return getCursorMemberRef(C).second;
4478
4479 case CXCursor_CXXBaseSpecifier:
4480 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4481
4482 case CXCursor_LabelRef:
4483 return getCursorLabelRef(C).second;
4484
4485 case CXCursor_OverloadedDeclRef:
4486 return getCursorOverloadedDeclRef(C).second;
4487
4488 case CXCursor_VariableRef:
4489 return getCursorVariableRef(C).second;
4490
4491 default:
4492 // FIXME: Need a way to enumerate all non-reference cases.
4493 llvm_unreachable("Missed a reference kind");
4494 }
4495 }
4496
4497 if (clang_isExpression(C.kind))
4498 return getCursorExpr(C)->getSourceRange();
4499
4500 if (clang_isStatement(C.kind))
4501 return getCursorStmt(C)->getSourceRange();
4502
4503 if (clang_isAttribute(C.kind))
4504 return getCursorAttr(C)->getRange();
4505
4506 if (C.kind == CXCursor_PreprocessingDirective)
4507 return cxcursor::getCursorPreprocessingDirective(C);
4508
4509 if (C.kind == CXCursor_MacroExpansion) {
4510 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004511 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 return TU->mapRangeFromPreamble(Range);
4513 }
4514
4515 if (C.kind == CXCursor_MacroDefinition) {
4516 ASTUnit *TU = getCursorASTUnit(C);
4517 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4518 return TU->mapRangeFromPreamble(Range);
4519 }
4520
4521 if (C.kind == CXCursor_InclusionDirective) {
4522 ASTUnit *TU = getCursorASTUnit(C);
4523 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4524 return TU->mapRangeFromPreamble(Range);
4525 }
4526
4527 if (C.kind == CXCursor_TranslationUnit) {
4528 ASTUnit *TU = getCursorASTUnit(C);
4529 FileID MainID = TU->getSourceManager().getMainFileID();
4530 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4531 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4532 return SourceRange(Start, End);
4533 }
4534
4535 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004536 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 if (!D)
4538 return SourceRange();
4539
4540 SourceRange R = D->getSourceRange();
4541 // FIXME: Multiple variables declared in a single declaration
4542 // currently lack the information needed to correctly determine their
4543 // ranges when accounting for the type-specifier. We use context
4544 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4545 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 if (!cxcursor::isFirstInDeclGroup(C))
4548 R.setBegin(VD->getLocation());
4549 }
4550 return R;
4551 }
4552 return SourceRange();
4553}
4554
4555/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4556/// the decl-specifier-seq for declarations.
4557static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4558 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004559 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 if (!D)
4561 return SourceRange();
4562
4563 SourceRange R = D->getSourceRange();
4564
4565 // Adjust the start of the location for declarations preceded by
4566 // declaration specifiers.
4567 SourceLocation StartLoc;
4568 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4569 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4570 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004571 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4573 StartLoc = TI->getTypeLoc().getLocStart();
4574 }
4575
4576 if (StartLoc.isValid() && R.getBegin().isValid() &&
4577 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4578 R.setBegin(StartLoc);
4579
4580 // FIXME: Multiple variables declared in a single declaration
4581 // currently lack the information needed to correctly determine their
4582 // ranges when accounting for the type-specifier. We use context
4583 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4584 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004585 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 if (!cxcursor::isFirstInDeclGroup(C))
4587 R.setBegin(VD->getLocation());
4588 }
4589
4590 return R;
4591 }
4592
4593 return getRawCursorExtent(C);
4594}
4595
4596extern "C" {
4597
4598CXSourceRange clang_getCursorExtent(CXCursor C) {
4599 SourceRange R = getRawCursorExtent(C);
4600 if (R.isInvalid())
4601 return clang_getNullRange();
4602
4603 return cxloc::translateSourceRange(getCursorContext(C), R);
4604}
4605
4606CXCursor clang_getCursorReferenced(CXCursor C) {
4607 if (clang_isInvalid(C.kind))
4608 return clang_getNullCursor();
4609
4610 CXTranslationUnit tu = getCursorTU(C);
4611 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004612 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 if (!D)
4614 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004615 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004617 if (const ObjCPropertyImplDecl *PropImpl =
4618 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4620 return MakeCXCursor(Property, tu);
4621
4622 return C;
4623 }
4624
4625 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004626 const Expr *E = getCursorExpr(C);
4627 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 if (D) {
4629 CXCursor declCursor = MakeCXCursor(D, tu);
4630 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4631 declCursor);
4632 return declCursor;
4633 }
4634
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004635 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 return MakeCursorOverloadedDeclRef(Ovl, tu);
4637
4638 return clang_getNullCursor();
4639 }
4640
4641 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004642 const Stmt *S = getCursorStmt(C);
4643 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 if (LabelDecl *label = Goto->getLabel())
4645 if (LabelStmt *labelS = label->getStmt())
4646 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4647
4648 return clang_getNullCursor();
4649 }
4650
4651 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004652 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 return MakeMacroDefinitionCursor(Def, tu);
4654 }
4655
4656 if (!clang_isReference(C.kind))
4657 return clang_getNullCursor();
4658
4659 switch (C.kind) {
4660 case CXCursor_ObjCSuperClassRef:
4661 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4662
4663 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004664 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4665 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 return MakeCXCursor(Def, tu);
4667
4668 return MakeCXCursor(Prot, tu);
4669 }
4670
4671 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004672 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4673 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 return MakeCXCursor(Def, tu);
4675
4676 return MakeCXCursor(Class, tu);
4677 }
4678
4679 case CXCursor_TypeRef:
4680 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4681
4682 case CXCursor_TemplateRef:
4683 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4684
4685 case CXCursor_NamespaceRef:
4686 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4687
4688 case CXCursor_MemberRef:
4689 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4690
4691 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004692 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4694 tu ));
4695 }
4696
4697 case CXCursor_LabelRef:
4698 // FIXME: We end up faking the "parent" declaration here because we
4699 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004700 return MakeCXCursor(getCursorLabelRef(C).first,
4701 cxtu::getASTUnit(tu)->getASTContext()
4702 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 tu);
4704
4705 case CXCursor_OverloadedDeclRef:
4706 return C;
4707
4708 case CXCursor_VariableRef:
4709 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4710
4711 default:
4712 // We would prefer to enumerate all non-reference cursor kinds here.
4713 llvm_unreachable("Unhandled reference cursor kind");
4714 }
4715}
4716
4717CXCursor clang_getCursorDefinition(CXCursor C) {
4718 if (clang_isInvalid(C.kind))
4719 return clang_getNullCursor();
4720
4721 CXTranslationUnit TU = getCursorTU(C);
4722
4723 bool WasReference = false;
4724 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4725 C = clang_getCursorReferenced(C);
4726 WasReference = true;
4727 }
4728
4729 if (C.kind == CXCursor_MacroExpansion)
4730 return clang_getCursorReferenced(C);
4731
4732 if (!clang_isDeclaration(C.kind))
4733 return clang_getNullCursor();
4734
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 if (!D)
4737 return clang_getNullCursor();
4738
4739 switch (D->getKind()) {
4740 // Declaration kinds that don't really separate the notions of
4741 // declaration and definition.
4742 case Decl::Namespace:
4743 case Decl::Typedef:
4744 case Decl::TypeAlias:
4745 case Decl::TypeAliasTemplate:
4746 case Decl::TemplateTypeParm:
4747 case Decl::EnumConstant:
4748 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004749 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 case Decl::IndirectField:
4751 case Decl::ObjCIvar:
4752 case Decl::ObjCAtDefsField:
4753 case Decl::ImplicitParam:
4754 case Decl::ParmVar:
4755 case Decl::NonTypeTemplateParm:
4756 case Decl::TemplateTemplateParm:
4757 case Decl::ObjCCategoryImpl:
4758 case Decl::ObjCImplementation:
4759 case Decl::AccessSpec:
4760 case Decl::LinkageSpec:
4761 case Decl::ObjCPropertyImpl:
4762 case Decl::FileScopeAsm:
4763 case Decl::StaticAssert:
4764 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004765 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 case Decl::Label: // FIXME: Is this right??
4767 case Decl::ClassScopeFunctionSpecialization:
4768 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004769 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 return C;
4771
4772 // Declaration kinds that don't make any sense here, but are
4773 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004774 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case Decl::TranslationUnit:
4776 break;
4777
4778 // Declaration kinds for which the definition is not resolvable.
4779 case Decl::UnresolvedUsingTypename:
4780 case Decl::UnresolvedUsingValue:
4781 break;
4782
4783 case Decl::UsingDirective:
4784 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4785 TU);
4786
4787 case Decl::NamespaceAlias:
4788 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4789
4790 case Decl::Enum:
4791 case Decl::Record:
4792 case Decl::CXXRecord:
4793 case Decl::ClassTemplateSpecialization:
4794 case Decl::ClassTemplatePartialSpecialization:
4795 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4796 return MakeCXCursor(Def, TU);
4797 return clang_getNullCursor();
4798
4799 case Decl::Function:
4800 case Decl::CXXMethod:
4801 case Decl::CXXConstructor:
4802 case Decl::CXXDestructor:
4803 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004804 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004806 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 return clang_getNullCursor();
4808 }
4809
Larisse Voufo39a1e502013-08-06 01:03:05 +00004810 case Decl::Var:
4811 case Decl::VarTemplateSpecialization:
4812 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004814 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 return MakeCXCursor(Def, TU);
4816 return clang_getNullCursor();
4817 }
4818
4819 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004820 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4822 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4823 return clang_getNullCursor();
4824 }
4825
4826 case Decl::ClassTemplate: {
4827 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4828 ->getDefinition())
4829 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4830 TU);
4831 return clang_getNullCursor();
4832 }
4833
Larisse Voufo39a1e502013-08-06 01:03:05 +00004834 case Decl::VarTemplate: {
4835 if (VarDecl *Def =
4836 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4837 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4838 return clang_getNullCursor();
4839 }
4840
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 case Decl::Using:
4842 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4843 D->getLocation(), TU);
4844
4845 case Decl::UsingShadow:
4846 return clang_getCursorDefinition(
4847 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4848 TU));
4849
4850 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 if (Method->isThisDeclarationADefinition())
4853 return C;
4854
4855 // Dig out the method definition in the associated
4856 // @implementation, if we have it.
4857 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4860 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4861 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4862 Method->isInstanceMethod()))
4863 if (Def->isThisDeclarationADefinition())
4864 return MakeCXCursor(Def, TU);
4865
4866 return clang_getNullCursor();
4867 }
4868
4869 case Decl::ObjCCategory:
4870 if (ObjCCategoryImplDecl *Impl
4871 = cast<ObjCCategoryDecl>(D)->getImplementation())
4872 return MakeCXCursor(Impl, TU);
4873 return clang_getNullCursor();
4874
4875 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 return MakeCXCursor(Def, TU);
4878 return clang_getNullCursor();
4879
4880 case Decl::ObjCInterface: {
4881 // There are two notions of a "definition" for an Objective-C
4882 // class: the interface and its implementation. When we resolved a
4883 // reference to an Objective-C class, produce the @interface as
4884 // the definition; when we were provided with the interface,
4885 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 return MakeCXCursor(Def, TU);
4890 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4891 return MakeCXCursor(Impl, TU);
4892 return clang_getNullCursor();
4893 }
4894
4895 case Decl::ObjCProperty:
4896 // FIXME: We don't really know where to find the
4897 // ObjCPropertyImplDecls that implement this property.
4898 return clang_getNullCursor();
4899
4900 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004903 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 return MakeCXCursor(Def, TU);
4905
4906 return clang_getNullCursor();
4907
4908 case Decl::Friend:
4909 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4910 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4911 return clang_getNullCursor();
4912
4913 case Decl::FriendTemplate:
4914 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4915 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4916 return clang_getNullCursor();
4917 }
4918
4919 return clang_getNullCursor();
4920}
4921
4922unsigned clang_isCursorDefinition(CXCursor C) {
4923 if (!clang_isDeclaration(C.kind))
4924 return 0;
4925
4926 return clang_getCursorDefinition(C) == C;
4927}
4928
4929CXCursor clang_getCanonicalCursor(CXCursor C) {
4930 if (!clang_isDeclaration(C.kind))
4931 return C;
4932
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004933 if (const Decl *D = getCursorDecl(C)) {
4934 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4936 return MakeCXCursor(CatD, getCursorTU(C));
4937
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004938 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4939 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 return MakeCXCursor(IFD, getCursorTU(C));
4941
4942 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4943 }
4944
4945 return C;
4946}
4947
4948int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4949 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4950}
4951
4952unsigned clang_getNumOverloadedDecls(CXCursor C) {
4953 if (C.kind != CXCursor_OverloadedDeclRef)
4954 return 0;
4955
4956 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004957 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 return E->getNumDecls();
4959
4960 if (OverloadedTemplateStorage *S
4961 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4962 return S->size();
4963
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004964 const Decl *D = Storage.get<const Decl *>();
4965 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 return Using->shadow_size();
4967
4968 return 0;
4969}
4970
4971CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4972 if (cursor.kind != CXCursor_OverloadedDeclRef)
4973 return clang_getNullCursor();
4974
4975 if (index >= clang_getNumOverloadedDecls(cursor))
4976 return clang_getNullCursor();
4977
4978 CXTranslationUnit TU = getCursorTU(cursor);
4979 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004980 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 return MakeCXCursor(E->decls_begin()[index], TU);
4982
4983 if (OverloadedTemplateStorage *S
4984 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4985 return MakeCXCursor(S->begin()[index], TU);
4986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004987 const Decl *D = Storage.get<const Decl *>();
4988 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 // FIXME: This is, unfortunately, linear time.
4990 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4991 std::advance(Pos, index);
4992 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4993 }
4994
4995 return clang_getNullCursor();
4996}
4997
4998void clang_getDefinitionSpellingAndExtent(CXCursor C,
4999 const char **startBuf,
5000 const char **endBuf,
5001 unsigned *startLine,
5002 unsigned *startColumn,
5003 unsigned *endLine,
5004 unsigned *endColumn) {
5005 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5008
5009 SourceManager &SM = FD->getASTContext().getSourceManager();
5010 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5011 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5012 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5013 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5014 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5015 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5016}
5017
5018
5019CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5020 unsigned PieceIndex) {
5021 RefNamePieces Pieces;
5022
5023 switch (C.kind) {
5024 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005025 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5027 E->getQualifierLoc().getSourceRange());
5028 break;
5029
5030 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005031 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5033 E->getQualifierLoc().getSourceRange(),
5034 E->getOptionalExplicitTemplateArgs());
5035 break;
5036
5037 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005038 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005040 const Expr *Callee = OCE->getCallee();
5041 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 Callee = ICE->getSubExpr();
5043
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005044 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5046 DRE->getQualifierLoc().getSourceRange());
5047 }
5048 break;
5049
5050 default:
5051 break;
5052 }
5053
5054 if (Pieces.empty()) {
5055 if (PieceIndex == 0)
5056 return clang_getCursorExtent(C);
5057 } else if (PieceIndex < Pieces.size()) {
5058 SourceRange R = Pieces[PieceIndex];
5059 if (R.isValid())
5060 return cxloc::translateSourceRange(getCursorContext(C), R);
5061 }
5062
5063 return clang_getNullRange();
5064}
5065
5066void clang_enableStackTraces(void) {
5067 llvm::sys::PrintStackTraceOnErrorSignal();
5068}
5069
5070void clang_executeOnThread(void (*fn)(void*), void *user_data,
5071 unsigned stack_size) {
5072 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5073}
5074
5075} // end: extern "C"
5076
5077//===----------------------------------------------------------------------===//
5078// Token-based Operations.
5079//===----------------------------------------------------------------------===//
5080
5081/* CXToken layout:
5082 * int_data[0]: a CXTokenKind
5083 * int_data[1]: starting token location
5084 * int_data[2]: token length
5085 * int_data[3]: reserved
5086 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5087 * otherwise unused.
5088 */
5089extern "C" {
5090
5091CXTokenKind clang_getTokenKind(CXToken CXTok) {
5092 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5093}
5094
5095CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5096 switch (clang_getTokenKind(CXTok)) {
5097 case CXToken_Identifier:
5098 case CXToken_Keyword:
5099 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005100 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 ->getNameStart());
5102
5103 case CXToken_Literal: {
5104 // We have stashed the starting pointer in the ptr_data field. Use it.
5105 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005106 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 }
5108
5109 case CXToken_Punctuation:
5110 case CXToken_Comment:
5111 break;
5112 }
5113
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005114 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005115 LOG_BAD_TU(TU);
5116 return cxstring::createEmpty();
5117 }
5118
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 // We have to find the starting buffer pointer the hard way, by
5120 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005121 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005123 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005124
5125 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5126 std::pair<FileID, unsigned> LocInfo
5127 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5128 bool Invalid = false;
5129 StringRef Buffer
5130 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5131 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005132 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005133
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005134 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005135}
5136
5137CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005138 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005139 LOG_BAD_TU(TU);
5140 return clang_getNullLocation();
5141 }
5142
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005143 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 if (!CXXUnit)
5145 return clang_getNullLocation();
5146
5147 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5148 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5149}
5150
5151CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005152 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005153 LOG_BAD_TU(TU);
5154 return clang_getNullRange();
5155 }
5156
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005157 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 if (!CXXUnit)
5159 return clang_getNullRange();
5160
5161 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5162 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5163}
5164
5165static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5166 SmallVectorImpl<CXToken> &CXTokens) {
5167 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5168 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005169 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005171 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005172
5173 // Cannot tokenize across files.
5174 if (BeginLocInfo.first != EndLocInfo.first)
5175 return;
5176
5177 // Create a lexer
5178 bool Invalid = false;
5179 StringRef Buffer
5180 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5181 if (Invalid)
5182 return;
5183
5184 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5185 CXXUnit->getASTContext().getLangOpts(),
5186 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5187 Lex.SetCommentRetentionState(true);
5188
5189 // Lex tokens until we hit the end of the range.
5190 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5191 Token Tok;
5192 bool previousWasAt = false;
5193 do {
5194 // Lex the next token
5195 Lex.LexFromRawLexer(Tok);
5196 if (Tok.is(tok::eof))
5197 break;
5198
5199 // Initialize the CXToken.
5200 CXToken CXTok;
5201
5202 // - Common fields
5203 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5204 CXTok.int_data[2] = Tok.getLength();
5205 CXTok.int_data[3] = 0;
5206
5207 // - Kind-specific fields
5208 if (Tok.isLiteral()) {
5209 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005210 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 } else if (Tok.is(tok::raw_identifier)) {
5212 // Lookup the identifier to determine whether we have a keyword.
5213 IdentifierInfo *II
5214 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5215
5216 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5217 CXTok.int_data[0] = CXToken_Keyword;
5218 }
5219 else {
5220 CXTok.int_data[0] = Tok.is(tok::identifier)
5221 ? CXToken_Identifier
5222 : CXToken_Keyword;
5223 }
5224 CXTok.ptr_data = II;
5225 } else if (Tok.is(tok::comment)) {
5226 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005227 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 } else {
5229 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005230 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 }
5232 CXTokens.push_back(CXTok);
5233 previousWasAt = Tok.is(tok::at);
5234 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5235}
5236
5237void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5238 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005239 LOG_FUNC_SECTION {
5240 *Log << TU << ' ' << Range;
5241 }
5242
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005244 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 if (NumTokens)
5246 *NumTokens = 0;
5247
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005248 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005249 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005250 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005251 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005253 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 if (!CXXUnit || !Tokens || !NumTokens)
5255 return;
5256
5257 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5258
5259 SourceRange R = cxloc::translateCXSourceRange(Range);
5260 if (R.isInvalid())
5261 return;
5262
5263 SmallVector<CXToken, 32> CXTokens;
5264 getTokens(CXXUnit, R, CXTokens);
5265
5266 if (CXTokens.empty())
5267 return;
5268
5269 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5270 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5271 *NumTokens = CXTokens.size();
5272}
5273
5274void clang_disposeTokens(CXTranslationUnit TU,
5275 CXToken *Tokens, unsigned NumTokens) {
5276 free(Tokens);
5277}
5278
5279} // end: extern "C"
5280
5281//===----------------------------------------------------------------------===//
5282// Token annotation APIs.
5283//===----------------------------------------------------------------------===//
5284
Guy Benyei11169dd2012-12-18 14:30:41 +00005285static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5286 CXCursor parent,
5287 CXClientData client_data);
5288static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5289 CXClientData client_data);
5290
5291namespace {
5292class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 CXToken *Tokens;
5294 CXCursor *Cursors;
5295 unsigned NumTokens;
5296 unsigned TokIdx;
5297 unsigned PreprocessingTokIdx;
5298 CursorVisitor AnnotateVis;
5299 SourceManager &SrcMgr;
5300 bool HasContextSensitiveKeywords;
5301
5302 struct PostChildrenInfo {
5303 CXCursor Cursor;
5304 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005305 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 unsigned BeforeChildrenTokenIdx;
5307 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005308 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005309
5310 CXToken &getTok(unsigned Idx) {
5311 assert(Idx < NumTokens);
5312 return Tokens[Idx];
5313 }
5314 const CXToken &getTok(unsigned Idx) const {
5315 assert(Idx < NumTokens);
5316 return Tokens[Idx];
5317 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 bool MoreTokens() const { return TokIdx < NumTokens; }
5319 unsigned NextToken() const { return TokIdx; }
5320 void AdvanceToken() { ++TokIdx; }
5321 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005322 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 }
5324 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005325 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 }
5327 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005328 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 }
5330
5331 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005332 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 SourceRange);
5334
5335public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005336 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005337 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005338 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005340 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 AnnotateTokensVisitor, this,
5342 /*VisitPreprocessorLast=*/true,
5343 /*VisitIncludedEntities=*/false,
5344 RegionOfInterest,
5345 /*VisitDeclsOnly=*/false,
5346 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005347 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 HasContextSensitiveKeywords(false) { }
5349
5350 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5351 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5352 bool postVisitChildren(CXCursor cursor);
5353 void AnnotateTokens();
5354
5355 /// \brief Determine whether the annotator saw any cursors that have
5356 /// context-sensitive keywords.
5357 bool hasContextSensitiveKeywords() const {
5358 return HasContextSensitiveKeywords;
5359 }
5360
5361 ~AnnotateTokensWorker() {
5362 assert(PostChildrenInfos.empty());
5363 }
5364};
5365}
5366
5367void AnnotateTokensWorker::AnnotateTokens() {
5368 // Walk the AST within the region of interest, annotating tokens
5369 // along the way.
5370 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005371}
Guy Benyei11169dd2012-12-18 14:30:41 +00005372
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005373static inline void updateCursorAnnotation(CXCursor &Cursor,
5374 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005375 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005377 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005378}
5379
5380/// \brief It annotates and advances tokens with a cursor until the comparison
5381//// between the cursor location and the source range is the same as
5382/// \arg compResult.
5383///
5384/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5385/// Pass RangeOverlap to annotate tokens inside a range.
5386void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5387 RangeComparisonResult compResult,
5388 SourceRange range) {
5389 while (MoreTokens()) {
5390 const unsigned I = NextToken();
5391 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005392 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5393 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005394
5395 SourceLocation TokLoc = GetTokenLoc(I);
5396 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005397 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 AdvanceToken();
5399 continue;
5400 }
5401 break;
5402 }
5403}
5404
5405/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005406/// \returns true if it advanced beyond all macro tokens, false otherwise.
5407bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 CXCursor updateC,
5409 RangeComparisonResult compResult,
5410 SourceRange range) {
5411 assert(MoreTokens());
5412 assert(isFunctionMacroToken(NextToken()) &&
5413 "Should be called only for macro arg tokens");
5414
5415 // This works differently than annotateAndAdvanceTokens; because expanded
5416 // macro arguments can have arbitrary translation-unit source order, we do not
5417 // advance the token index one by one until a token fails the range test.
5418 // We only advance once past all of the macro arg tokens if all of them
5419 // pass the range test. If one of them fails we keep the token index pointing
5420 // at the start of the macro arg tokens so that the failing token will be
5421 // annotated by a subsequent annotation try.
5422
5423 bool atLeastOneCompFail = false;
5424
5425 unsigned I = NextToken();
5426 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5427 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5428 if (TokLoc.isFileID())
5429 continue; // not macro arg token, it's parens or comma.
5430 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5431 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5432 Cursors[I] = updateC;
5433 } else
5434 atLeastOneCompFail = true;
5435 }
5436
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005437 if (atLeastOneCompFail)
5438 return false;
5439
5440 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5441 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005442}
5443
5444enum CXChildVisitResult
5445AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 SourceRange cursorRange = getRawCursorExtent(cursor);
5447 if (cursorRange.isInvalid())
5448 return CXChildVisit_Recurse;
5449
5450 if (!HasContextSensitiveKeywords) {
5451 // Objective-C properties can have context-sensitive keywords.
5452 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005453 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5455 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5456 }
5457 // Objective-C methods can have context-sensitive keywords.
5458 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5459 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005460 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5462 if (Method->getObjCDeclQualifier())
5463 HasContextSensitiveKeywords = true;
5464 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005465 for (const auto *P : Method->params()) {
5466 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 HasContextSensitiveKeywords = true;
5468 break;
5469 }
5470 }
5471 }
5472 }
5473 }
5474 // C++ methods can have context-sensitive keywords.
5475 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005476 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5478 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5479 HasContextSensitiveKeywords = true;
5480 }
5481 }
5482 // C++ classes can have context-sensitive keywords.
5483 else if (cursor.kind == CXCursor_StructDecl ||
5484 cursor.kind == CXCursor_ClassDecl ||
5485 cursor.kind == CXCursor_ClassTemplate ||
5486 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005487 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 if (D->hasAttr<FinalAttr>())
5489 HasContextSensitiveKeywords = true;
5490 }
5491 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005492
5493 // Don't override a property annotation with its getter/setter method.
5494 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5495 parent.kind == CXCursor_ObjCPropertyDecl)
5496 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005497
5498 if (clang_isPreprocessing(cursor.kind)) {
5499 // Items in the preprocessing record are kept separate from items in
5500 // declarations, so we keep a separate token index.
5501 unsigned SavedTokIdx = TokIdx;
5502 TokIdx = PreprocessingTokIdx;
5503
5504 // Skip tokens up until we catch up to the beginning of the preprocessing
5505 // entry.
5506 while (MoreTokens()) {
5507 const unsigned I = NextToken();
5508 SourceLocation TokLoc = GetTokenLoc(I);
5509 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5510 case RangeBefore:
5511 AdvanceToken();
5512 continue;
5513 case RangeAfter:
5514 case RangeOverlap:
5515 break;
5516 }
5517 break;
5518 }
5519
5520 // Look at all of the tokens within this range.
5521 while (MoreTokens()) {
5522 const unsigned I = NextToken();
5523 SourceLocation TokLoc = GetTokenLoc(I);
5524 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5525 case RangeBefore:
5526 llvm_unreachable("Infeasible");
5527 case RangeAfter:
5528 break;
5529 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005530 // For macro expansions, just note where the beginning of the macro
5531 // expansion occurs.
5532 if (cursor.kind == CXCursor_MacroExpansion) {
5533 if (TokLoc == cursorRange.getBegin())
5534 Cursors[I] = cursor;
5535 AdvanceToken();
5536 break;
5537 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005538 // We may have already annotated macro names inside macro definitions.
5539 if (Cursors[I].kind != CXCursor_MacroExpansion)
5540 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 continue;
5543 }
5544 break;
5545 }
5546
5547 // Save the preprocessing token index; restore the non-preprocessing
5548 // token index.
5549 PreprocessingTokIdx = TokIdx;
5550 TokIdx = SavedTokIdx;
5551 return CXChildVisit_Recurse;
5552 }
5553
5554 if (cursorRange.isInvalid())
5555 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005556
5557 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 const enum CXCursorKind K = clang_getCursorKind(parent);
5560 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005561 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5562 // Attributes are annotated out-of-order, skip tokens until we reach it.
5563 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 ? clang_getNullCursor() : parent;
5565
5566 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5567
5568 // Avoid having the cursor of an expression "overwrite" the annotation of the
5569 // variable declaration that it belongs to.
5570 // This can happen for C++ constructor expressions whose range generally
5571 // include the variable declaration, e.g.:
5572 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005573 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005574 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005575 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005576 const unsigned I = NextToken();
5577 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5578 E->getLocStart() == D->getLocation() &&
5579 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005580 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 AdvanceToken();
5582 }
5583 }
5584 }
5585
5586 // Before recursing into the children keep some state that we are going
5587 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5588 // extra work after the child nodes are visited.
5589 // Note that we don't call VisitChildren here to avoid traversing statements
5590 // code-recursively which can blow the stack.
5591
5592 PostChildrenInfo Info;
5593 Info.Cursor = cursor;
5594 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005595 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 Info.BeforeChildrenTokenIdx = NextToken();
5597 PostChildrenInfos.push_back(Info);
5598
5599 return CXChildVisit_Recurse;
5600}
5601
5602bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5603 if (PostChildrenInfos.empty())
5604 return false;
5605 const PostChildrenInfo &Info = PostChildrenInfos.back();
5606 if (!clang_equalCursors(Info.Cursor, cursor))
5607 return false;
5608
5609 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5610 const unsigned AfterChildren = NextToken();
5611 SourceRange cursorRange = Info.CursorRange;
5612
5613 // Scan the tokens that are at the end of the cursor, but are not captured
5614 // but the child cursors.
5615 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5616
5617 // Scan the tokens that are at the beginning of the cursor, but are not
5618 // capture by the child cursors.
5619 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5620 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5621 break;
5622
5623 Cursors[I] = cursor;
5624 }
5625
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005626 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5627 // encountered the attribute cursor.
5628 if (clang_isAttribute(cursor.kind))
5629 TokIdx = Info.BeforeReachingCursorIdx;
5630
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 PostChildrenInfos.pop_back();
5632 return false;
5633}
5634
5635static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5636 CXCursor parent,
5637 CXClientData client_data) {
5638 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5639}
5640
5641static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5642 CXClientData client_data) {
5643 return static_cast<AnnotateTokensWorker*>(client_data)->
5644 postVisitChildren(cursor);
5645}
5646
5647namespace {
5648
5649/// \brief Uses the macro expansions in the preprocessing record to find
5650/// and mark tokens that are macro arguments. This info is used by the
5651/// AnnotateTokensWorker.
5652class MarkMacroArgTokensVisitor {
5653 SourceManager &SM;
5654 CXToken *Tokens;
5655 unsigned NumTokens;
5656 unsigned CurIdx;
5657
5658public:
5659 MarkMacroArgTokensVisitor(SourceManager &SM,
5660 CXToken *tokens, unsigned numTokens)
5661 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5662
5663 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5664 if (cursor.kind != CXCursor_MacroExpansion)
5665 return CXChildVisit_Continue;
5666
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005667 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 if (macroRange.getBegin() == macroRange.getEnd())
5669 return CXChildVisit_Continue; // it's not a function macro.
5670
5671 for (; CurIdx < NumTokens; ++CurIdx) {
5672 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5673 macroRange.getBegin()))
5674 break;
5675 }
5676
5677 if (CurIdx == NumTokens)
5678 return CXChildVisit_Break;
5679
5680 for (; CurIdx < NumTokens; ++CurIdx) {
5681 SourceLocation tokLoc = getTokenLoc(CurIdx);
5682 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5683 break;
5684
5685 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5686 }
5687
5688 if (CurIdx == NumTokens)
5689 return CXChildVisit_Break;
5690
5691 return CXChildVisit_Continue;
5692 }
5693
5694private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005695 CXToken &getTok(unsigned Idx) {
5696 assert(Idx < NumTokens);
5697 return Tokens[Idx];
5698 }
5699 const CXToken &getTok(unsigned Idx) const {
5700 assert(Idx < NumTokens);
5701 return Tokens[Idx];
5702 }
5703
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005705 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 }
5707
5708 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5709 // The third field is reserved and currently not used. Use it here
5710 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005711 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 }
5713};
5714
5715} // end anonymous namespace
5716
5717static CXChildVisitResult
5718MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5719 CXClientData client_data) {
5720 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5721 parent);
5722}
5723
5724namespace {
5725 struct clang_annotateTokens_Data {
5726 CXTranslationUnit TU;
5727 ASTUnit *CXXUnit;
5728 CXToken *Tokens;
5729 unsigned NumTokens;
5730 CXCursor *Cursors;
5731 };
5732}
5733
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005734/// \brief Used by \c annotatePreprocessorTokens.
5735/// \returns true if lexing was finished, false otherwise.
5736static bool lexNext(Lexer &Lex, Token &Tok,
5737 unsigned &NextIdx, unsigned NumTokens) {
5738 if (NextIdx >= NumTokens)
5739 return true;
5740
5741 ++NextIdx;
5742 Lex.LexFromRawLexer(Tok);
5743 if (Tok.is(tok::eof))
5744 return true;
5745
5746 return false;
5747}
5748
Guy Benyei11169dd2012-12-18 14:30:41 +00005749static void annotatePreprocessorTokens(CXTranslationUnit TU,
5750 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751 CXCursor *Cursors,
5752 CXToken *Tokens,
5753 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005754 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005755
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005756 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5758 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005759 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005761 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005762
5763 if (BeginLocInfo.first != EndLocInfo.first)
5764 return;
5765
5766 StringRef Buffer;
5767 bool Invalid = false;
5768 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5769 if (Buffer.empty() || Invalid)
5770 return;
5771
5772 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5773 CXXUnit->getASTContext().getLangOpts(),
5774 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5775 Buffer.end());
5776 Lex.SetCommentRetentionState(true);
5777
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005778 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 // Lex tokens in raw mode until we hit the end of the range, to avoid
5780 // entering #includes or expanding macros.
5781 while (true) {
5782 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005783 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5784 break;
5785 unsigned TokIdx = NextIdx-1;
5786 assert(Tok.getLocation() ==
5787 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005788
5789 reprocess:
5790 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005791 // We have found a preprocessing directive. Annotate the tokens
5792 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 //
5794 // FIXME: Some simple tests here could identify macro definitions and
5795 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005796
5797 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005798 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5799 break;
5800
Craig Topper69186e72014-06-08 08:38:04 +00005801 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005802 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005803 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5804 break;
5805
5806 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005807 IdentifierInfo &II =
5808 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005809 SourceLocation MappedTokLoc =
5810 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5811 MI = getMacroInfo(II, MappedTokLoc, TU);
5812 }
5813 }
5814
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005815 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005817 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5818 finished = true;
5819 break;
5820 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005821 // If we are in a macro definition, check if the token was ever a
5822 // macro name and annotate it if that's the case.
5823 if (MI) {
5824 SourceLocation SaveLoc = Tok.getLocation();
5825 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5826 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5827 Tok.setLocation(SaveLoc);
5828 if (MacroDef)
5829 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5830 Tok.getLocation(), TU);
5831 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005832 } while (!Tok.isAtStartOfLine());
5833
5834 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5835 assert(TokIdx <= LastIdx);
5836 SourceLocation EndLoc =
5837 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5838 CXCursor Cursor =
5839 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5840
5841 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005842 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005843
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005844 if (finished)
5845 break;
5846 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 }
5849}
5850
5851// This gets run a separate thread to avoid stack blowout.
5852static void clang_annotateTokensImpl(void *UserData) {
5853 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5854 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5855 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5856 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5857 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5858
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005859 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5861 setThreadBackgroundPriority();
5862
5863 // Determine the region of interest, which contains all of the tokens.
5864 SourceRange RegionOfInterest;
5865 RegionOfInterest.setBegin(
5866 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5867 RegionOfInterest.setEnd(
5868 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5869 Tokens[NumTokens-1])));
5870
Guy Benyei11169dd2012-12-18 14:30:41 +00005871 // Relex the tokens within the source range to look for preprocessing
5872 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005873 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005874
5875 // If begin location points inside a macro argument, set it to the expansion
5876 // location so we can have the full context when annotating semantically.
5877 {
5878 SourceManager &SM = CXXUnit->getSourceManager();
5879 SourceLocation Loc =
5880 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5881 if (Loc.isMacroID())
5882 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5883 }
5884
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5886 // Search and mark tokens that are macro argument expansions.
5887 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5888 Tokens, NumTokens);
5889 CursorVisitor MacroArgMarker(TU,
5890 MarkMacroArgTokensVisitorDelegate, &Visitor,
5891 /*VisitPreprocessorLast=*/true,
5892 /*VisitIncludedEntities=*/false,
5893 RegionOfInterest);
5894 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5895 }
5896
5897 // Annotate all of the source locations in the region of interest that map to
5898 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005899 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005900
5901 // FIXME: We use a ridiculous stack size here because the data-recursion
5902 // algorithm uses a large stack frame than the non-data recursive version,
5903 // and AnnotationTokensWorker currently transforms the data-recursion
5904 // algorithm back into a traditional recursion by explicitly calling
5905 // VisitChildren(). We will need to remove this explicit recursive call.
5906 W.AnnotateTokens();
5907
5908 // If we ran into any entities that involve context-sensitive keywords,
5909 // take another pass through the tokens to mark them as such.
5910 if (W.hasContextSensitiveKeywords()) {
5911 for (unsigned I = 0; I != NumTokens; ++I) {
5912 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5913 continue;
5914
5915 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5916 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005917 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5919 if (Property->getPropertyAttributesAsWritten() != 0 &&
5920 llvm::StringSwitch<bool>(II->getName())
5921 .Case("readonly", true)
5922 .Case("assign", true)
5923 .Case("unsafe_unretained", true)
5924 .Case("readwrite", true)
5925 .Case("retain", true)
5926 .Case("copy", true)
5927 .Case("nonatomic", true)
5928 .Case("atomic", true)
5929 .Case("getter", true)
5930 .Case("setter", true)
5931 .Case("strong", true)
5932 .Case("weak", true)
5933 .Default(false))
5934 Tokens[I].int_data[0] = CXToken_Keyword;
5935 }
5936 continue;
5937 }
5938
5939 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5940 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5941 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5942 if (llvm::StringSwitch<bool>(II->getName())
5943 .Case("in", true)
5944 .Case("out", true)
5945 .Case("inout", true)
5946 .Case("oneway", true)
5947 .Case("bycopy", true)
5948 .Case("byref", true)
5949 .Default(false))
5950 Tokens[I].int_data[0] = CXToken_Keyword;
5951 continue;
5952 }
5953
5954 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5955 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5956 Tokens[I].int_data[0] = CXToken_Keyword;
5957 continue;
5958 }
5959 }
5960 }
5961}
5962
5963extern "C" {
5964
5965void clang_annotateTokens(CXTranslationUnit TU,
5966 CXToken *Tokens, unsigned NumTokens,
5967 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005968 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005969 LOG_BAD_TU(TU);
5970 return;
5971 }
5972 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005973 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005975 }
5976
5977 LOG_FUNC_SECTION {
5978 *Log << TU << ' ';
5979 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5980 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5981 *Log << clang_getRange(bloc, eloc);
5982 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005983
5984 // Any token we don't specifically annotate will have a NULL cursor.
5985 CXCursor C = clang_getNullCursor();
5986 for (unsigned I = 0; I != NumTokens; ++I)
5987 Cursors[I] = C;
5988
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005989 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 if (!CXXUnit)
5991 return;
5992
5993 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5994
5995 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5996 llvm::CrashRecoveryContext CRC;
5997 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5998 GetSafetyThreadStackSize() * 2)) {
5999 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6000 }
6001}
6002
6003} // end: extern "C"
6004
6005//===----------------------------------------------------------------------===//
6006// Operations for querying linkage of a cursor.
6007//===----------------------------------------------------------------------===//
6008
6009extern "C" {
6010CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6011 if (!clang_isDeclaration(cursor.kind))
6012 return CXLinkage_Invalid;
6013
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006014 const Decl *D = cxcursor::getCursorDecl(cursor);
6015 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006016 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006017 case NoLinkage:
6018 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 case InternalLinkage: return CXLinkage_Internal;
6020 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6021 case ExternalLinkage: return CXLinkage_External;
6022 };
6023
6024 return CXLinkage_Invalid;
6025}
6026} // end: extern "C"
6027
6028//===----------------------------------------------------------------------===//
6029// Operations for querying language of a cursor.
6030//===----------------------------------------------------------------------===//
6031
6032static CXLanguageKind getDeclLanguage(const Decl *D) {
6033 if (!D)
6034 return CXLanguage_C;
6035
6036 switch (D->getKind()) {
6037 default:
6038 break;
6039 case Decl::ImplicitParam:
6040 case Decl::ObjCAtDefsField:
6041 case Decl::ObjCCategory:
6042 case Decl::ObjCCategoryImpl:
6043 case Decl::ObjCCompatibleAlias:
6044 case Decl::ObjCImplementation:
6045 case Decl::ObjCInterface:
6046 case Decl::ObjCIvar:
6047 case Decl::ObjCMethod:
6048 case Decl::ObjCProperty:
6049 case Decl::ObjCPropertyImpl:
6050 case Decl::ObjCProtocol:
6051 return CXLanguage_ObjC;
6052 case Decl::CXXConstructor:
6053 case Decl::CXXConversion:
6054 case Decl::CXXDestructor:
6055 case Decl::CXXMethod:
6056 case Decl::CXXRecord:
6057 case Decl::ClassTemplate:
6058 case Decl::ClassTemplatePartialSpecialization:
6059 case Decl::ClassTemplateSpecialization:
6060 case Decl::Friend:
6061 case Decl::FriendTemplate:
6062 case Decl::FunctionTemplate:
6063 case Decl::LinkageSpec:
6064 case Decl::Namespace:
6065 case Decl::NamespaceAlias:
6066 case Decl::NonTypeTemplateParm:
6067 case Decl::StaticAssert:
6068 case Decl::TemplateTemplateParm:
6069 case Decl::TemplateTypeParm:
6070 case Decl::UnresolvedUsingTypename:
6071 case Decl::UnresolvedUsingValue:
6072 case Decl::Using:
6073 case Decl::UsingDirective:
6074 case Decl::UsingShadow:
6075 return CXLanguage_CPlusPlus;
6076 }
6077
6078 return CXLanguage_C;
6079}
6080
6081extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006082
6083static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6084 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6085 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006086
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087 switch (D->getAvailability()) {
6088 case AR_Available:
6089 case AR_NotYetIntroduced:
6090 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006091 return getCursorAvailabilityForDecl(
6092 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006093 return CXAvailability_Available;
6094
6095 case AR_Deprecated:
6096 return CXAvailability_Deprecated;
6097
6098 case AR_Unavailable:
6099 return CXAvailability_NotAvailable;
6100 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006101
6102 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006103}
6104
Guy Benyei11169dd2012-12-18 14:30:41 +00006105enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6106 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006107 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6108 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006109
6110 return CXAvailability_Available;
6111}
6112
6113static CXVersion convertVersion(VersionTuple In) {
6114 CXVersion Out = { -1, -1, -1 };
6115 if (In.empty())
6116 return Out;
6117
6118 Out.Major = In.getMajor();
6119
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006120 Optional<unsigned> Minor = In.getMinor();
6121 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 Out.Minor = *Minor;
6123 else
6124 return Out;
6125
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006126 Optional<unsigned> Subminor = In.getSubminor();
6127 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006128 Out.Subminor = *Subminor;
6129
6130 return Out;
6131}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006132
6133static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6134 int *always_deprecated,
6135 CXString *deprecated_message,
6136 int *always_unavailable,
6137 CXString *unavailable_message,
6138 CXPlatformAvailability *availability,
6139 int availability_size) {
6140 bool HadAvailAttr = false;
6141 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006142 for (auto A : D->attrs()) {
6143 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006144 HadAvailAttr = true;
6145 if (always_deprecated)
6146 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006147 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006148 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006149 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006150 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006151 continue;
6152 }
6153
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006154 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006155 HadAvailAttr = true;
6156 if (always_unavailable)
6157 *always_unavailable = 1;
6158 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006159 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006160 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6161 }
6162 continue;
6163 }
6164
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006165 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006166 HadAvailAttr = true;
6167 if (N < availability_size) {
6168 availability[N].Platform
6169 = cxstring::createDup(Avail->getPlatform()->getName());
6170 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6171 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6172 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6173 availability[N].Unavailable = Avail->getUnavailable();
6174 availability[N].Message = cxstring::createDup(Avail->getMessage());
6175 }
6176 ++N;
6177 }
6178 }
6179
6180 if (!HadAvailAttr)
6181 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6182 return getCursorPlatformAvailabilityForDecl(
6183 cast<Decl>(EnumConst->getDeclContext()),
6184 always_deprecated,
6185 deprecated_message,
6186 always_unavailable,
6187 unavailable_message,
6188 availability,
6189 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006190
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006191 return N;
6192}
6193
Guy Benyei11169dd2012-12-18 14:30:41 +00006194int clang_getCursorPlatformAvailability(CXCursor cursor,
6195 int *always_deprecated,
6196 CXString *deprecated_message,
6197 int *always_unavailable,
6198 CXString *unavailable_message,
6199 CXPlatformAvailability *availability,
6200 int availability_size) {
6201 if (always_deprecated)
6202 *always_deprecated = 0;
6203 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006204 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006205 if (always_unavailable)
6206 *always_unavailable = 0;
6207 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006208 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006209
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 if (!clang_isDeclaration(cursor.kind))
6211 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006212
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006213 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 if (!D)
6215 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006216
6217 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6218 deprecated_message,
6219 always_unavailable,
6220 unavailable_message,
6221 availability,
6222 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006223}
6224
6225void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6226 clang_disposeString(availability->Platform);
6227 clang_disposeString(availability->Message);
6228}
6229
6230CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6231 if (clang_isDeclaration(cursor.kind))
6232 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6233
6234 return CXLanguage_Invalid;
6235}
6236
6237 /// \brief If the given cursor is the "templated" declaration
6238 /// descibing a class or function template, return the class or
6239 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006240static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006241 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006242 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006243
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006244 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6246 return FunTmpl;
6247
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006248 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6250 return ClassTmpl;
6251
6252 return D;
6253}
6254
6255CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6256 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006257 if (const Decl *D = getCursorDecl(cursor)) {
6258 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006259 if (!DC)
6260 return clang_getNullCursor();
6261
6262 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6263 getCursorTU(cursor));
6264 }
6265 }
6266
6267 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006268 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006269 return MakeCXCursor(D, getCursorTU(cursor));
6270 }
6271
6272 return clang_getNullCursor();
6273}
6274
6275CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6276 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006277 if (const Decl *D = getCursorDecl(cursor)) {
6278 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006279 if (!DC)
6280 return clang_getNullCursor();
6281
6282 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6283 getCursorTU(cursor));
6284 }
6285 }
6286
6287 // FIXME: Note that we can't easily compute the lexical context of a
6288 // statement or expression, so we return nothing.
6289 return clang_getNullCursor();
6290}
6291
6292CXFile clang_getIncludedFile(CXCursor cursor) {
6293 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006294 return nullptr;
6295
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006296 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006297 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006298}
6299
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006300unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6301 if (C.kind != CXCursor_ObjCPropertyDecl)
6302 return CXObjCPropertyAttr_noattr;
6303
6304 unsigned Result = CXObjCPropertyAttr_noattr;
6305 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6306 ObjCPropertyDecl::PropertyAttributeKind Attr =
6307 PD->getPropertyAttributesAsWritten();
6308
6309#define SET_CXOBJCPROP_ATTR(A) \
6310 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6311 Result |= CXObjCPropertyAttr_##A
6312 SET_CXOBJCPROP_ATTR(readonly);
6313 SET_CXOBJCPROP_ATTR(getter);
6314 SET_CXOBJCPROP_ATTR(assign);
6315 SET_CXOBJCPROP_ATTR(readwrite);
6316 SET_CXOBJCPROP_ATTR(retain);
6317 SET_CXOBJCPROP_ATTR(copy);
6318 SET_CXOBJCPROP_ATTR(nonatomic);
6319 SET_CXOBJCPROP_ATTR(setter);
6320 SET_CXOBJCPROP_ATTR(atomic);
6321 SET_CXOBJCPROP_ATTR(weak);
6322 SET_CXOBJCPROP_ATTR(strong);
6323 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6324#undef SET_CXOBJCPROP_ATTR
6325
6326 return Result;
6327}
6328
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006329unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6330 if (!clang_isDeclaration(C.kind))
6331 return CXObjCDeclQualifier_None;
6332
6333 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6334 const Decl *D = getCursorDecl(C);
6335 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6336 QT = MD->getObjCDeclQualifier();
6337 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6338 QT = PD->getObjCDeclQualifier();
6339 if (QT == Decl::OBJC_TQ_None)
6340 return CXObjCDeclQualifier_None;
6341
6342 unsigned Result = CXObjCDeclQualifier_None;
6343 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6344 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6345 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6346 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6347 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6348 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6349
6350 return Result;
6351}
6352
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006353unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6354 if (!clang_isDeclaration(C.kind))
6355 return 0;
6356
6357 const Decl *D = getCursorDecl(C);
6358 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6359 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6360 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6361 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6362
6363 return 0;
6364}
6365
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006366unsigned clang_Cursor_isVariadic(CXCursor C) {
6367 if (!clang_isDeclaration(C.kind))
6368 return 0;
6369
6370 const Decl *D = getCursorDecl(C);
6371 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6372 return FD->isVariadic();
6373 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6374 return MD->isVariadic();
6375
6376 return 0;
6377}
6378
Guy Benyei11169dd2012-12-18 14:30:41 +00006379CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6380 if (!clang_isDeclaration(C.kind))
6381 return clang_getNullRange();
6382
6383 const Decl *D = getCursorDecl(C);
6384 ASTContext &Context = getCursorContext(C);
6385 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6386 if (!RC)
6387 return clang_getNullRange();
6388
6389 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6390}
6391
6392CXString clang_Cursor_getRawCommentText(CXCursor C) {
6393 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006394 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006395
6396 const Decl *D = getCursorDecl(C);
6397 ASTContext &Context = getCursorContext(C);
6398 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6399 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6400 StringRef();
6401
6402 // Don't duplicate the string because RawText points directly into source
6403 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006404 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006405}
6406
6407CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6408 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006409 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006410
6411 const Decl *D = getCursorDecl(C);
6412 const ASTContext &Context = getCursorContext(C);
6413 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6414
6415 if (RC) {
6416 StringRef BriefText = RC->getBriefText(Context);
6417
6418 // Don't duplicate the string because RawComment ensures that this memory
6419 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006420 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 }
6422
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006423 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006424}
6425
Guy Benyei11169dd2012-12-18 14:30:41 +00006426CXModule clang_Cursor_getModule(CXCursor C) {
6427 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006428 if (const ImportDecl *ImportD =
6429 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 return ImportD->getImportedModule();
6431 }
6432
Craig Topper69186e72014-06-08 08:38:04 +00006433 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006434}
6435
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006436CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6437 if (isNotUsableTU(TU)) {
6438 LOG_BAD_TU(TU);
6439 return nullptr;
6440 }
6441 if (!File)
6442 return nullptr;
6443 FileEntry *FE = static_cast<FileEntry *>(File);
6444
6445 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6446 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6447 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6448
6449 if (Module *Mod = Header.getModule()) {
6450 if (Header.getRole() != ModuleMap::ExcludedHeader)
6451 return Mod;
6452 }
6453 return nullptr;
6454}
6455
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006456CXFile clang_Module_getASTFile(CXModule CXMod) {
6457 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006458 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006459 Module *Mod = static_cast<Module*>(CXMod);
6460 return const_cast<FileEntry *>(Mod->getASTFile());
6461}
6462
Guy Benyei11169dd2012-12-18 14:30:41 +00006463CXModule clang_Module_getParent(CXModule CXMod) {
6464 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006465 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006466 Module *Mod = static_cast<Module*>(CXMod);
6467 return Mod->Parent;
6468}
6469
6470CXString clang_Module_getName(CXModule CXMod) {
6471 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006472 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006474 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006475}
6476
6477CXString clang_Module_getFullName(CXModule CXMod) {
6478 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006479 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006480 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006481 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006482}
6483
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006484int clang_Module_isSystem(CXModule CXMod) {
6485 if (!CXMod)
6486 return 0;
6487 Module *Mod = static_cast<Module*>(CXMod);
6488 return Mod->IsSystem;
6489}
6490
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006491unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6492 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006493 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006494 LOG_BAD_TU(TU);
6495 return 0;
6496 }
6497 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 return 0;
6499 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006500 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6501 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6502 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006503}
6504
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006505CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6506 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006507 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006508 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006509 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006510 }
6511 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006512 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006514 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006515
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006516 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6517 if (Index < TopHeaders.size())
6518 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006519
Craig Topper69186e72014-06-08 08:38:04 +00006520 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006521}
6522
6523} // end: extern "C"
6524
6525//===----------------------------------------------------------------------===//
6526// C++ AST instrospection.
6527//===----------------------------------------------------------------------===//
6528
6529extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006530unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6531 if (!clang_isDeclaration(C.kind))
6532 return 0;
6533
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006534 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006535 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006536 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006537 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6538}
6539
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006540unsigned clang_CXXMethod_isConst(CXCursor C) {
6541 if (!clang_isDeclaration(C.kind))
6542 return 0;
6543
6544 const Decl *D = cxcursor::getCursorDecl(C);
6545 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006546 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006547 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6548}
6549
Guy Benyei11169dd2012-12-18 14:30:41 +00006550unsigned clang_CXXMethod_isStatic(CXCursor C) {
6551 if (!clang_isDeclaration(C.kind))
6552 return 0;
6553
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006554 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006555 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006556 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006557 return (Method && Method->isStatic()) ? 1 : 0;
6558}
6559
6560unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6561 if (!clang_isDeclaration(C.kind))
6562 return 0;
6563
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006564 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006565 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006566 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006567 return (Method && Method->isVirtual()) ? 1 : 0;
6568}
6569} // end: extern "C"
6570
6571//===----------------------------------------------------------------------===//
6572// Attribute introspection.
6573//===----------------------------------------------------------------------===//
6574
6575extern "C" {
6576CXType clang_getIBOutletCollectionType(CXCursor C) {
6577 if (C.kind != CXCursor_IBOutletCollectionAttr)
6578 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6579
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006580 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6582
6583 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6584}
6585} // end: extern "C"
6586
6587//===----------------------------------------------------------------------===//
6588// Inspecting memory usage.
6589//===----------------------------------------------------------------------===//
6590
6591typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6592
6593static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6594 enum CXTUResourceUsageKind k,
6595 unsigned long amount) {
6596 CXTUResourceUsageEntry entry = { k, amount };
6597 entries.push_back(entry);
6598}
6599
6600extern "C" {
6601
6602const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6603 const char *str = "";
6604 switch (kind) {
6605 case CXTUResourceUsage_AST:
6606 str = "ASTContext: expressions, declarations, and types";
6607 break;
6608 case CXTUResourceUsage_Identifiers:
6609 str = "ASTContext: identifiers";
6610 break;
6611 case CXTUResourceUsage_Selectors:
6612 str = "ASTContext: selectors";
6613 break;
6614 case CXTUResourceUsage_GlobalCompletionResults:
6615 str = "Code completion: cached global results";
6616 break;
6617 case CXTUResourceUsage_SourceManagerContentCache:
6618 str = "SourceManager: content cache allocator";
6619 break;
6620 case CXTUResourceUsage_AST_SideTables:
6621 str = "ASTContext: side tables";
6622 break;
6623 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6624 str = "SourceManager: malloc'ed memory buffers";
6625 break;
6626 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6627 str = "SourceManager: mmap'ed memory buffers";
6628 break;
6629 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6630 str = "ExternalASTSource: malloc'ed memory buffers";
6631 break;
6632 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6633 str = "ExternalASTSource: mmap'ed memory buffers";
6634 break;
6635 case CXTUResourceUsage_Preprocessor:
6636 str = "Preprocessor: malloc'ed memory";
6637 break;
6638 case CXTUResourceUsage_PreprocessingRecord:
6639 str = "Preprocessor: PreprocessingRecord";
6640 break;
6641 case CXTUResourceUsage_SourceManager_DataStructures:
6642 str = "SourceManager: data structures and tables";
6643 break;
6644 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6645 str = "Preprocessor: header search tables";
6646 break;
6647 }
6648 return str;
6649}
6650
6651CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006652 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006653 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006654 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 return usage;
6656 }
6657
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006658 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006659 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006660 ASTContext &astContext = astUnit->getASTContext();
6661
6662 // How much memory is used by AST nodes and types?
6663 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6664 (unsigned long) astContext.getASTAllocatedMemory());
6665
6666 // How much memory is used by identifiers?
6667 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6668 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6669
6670 // How much memory is used for selectors?
6671 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6672 (unsigned long) astContext.Selectors.getTotalMemory());
6673
6674 // How much memory is used by ASTContext's side tables?
6675 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6676 (unsigned long) astContext.getSideTableAllocatedMemory());
6677
6678 // How much memory is used for caching global code completion results?
6679 unsigned long completionBytes = 0;
6680 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006681 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006682 completionBytes = completionAllocator->getTotalMemory();
6683 }
6684 createCXTUResourceUsageEntry(*entries,
6685 CXTUResourceUsage_GlobalCompletionResults,
6686 completionBytes);
6687
6688 // How much memory is being used by SourceManager's content cache?
6689 createCXTUResourceUsageEntry(*entries,
6690 CXTUResourceUsage_SourceManagerContentCache,
6691 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6692
6693 // How much memory is being used by the MemoryBuffer's in SourceManager?
6694 const SourceManager::MemoryBufferSizes &srcBufs =
6695 astUnit->getSourceManager().getMemoryBufferSizes();
6696
6697 createCXTUResourceUsageEntry(*entries,
6698 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6699 (unsigned long) srcBufs.malloc_bytes);
6700 createCXTUResourceUsageEntry(*entries,
6701 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6702 (unsigned long) srcBufs.mmap_bytes);
6703 createCXTUResourceUsageEntry(*entries,
6704 CXTUResourceUsage_SourceManager_DataStructures,
6705 (unsigned long) astContext.getSourceManager()
6706 .getDataStructureSizes());
6707
6708 // How much memory is being used by the ExternalASTSource?
6709 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6710 const ExternalASTSource::MemoryBufferSizes &sizes =
6711 esrc->getMemoryBufferSizes();
6712
6713 createCXTUResourceUsageEntry(*entries,
6714 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6715 (unsigned long) sizes.malloc_bytes);
6716 createCXTUResourceUsageEntry(*entries,
6717 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6718 (unsigned long) sizes.mmap_bytes);
6719 }
6720
6721 // How much memory is being used by the Preprocessor?
6722 Preprocessor &pp = astUnit->getPreprocessor();
6723 createCXTUResourceUsageEntry(*entries,
6724 CXTUResourceUsage_Preprocessor,
6725 pp.getTotalMemory());
6726
6727 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6728 createCXTUResourceUsageEntry(*entries,
6729 CXTUResourceUsage_PreprocessingRecord,
6730 pRec->getTotalMemory());
6731 }
6732
6733 createCXTUResourceUsageEntry(*entries,
6734 CXTUResourceUsage_Preprocessor_HeaderSearch,
6735 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006736
Guy Benyei11169dd2012-12-18 14:30:41 +00006737 CXTUResourceUsage usage = { (void*) entries.get(),
6738 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006739 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006740 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006741 return usage;
6742}
6743
6744void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6745 if (usage.data)
6746 delete (MemUsageEntries*) usage.data;
6747}
6748
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006749CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6750 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006751 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006752 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006753
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006754 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006755 LOG_BAD_TU(TU);
6756 return skipped;
6757 }
6758
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006759 if (!file)
6760 return skipped;
6761
6762 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6763 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6764 if (!ppRec)
6765 return skipped;
6766
6767 ASTContext &Ctx = astUnit->getASTContext();
6768 SourceManager &sm = Ctx.getSourceManager();
6769 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6770 FileID wantedFileID = sm.translateFile(fileEntry);
6771
6772 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6773 std::vector<SourceRange> wantedRanges;
6774 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6775 i != ei; ++i) {
6776 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6777 wantedRanges.push_back(*i);
6778 }
6779
6780 skipped->count = wantedRanges.size();
6781 skipped->ranges = new CXSourceRange[skipped->count];
6782 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6783 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6784
6785 return skipped;
6786}
6787
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006788void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6789 if (ranges) {
6790 delete[] ranges->ranges;
6791 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006792 }
6793}
6794
Guy Benyei11169dd2012-12-18 14:30:41 +00006795} // end extern "C"
6796
6797void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6798 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6799 for (unsigned I = 0; I != Usage.numEntries; ++I)
6800 fprintf(stderr, " %s: %lu\n",
6801 clang_getTUResourceUsageName(Usage.entries[I].kind),
6802 Usage.entries[I].amount);
6803
6804 clang_disposeCXTUResourceUsage(Usage);
6805}
6806
6807//===----------------------------------------------------------------------===//
6808// Misc. utility functions.
6809//===----------------------------------------------------------------------===//
6810
6811/// Default to using an 8 MB stack size on "safety" threads.
6812static unsigned SafetyStackThreadSize = 8 << 20;
6813
6814namespace clang {
6815
6816bool RunSafely(llvm::CrashRecoveryContext &CRC,
6817 void (*Fn)(void*), void *UserData,
6818 unsigned Size) {
6819 if (!Size)
6820 Size = GetSafetyThreadStackSize();
6821 if (Size)
6822 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6823 return CRC.RunSafely(Fn, UserData);
6824}
6825
6826unsigned GetSafetyThreadStackSize() {
6827 return SafetyStackThreadSize;
6828}
6829
6830void SetSafetyThreadStackSize(unsigned Value) {
6831 SafetyStackThreadSize = Value;
6832}
6833
6834}
6835
6836void clang::setThreadBackgroundPriority() {
6837 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6838 return;
6839
Alp Toker1a86ad22014-07-06 06:24:00 +00006840#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006841 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6842#endif
6843}
6844
6845void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6846 if (!Unit)
6847 return;
6848
6849 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6850 DEnd = Unit->stored_diag_end();
6851 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006852 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006853 CXString Msg = clang_formatDiagnostic(&Diag,
6854 clang_defaultDiagnosticDisplayOptions());
6855 fprintf(stderr, "%s\n", clang_getCString(Msg));
6856 clang_disposeString(Msg);
6857 }
6858#ifdef LLVM_ON_WIN32
6859 // On Windows, force a flush, since there may be multiple copies of
6860 // stderr and stdout in the file system, all with different buffers
6861 // but writing to the same device.
6862 fflush(stderr);
6863#endif
6864}
6865
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6867 SourceLocation MacroDefLoc,
6868 CXTranslationUnit TU){
6869 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006870 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006871 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006874 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006875 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006876 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006877 if (MD) {
6878 for (MacroDirective::DefInfo
6879 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6880 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6881 return Def.getMacroInfo();
6882 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006883 }
6884
Craig Topper69186e72014-06-08 08:38:04 +00006885 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006886}
6887
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006888const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6889 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006890 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006892 const IdentifierInfo *II = MacroDef->getName();
6893 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006895
6896 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6897}
6898
6899MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6900 const Token &Tok,
6901 CXTranslationUnit TU) {
6902 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006903 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006904 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006905 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006906
6907 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006908 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006909 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6910 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006911 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006912
6913 // Check that the token is inside the definition and not its argument list.
6914 SourceManager &SM = Unit->getSourceManager();
6915 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006916 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006917 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006918 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006919
6920 Preprocessor &PP = Unit->getPreprocessor();
6921 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6922 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006923 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006924
Alp Toker2d57cea2014-05-17 04:53:25 +00006925 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006926 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006927 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006928
6929 // Check that the identifier is not one of the macro arguments.
6930 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006931 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006932
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006933 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6934 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006936
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006937 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006938}
6939
6940MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6941 SourceLocation Loc,
6942 CXTranslationUnit TU) {
6943 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006944 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006945
6946 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006947 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006948 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006949 Preprocessor &PP = Unit->getPreprocessor();
6950 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006951 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006952 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6953 Token Tok;
6954 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006955 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006956
6957 return checkForMacroInMacroDefinition(MI, Tok, TU);
6958}
6959
Guy Benyei11169dd2012-12-18 14:30:41 +00006960extern "C" {
6961
6962CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006963 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006964}
6965
6966} // end: extern "C"
6967
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006968Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6969 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006970 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006971 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006972 if (Unit->isMainFileAST())
6973 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006974 return *this;
6975 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006976 } else {
6977 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006978 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006979 return *this;
6980}
6981
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006982Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6983 *this << FE->getName();
6984 return *this;
6985}
6986
6987Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6988 CXString cursorName = clang_getCursorDisplayName(cursor);
6989 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6990 clang_disposeString(cursorName);
6991 return *this;
6992}
6993
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006994Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6995 CXFile File;
6996 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006997 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006998 CXString FileName = clang_getFileName(File);
6999 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7000 clang_disposeString(FileName);
7001 return *this;
7002}
7003
7004Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7005 CXSourceLocation BLoc = clang_getRangeStart(range);
7006 CXSourceLocation ELoc = clang_getRangeEnd(range);
7007
7008 CXFile BFile;
7009 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007010 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007011
7012 CXFile EFile;
7013 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007014 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007015
7016 CXString BFileName = clang_getFileName(BFile);
7017 if (BFile == EFile) {
7018 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7019 BLine, BColumn, ELine, EColumn);
7020 } else {
7021 CXString EFileName = clang_getFileName(EFile);
7022 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7023 BLine, BColumn)
7024 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7025 ELine, EColumn);
7026 clang_disposeString(EFileName);
7027 }
7028 clang_disposeString(BFileName);
7029 return *this;
7030}
7031
7032Logger &cxindex::Logger::operator<<(CXString Str) {
7033 *this << clang_getCString(Str);
7034 return *this;
7035}
7036
7037Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7038 LogOS << Fmt;
7039 return *this;
7040}
7041
Chandler Carruth37ad2582014-06-27 15:14:39 +00007042static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7043
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007044cxindex::Logger::~Logger() {
7045 LogOS.flush();
7046
Chandler Carruth37ad2582014-06-27 15:14:39 +00007047 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007048
7049 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7050
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007051 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007052 OS << "[libclang:" << Name << ':';
7053
Alp Toker1a86ad22014-07-06 06:24:00 +00007054#ifdef USE_DARWIN_THREADS
7055 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007056 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7057 OS << tid << ':';
7058#endif
7059
7060 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7061 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7062 OS << Msg.str() << '\n';
7063
7064 if (Trace) {
7065 llvm::sys::PrintStackTrace(stderr);
7066 OS << "--------------------------------------------------\n";
7067 }
7068}