blob: 93c36577bdf3db5819488a2741526a47eebe284e [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1848 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1849 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1850 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1851 void VisitVAArgExpr(const VAArgExpr *E);
1852 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1853 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1854 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1855 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001856 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1857 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001858 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001859 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001860 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001861 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001862 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001863 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864
Guy Benyei11169dd2012-12-18 14:30:41 +00001865private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1868 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1870 void AddStmt(const Stmt *S);
1871 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001874 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001875};
1876} // end anonyous namespace
1877
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 // 'S' should always be non-null, since it comes from the
1880 // statement we are visiting.
1881 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1882}
1883
1884void
1885EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1886 if (Qualifier)
1887 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1888}
1889
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 if (S)
1892 WL.push_back(StmtVisit(S, Parent));
1893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(DeclVisit(D, Parent, isFirst));
1897}
1898void EnqueueVisitor::
1899 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1900 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001902}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 if (D)
1905 WL.push_back(MemberRefVisit(D, L, Parent));
1906}
1907void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1908 if (TI)
1909 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1910 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001911void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001912 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 AddStmt(*Child);
1915 }
1916 if (size == WL.size())
1917 return;
1918 // Now reverse the entries we just added. This will match the DFS
1919 // ordering performed by the worklist.
1920 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1921 std::reverse(I, E);
1922}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001923namespace {
1924class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1925 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001926 /// \brief Process clauses with list of variables.
1927 template <typename T>
1928 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929public:
1930 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1931#define OPENMP_CLAUSE(Name, Class) \
1932 void Visit##Class(const Class *C);
1933#include "clang/Basic/OpenMPKinds.def"
1934};
1935
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001936void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1937 Visitor->AddStmt(C->getCondition());
1938}
1939
Alexey Bataev568a8332014-03-06 06:15:19 +00001940void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1941 Visitor->AddStmt(C->getNumThreads());
1942}
1943
Alexey Bataev62c87d22014-03-21 04:51:18 +00001944void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1945 Visitor->AddStmt(C->getSafelen());
1946}
1947
Alexander Musman8bd31e62014-05-27 15:12:19 +00001948void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1949 Visitor->AddStmt(C->getNumForLoops());
1950}
1951
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001953
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001954void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1955
Alexey Bataev56dafe82014-06-20 07:16:17 +00001956void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1957 Visitor->AddStmt(C->getChunkSize());
1958}
1959
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001960void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1961
Alexey Bataev236070f2014-06-20 11:19:47 +00001962void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1963
Alexey Bataev756c1962013-09-24 03:17:45 +00001964template<typename T>
1965void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001966 for (const auto *I : Node->varlists())
1967 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001968}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001969
1970void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001971 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001972}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001973void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1974 const OMPFirstprivateClause *C) {
1975 VisitOMPClauseList(C);
1976}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001977void OMPClauseEnqueue::VisitOMPLastprivateClause(
1978 const OMPLastprivateClause *C) {
1979 VisitOMPClauseList(C);
1980}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001981void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001982 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001983}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001984void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1985 VisitOMPClauseList(C);
1986}
Alexander Musman8dba6642014-04-22 13:09:42 +00001987void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1988 VisitOMPClauseList(C);
1989 Visitor->AddStmt(C->getStep());
1990}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001991void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1992 VisitOMPClauseList(C);
1993 Visitor->AddStmt(C->getAlignment());
1994}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001995void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1996 VisitOMPClauseList(C);
1997}
Alexey Bataevbae9a792014-06-27 10:37:06 +00001998void
1999OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2000 VisitOMPClauseList(C);
2001}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002002}
Alexey Bataev756c1962013-09-24 03:17:45 +00002003
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002004void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2005 unsigned size = WL.size();
2006 OMPClauseEnqueue Visitor(this);
2007 Visitor.Visit(S);
2008 if (size == WL.size())
2009 return;
2010 // Now reverse the entries we just added. This will match the DFS
2011 // ordering performed by the worklist.
2012 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2013 std::reverse(I, E);
2014}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2017}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002018void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002019 AddDecl(B->getBlockDecl());
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002022 EnqueueChildren(E);
2023 AddTypeLoc(E->getTypeSourceInfo());
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2026 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 E = S->body_rend(); I != E; ++I) {
2028 AddStmt(*I);
2029 }
2030}
2031void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002032VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 AddStmt(S->getSubStmt());
2034 AddDeclarationNameInfo(S);
2035 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2036 AddNestedNameSpecifierLoc(QualifierLoc);
2037}
2038
2039void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2042 AddDeclarationNameInfo(E);
2043 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2044 AddNestedNameSpecifierLoc(QualifierLoc);
2045 if (!E->isImplicitAccess())
2046 AddStmt(E->getBase());
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 // Enqueue the initializer , if any.
2050 AddStmt(E->getInitializer());
2051 // Enqueue the array size, if any.
2052 AddStmt(E->getArraySize());
2053 // Enqueue the allocated type.
2054 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2055 // Enqueue the placement arguments.
2056 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2057 AddStmt(E->getPlacementArg(I-1));
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2061 AddStmt(CE->getArg(I-1));
2062 AddStmt(CE->getCallee());
2063 AddStmt(CE->getArg(0));
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2066 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 // Visit the name of the type being destroyed.
2068 AddTypeLoc(E->getDestroyedTypeInfo());
2069 // Visit the scope type that looks disturbingly like the nested-name-specifier
2070 // but isn't.
2071 AddTypeLoc(E->getScopeTypeInfo());
2072 // Visit the nested-name-specifier.
2073 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2074 AddNestedNameSpecifierLoc(QualifierLoc);
2075 // Visit base expression.
2076 AddStmt(E->getBase());
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2079 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddTypeLoc(E->getTypeSourceInfo());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2083 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 EnqueueChildren(E);
2085 AddTypeLoc(E->getTypeSourceInfo());
2086}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 EnqueueChildren(E);
2089 if (E->isTypeOperand())
2090 AddTypeLoc(E->getTypeOperandSourceInfo());
2091}
2092
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2094 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002095 EnqueueChildren(E);
2096 AddTypeLoc(E->getTypeSourceInfo());
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 EnqueueChildren(E);
2100 if (E->isTypeOperand())
2101 AddTypeLoc(E->getTypeOperandSourceInfo());
2102}
2103
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 EnqueueChildren(S);
2106 AddDecl(S->getExceptionDecl());
2107}
2108
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 if (DR->hasExplicitTemplateArgs()) {
2111 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2112 }
2113 WL.push_back(DeclRefExprParts(DR, Parent));
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2116 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2118 AddDeclarationNameInfo(E);
2119 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 unsigned size = WL.size();
2123 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002124 for (const auto *D : S->decls()) {
2125 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 isFirst = false;
2127 }
2128 if (size == WL.size())
2129 return;
2130 // Now reverse the entries we just added. This will match the DFS
2131 // ordering performed by the worklist.
2132 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2133 std::reverse(I, E);
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 D = E->designators_rbegin(), DEnd = E->designators_rend();
2139 D != DEnd; ++D) {
2140 if (D->isFieldDesignator()) {
2141 if (FieldDecl *Field = D->getField())
2142 AddMemberRef(Field, D->getFieldLoc());
2143 continue;
2144 }
2145 if (D->isArrayDesignator()) {
2146 AddStmt(E->getArrayIndex(*D));
2147 continue;
2148 }
2149 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2150 AddStmt(E->getArrayRangeEnd(*D));
2151 AddStmt(E->getArrayRangeStart(*D));
2152 }
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 EnqueueChildren(E);
2156 AddTypeLoc(E->getTypeInfoAsWritten());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 AddStmt(FS->getBody());
2160 AddStmt(FS->getInc());
2161 AddStmt(FS->getCond());
2162 AddDecl(FS->getConditionVariable());
2163 AddStmt(FS->getInit());
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 AddStmt(If->getElse());
2170 AddStmt(If->getThen());
2171 AddStmt(If->getCond());
2172 AddDecl(If->getConditionVariable());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 // We care about the syntactic form of the initializer list, only.
2176 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2177 IE = Syntactic;
2178 EnqueueChildren(IE);
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 WL.push_back(MemberExprParts(M, Parent));
2182
2183 // If the base of the member access expression is an implicit 'this', don't
2184 // visit it.
2185 // FIXME: If we ever want to show these implicit accesses, this will be
2186 // unfortunate. However, clang_getCursor() relies on this behavior.
2187 if (!M->isImplicitAccess())
2188 AddStmt(M->getBase());
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddTypeLoc(E->getEncodedTypeSourceInfo());
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 EnqueueChildren(M);
2195 AddTypeLoc(M->getClassReceiverTypeInfo());
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 // Visit the components of the offsetof expression.
2199 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2200 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2201 const OffsetOfNode &Node = E->getComponent(I-1);
2202 switch (Node.getKind()) {
2203 case OffsetOfNode::Array:
2204 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2205 break;
2206 case OffsetOfNode::Field:
2207 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2208 break;
2209 case OffsetOfNode::Identifier:
2210 case OffsetOfNode::Base:
2211 continue;
2212 }
2213 }
2214 // Visit the type into which we're computing the offset.
2215 AddTypeLoc(E->getTypeSourceInfo());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2219 WL.push_back(OverloadExprParts(E, Parent));
2220}
2221void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 EnqueueChildren(E);
2224 if (E->isArgumentType())
2225 AddTypeLoc(E->getArgumentTypeInfo());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 EnqueueChildren(S);
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddStmt(S->getBody());
2232 AddStmt(S->getCond());
2233 AddDecl(S->getConditionVariable());
2234}
2235
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 AddStmt(W->getBody());
2238 AddStmt(W->getCond());
2239 AddDecl(W->getConditionVariable());
2240}
2241
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 for (unsigned I = E->getNumArgs(); I > 0; --I)
2244 AddTypeLoc(E->getArg(I-1));
2245}
2246
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 AddTypeLoc(E->getQueriedTypeSourceInfo());
2249}
2250
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 EnqueueChildren(E);
2253}
2254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 VisitOverloadExpr(U);
2257 if (!U->isImplicitAccess())
2258 AddStmt(U->getBase());
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 AddStmt(E->getSubExpr());
2262 AddTypeLoc(E->getWrittenTypeInfo());
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 WL.push_back(SizeOfPackExprParts(E, Parent));
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 // If the opaque value has a source expression, just transparently
2269 // visit that. This is useful for (e.g.) pseudo-object expressions.
2270 if (Expr *SourceExpr = E->getSourceExpr())
2271 return Visit(SourceExpr);
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(E->getBody());
2275 WL.push_back(LambdaExprParts(E, Parent));
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 // Treat the expression like its syntactic form.
2279 Visit(E->getSyntacticForm());
2280}
2281
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002282void EnqueueVisitor::VisitOMPExecutableDirective(
2283 const OMPExecutableDirective *D) {
2284 EnqueueChildren(D);
2285 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2286 E = D->clauses().end();
2287 I != E; ++I)
2288 EnqueueChildren(*I);
2289}
2290
2291void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2292 VisitOMPExecutableDirective(D);
2293}
2294
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002295void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2296 VisitOMPExecutableDirective(D);
2297}
2298
Alexey Bataevf29276e2014-06-18 04:14:57 +00002299void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2300 VisitOMPExecutableDirective(D);
2301}
2302
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002303void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2304 VisitOMPExecutableDirective(D);
2305}
2306
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002307void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2308 VisitOMPExecutableDirective(D);
2309}
2310
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002311void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2312 VisitOMPExecutableDirective(D);
2313}
2314
Alexey Bataev4acb8592014-07-07 13:01:15 +00002315void
2316EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2322}
2323
2324bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2325 if (RegionOfInterest.isValid()) {
2326 SourceRange Range = getRawCursorExtent(C);
2327 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2328 return false;
2329 }
2330 return true;
2331}
2332
2333bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2334 while (!WL.empty()) {
2335 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002336 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002337
2338 // Set the Parent field, then back to its old value once we're done.
2339 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2340
2341 switch (LI.getKind()) {
2342 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 if (!D)
2345 continue;
2346
2347 // For now, perform default visitation for Decls.
2348 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2349 cast<DeclVisit>(&LI)->isFirst())))
2350 return true;
2351
2352 continue;
2353 }
2354 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2355 const ASTTemplateArgumentListInfo *ArgList =
2356 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2357 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2358 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2359 Arg != ArgEnd; ++Arg) {
2360 if (VisitTemplateArgumentLoc(*Arg))
2361 return true;
2362 }
2363 continue;
2364 }
2365 case VisitorJob::TypeLocVisitKind: {
2366 // Perform default visitation for TypeLocs.
2367 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2368 return true;
2369 continue;
2370 }
2371 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 if (LabelStmt *stmt = LS->getStmt()) {
2374 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2375 TU))) {
2376 return true;
2377 }
2378 }
2379 continue;
2380 }
2381
2382 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2383 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2384 if (VisitNestedNameSpecifierLoc(V->get()))
2385 return true;
2386 continue;
2387 }
2388
2389 case VisitorJob::DeclarationNameInfoVisitKind: {
2390 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2391 ->get()))
2392 return true;
2393 continue;
2394 }
2395 case VisitorJob::MemberRefVisitKind: {
2396 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2397 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2398 return true;
2399 continue;
2400 }
2401 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002402 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002403 if (!S)
2404 continue;
2405
2406 // Update the current cursor.
2407 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2408 if (!IsInRegionOfInterest(Cursor))
2409 continue;
2410 switch (Visitor(Cursor, Parent, ClientData)) {
2411 case CXChildVisit_Break: return true;
2412 case CXChildVisit_Continue: break;
2413 case CXChildVisit_Recurse:
2414 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002415 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 EnqueueWorkList(WL, S);
2417 break;
2418 }
2419 continue;
2420 }
2421 case VisitorJob::MemberExprPartsKind: {
2422 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002424
2425 // Visit the nested-name-specifier
2426 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2427 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2428 return true;
2429
2430 // Visit the declaration name.
2431 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2432 return true;
2433
2434 // Visit the explicitly-specified template arguments, if any.
2435 if (M->hasExplicitTemplateArgs()) {
2436 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2437 *ArgEnd = Arg + M->getNumTemplateArgs();
2438 Arg != ArgEnd; ++Arg) {
2439 if (VisitTemplateArgumentLoc(*Arg))
2440 return true;
2441 }
2442 }
2443 continue;
2444 }
2445 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 // Visit nested-name-specifier, if present.
2448 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2449 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2450 return true;
2451 // Visit declaration name.
2452 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2453 return true;
2454 continue;
2455 }
2456 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002457 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 // Visit the nested-name-specifier.
2459 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2460 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2461 return true;
2462 // Visit the declaration name.
2463 if (VisitDeclarationNameInfo(O->getNameInfo()))
2464 return true;
2465 // Visit the overloaded declaration reference.
2466 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2467 return true;
2468 continue;
2469 }
2470 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 NamedDecl *Pack = E->getPack();
2473 if (isa<TemplateTypeParmDecl>(Pack)) {
2474 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2475 E->getPackLoc(), TU)))
2476 return true;
2477
2478 continue;
2479 }
2480
2481 if (isa<TemplateTemplateParmDecl>(Pack)) {
2482 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2483 E->getPackLoc(), TU)))
2484 return true;
2485
2486 continue;
2487 }
2488
2489 // Non-type template parameter packs and function parameter packs are
2490 // treated like DeclRefExpr cursors.
2491 continue;
2492 }
2493
2494 case VisitorJob::LambdaExprPartsKind: {
2495 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002496 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2498 CEnd = E->explicit_capture_end();
2499 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002500 // FIXME: Lambda init-captures.
2501 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002503
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2505 C->getLocation(),
2506 TU)))
2507 return true;
2508 }
2509
2510 // Visit parameters and return type, if present.
2511 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2512 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2513 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2514 // Visit the whole type.
2515 if (Visit(TL))
2516 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002517 } else if (FunctionProtoTypeLoc Proto =
2518 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 if (E->hasExplicitParameters()) {
2520 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002521 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2522 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 return true;
2524 } else {
2525 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002526 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002527 return true;
2528 }
2529 }
2530 }
2531 break;
2532 }
2533
2534 case VisitorJob::PostChildrenVisitKind:
2535 if (PostChildrenVisitor(Parent, ClientData))
2536 return true;
2537 break;
2538 }
2539 }
2540 return false;
2541}
2542
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002543bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002544 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 if (!WorkListFreeList.empty()) {
2546 WL = WorkListFreeList.back();
2547 WL->clear();
2548 WorkListFreeList.pop_back();
2549 }
2550 else {
2551 WL = new VisitorWorkList();
2552 WorkListCache.push_back(WL);
2553 }
2554 EnqueueWorkList(*WL, S);
2555 bool result = RunVisitorWorkList(*WL);
2556 WorkListFreeList.push_back(WL);
2557 return result;
2558}
2559
2560namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002561typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002562RefNamePieces
2563buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2564 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2565 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2567 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2568 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2569
2570 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2571
2572 RefNamePieces Pieces;
2573
2574 if (WantQualifier && QLoc.isValid())
2575 Pieces.push_back(QLoc);
2576
2577 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2578 Pieces.push_back(NI.getLoc());
2579
2580 if (WantTemplateArgs && TemplateArgs)
2581 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2582 TemplateArgs->RAngleLoc));
2583
2584 if (Kind == DeclarationName::CXXOperatorName) {
2585 Pieces.push_back(SourceLocation::getFromRawEncoding(
2586 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2587 Pieces.push_back(SourceLocation::getFromRawEncoding(
2588 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2589 }
2590
2591 if (WantSinglePiece) {
2592 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2593 Pieces.clear();
2594 Pieces.push_back(R);
2595 }
2596
2597 return Pieces;
2598}
2599}
2600
2601//===----------------------------------------------------------------------===//
2602// Misc. API hooks.
2603//===----------------------------------------------------------------------===//
2604
Chad Rosier05c71aa2013-03-27 18:28:23 +00002605static void fatal_error_handler(void *user_data, const std::string& reason,
2606 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 // Write the result out to stderr avoiding errs() because raw_ostreams can
2608 // call report_fatal_error.
2609 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2610 ::abort();
2611}
2612
Chandler Carruth66660742014-06-27 16:37:27 +00002613namespace {
2614struct RegisterFatalErrorHandler {
2615 RegisterFatalErrorHandler() {
2616 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2617 }
2618};
2619}
2620
2621static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2622
Guy Benyei11169dd2012-12-18 14:30:41 +00002623extern "C" {
2624CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2625 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002626 // We use crash recovery to make some of our APIs more reliable, implicitly
2627 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002628 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2629 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002630
Chandler Carruth66660742014-06-27 16:37:27 +00002631 // Look through the managed static to trigger construction of the managed
2632 // static which registers our fatal error handler. This ensures it is only
2633 // registered once.
2634 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002635
2636 CIndexer *CIdxr = new CIndexer();
2637 if (excludeDeclarationsFromPCH)
2638 CIdxr->setOnlyLocalDecls();
2639 if (displayDiagnostics)
2640 CIdxr->setDisplayDiagnostics();
2641
2642 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2643 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2644 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2645 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2646 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2647 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2648
2649 return CIdxr;
2650}
2651
2652void clang_disposeIndex(CXIndex CIdx) {
2653 if (CIdx)
2654 delete static_cast<CIndexer *>(CIdx);
2655}
2656
2657void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2658 if (CIdx)
2659 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2660}
2661
2662unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2663 if (CIdx)
2664 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2665 return 0;
2666}
2667
2668void clang_toggleCrashRecovery(unsigned isEnabled) {
2669 if (isEnabled)
2670 llvm::CrashRecoveryContext::Enable();
2671 else
2672 llvm::CrashRecoveryContext::Disable();
2673}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674
Guy Benyei11169dd2012-12-18 14:30:41 +00002675CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2676 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002677 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002678 enum CXErrorCode Result =
2679 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002680 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002681 assert((TU && Result == CXError_Success) ||
2682 (!TU && Result != CXError_Success));
2683 return TU;
2684}
2685
2686enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2687 const char *ast_filename,
2688 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002689 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002690 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002691
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002692 if (!CIdx || !ast_filename || !out_TU)
2693 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002694
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002695 LOG_FUNC_SECTION {
2696 *Log << ast_filename;
2697 }
2698
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2700 FileSystemOptions FileSystemOpts;
2701
2702 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002704 CXXIdx->getOnlyLocalDecls(), None,
2705 /*CaptureDiagnostics=*/true,
2706 /*AllowPCHWithCompilerErrors=*/true,
2707 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002708 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2709 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002710}
2711
2712unsigned clang_defaultEditingTranslationUnitOptions() {
2713 return CXTranslationUnit_PrecompiledPreamble |
2714 CXTranslationUnit_CacheCompletionResults;
2715}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002716
Guy Benyei11169dd2012-12-18 14:30:41 +00002717CXTranslationUnit
2718clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2719 const char *source_filename,
2720 int num_command_line_args,
2721 const char * const *command_line_args,
2722 unsigned num_unsaved_files,
2723 struct CXUnsavedFile *unsaved_files) {
2724 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2725 return clang_parseTranslationUnit(CIdx, source_filename,
2726 command_line_args, num_command_line_args,
2727 unsaved_files, num_unsaved_files,
2728 Options);
2729}
2730
2731struct ParseTranslationUnitInfo {
2732 CXIndex CIdx;
2733 const char *source_filename;
2734 const char *const *command_line_args;
2735 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002736 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002738 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002739 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002740};
2741static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002742 const ParseTranslationUnitInfo *PTUI =
2743 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 CXIndex CIdx = PTUI->CIdx;
2745 const char *source_filename = PTUI->source_filename;
2746 const char * const *command_line_args = PTUI->command_line_args;
2747 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002749 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002750
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002751 // Set up the initial return values.
2752 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002753 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002754
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002755 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002756 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002757 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002759 }
2760
Guy Benyei11169dd2012-12-18 14:30:41 +00002761 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2762
2763 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2764 setThreadBackgroundPriority();
2765
2766 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2767 // FIXME: Add a flag for modules.
2768 TranslationUnitKind TUKind
2769 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002770 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002771 = options & CXTranslationUnit_CacheCompletionResults;
2772 bool IncludeBriefCommentsInCodeCompletion
2773 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2774 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2775 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2776
2777 // Configure the diagnostics.
2778 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002779 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002780
2781 // Recover resources if we crash before exiting this function.
2782 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2783 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002784 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002785
Ahmed Charlesb8984322014-03-07 20:03:18 +00002786 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2787 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002788
2789 // Recover resources if we crash before exiting this function.
2790 llvm::CrashRecoveryContextCleanupRegistrar<
2791 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2792
Alp Toker9d85b182014-07-07 01:23:14 +00002793 for (auto &UF : PTUI->unsaved_files) {
2794 llvm::MemoryBuffer *MB =
2795 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2796 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 }
2798
Ahmed Charlesb8984322014-03-07 20:03:18 +00002799 std::unique_ptr<std::vector<const char *>> Args(
2800 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002801
2802 // Recover resources if we crash before exiting this method.
2803 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2804 ArgsCleanup(Args.get());
2805
2806 // Since the Clang C library is primarily used by batch tools dealing with
2807 // (often very broken) source code, where spell-checking can have a
2808 // significant negative impact on performance (particularly when
2809 // precompiled headers are involved), we disable it by default.
2810 // Only do this if we haven't found a spell-checking-related argument.
2811 bool FoundSpellCheckingArgument = false;
2812 for (int I = 0; I != num_command_line_args; ++I) {
2813 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2814 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2815 FoundSpellCheckingArgument = true;
2816 break;
2817 }
2818 }
2819 if (!FoundSpellCheckingArgument)
2820 Args->push_back("-fno-spell-checking");
2821
2822 Args->insert(Args->end(), command_line_args,
2823 command_line_args + num_command_line_args);
2824
2825 // The 'source_filename' argument is optional. If the caller does not
2826 // specify it then it is assumed that the source file is specified
2827 // in the actual argument list.
2828 // Put the source file after command_line_args otherwise if '-x' flag is
2829 // present it will be unused.
2830 if (source_filename)
2831 Args->push_back(source_filename);
2832
2833 // Do we need the detailed preprocessing record?
2834 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2835 Args->push_back("-Xclang");
2836 Args->push_back("-detailed-preprocessing-record");
2837 }
2838
2839 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002840 std::unique_ptr<ASTUnit> ErrUnit;
2841 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002842 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002843 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2844 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2845 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2846 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2847 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2848 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002849
2850 if (NumErrors != Diags->getClient()->getNumErrors()) {
2851 // Make sure to check that 'Unit' is non-NULL.
2852 if (CXXIdx->getDisplayDiagnostics())
2853 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2854 }
2855
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002856 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2857 PTUI->result = CXError_ASTReadError;
2858 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002859 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002860 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2861 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002862}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002863
2864CXTranslationUnit
2865clang_parseTranslationUnit(CXIndex CIdx,
2866 const char *source_filename,
2867 const char *const *command_line_args,
2868 int num_command_line_args,
2869 struct CXUnsavedFile *unsaved_files,
2870 unsigned num_unsaved_files,
2871 unsigned options) {
2872 CXTranslationUnit TU;
2873 enum CXErrorCode Result = clang_parseTranslationUnit2(
2874 CIdx, source_filename, command_line_args, num_command_line_args,
2875 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002876 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002877 assert((TU && Result == CXError_Success) ||
2878 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879 return TU;
2880}
2881
2882enum CXErrorCode clang_parseTranslationUnit2(
2883 CXIndex CIdx,
2884 const char *source_filename,
2885 const char *const *command_line_args,
2886 int num_command_line_args,
2887 struct CXUnsavedFile *unsaved_files,
2888 unsigned num_unsaved_files,
2889 unsigned options,
2890 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002891 LOG_FUNC_SECTION {
2892 *Log << source_filename << ": ";
2893 for (int i = 0; i != num_command_line_args; ++i)
2894 *Log << command_line_args[i] << " ";
2895 }
2896
Alp Toker9d85b182014-07-07 01:23:14 +00002897 if (num_unsaved_files && !unsaved_files)
2898 return CXError_InvalidArguments;
2899
Alp Toker5c532982014-07-07 22:42:03 +00002900 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002901 ParseTranslationUnitInfo PTUI = {
2902 CIdx,
2903 source_filename,
2904 command_line_args,
2905 num_command_line_args,
2906 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2907 options,
2908 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002909 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 llvm::CrashRecoveryContext CRC;
2911
2912 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2913 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2914 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2915 fprintf(stderr, " 'command_line_args' : [");
2916 for (int i = 0; i != num_command_line_args; ++i) {
2917 if (i)
2918 fprintf(stderr, ", ");
2919 fprintf(stderr, "'%s'", command_line_args[i]);
2920 }
2921 fprintf(stderr, "],\n");
2922 fprintf(stderr, " 'unsaved_files' : [");
2923 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2924 if (i)
2925 fprintf(stderr, ", ");
2926 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2927 unsaved_files[i].Length);
2928 }
2929 fprintf(stderr, "],\n");
2930 fprintf(stderr, " 'options' : %d,\n", options);
2931 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002932
2933 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002934 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002935 if (CXTranslationUnit *TU = PTUI.out_TU)
2936 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 }
Alp Toker5c532982014-07-07 22:42:03 +00002938
2939 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002940}
2941
2942unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2943 return CXSaveTranslationUnit_None;
2944}
2945
2946namespace {
2947
2948struct SaveTranslationUnitInfo {
2949 CXTranslationUnit TU;
2950 const char *FileName;
2951 unsigned options;
2952 CXSaveError result;
2953};
2954
2955}
2956
2957static void clang_saveTranslationUnit_Impl(void *UserData) {
2958 SaveTranslationUnitInfo *STUI =
2959 static_cast<SaveTranslationUnitInfo*>(UserData);
2960
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002961 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2963 setThreadBackgroundPriority();
2964
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002965 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2967}
2968
2969int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2970 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << TU << ' ' << FileName;
2973 }
2974
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002975 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002976 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002978 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002979
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002980 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002981 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2982 if (!CXXUnit->hasSema())
2983 return CXSaveError_InvalidTU;
2984
2985 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2986
2987 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2988 getenv("LIBCLANG_NOTHREADS")) {
2989 clang_saveTranslationUnit_Impl(&STUI);
2990
2991 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2992 PrintLibclangResourceUsage(TU);
2993
2994 return STUI.result;
2995 }
2996
2997 // We have an AST that has invalid nodes due to compiler errors.
2998 // Use a crash recovery thread for protection.
2999
3000 llvm::CrashRecoveryContext CRC;
3001
3002 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3003 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3004 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3005 fprintf(stderr, " 'options' : %d,\n", options);
3006 fprintf(stderr, "}\n");
3007
3008 return CXSaveError_Unknown;
3009
3010 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3011 PrintLibclangResourceUsage(TU);
3012 }
3013
3014 return STUI.result;
3015}
3016
3017void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3018 if (CTUnit) {
3019 // If the translation unit has been marked as unsafe to free, just discard
3020 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003021 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3022 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 return;
3024
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003025 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003026 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3028 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003029 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003030 delete CTUnit;
3031 }
3032}
3033
3034unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3035 return CXReparse_None;
3036}
3037
3038struct ReparseTranslationUnitInfo {
3039 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003040 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003042 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003043};
3044
3045static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003046 const ReparseTranslationUnitInfo *RTUI =
3047 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003048 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003049 unsigned options = RTUI->options;
3050 (void) options;
3051
3052 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003053 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003054 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 RTUI->result = CXError_InvalidArguments;
3056 return;
3057 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003058
3059 // Reset the associated diagnostics.
3060 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003061 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003062
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003063 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003064 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3065 setThreadBackgroundPriority();
3066
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003067 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003068 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003069
3070 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3071 new std::vector<ASTUnit::RemappedFile>());
3072
Guy Benyei11169dd2012-12-18 14:30:41 +00003073 // Recover resources if we crash before exiting this function.
3074 llvm::CrashRecoveryContextCleanupRegistrar<
3075 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003076
3077 for (auto &UF : RTUI->unsaved_files) {
3078 llvm::MemoryBuffer *MB =
3079 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3080 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003082
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003083 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084 RTUI->result = CXError_Success;
3085 else if (isASTReadError(CXXUnit))
3086 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003087}
3088
3089int clang_reparseTranslationUnit(CXTranslationUnit TU,
3090 unsigned num_unsaved_files,
3091 struct CXUnsavedFile *unsaved_files,
3092 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003093 LOG_FUNC_SECTION {
3094 *Log << TU;
3095 }
3096
Alp Toker9d85b182014-07-07 01:23:14 +00003097 if (num_unsaved_files && !unsaved_files)
3098 return CXError_InvalidArguments;
3099
Alp Toker5c532982014-07-07 22:42:03 +00003100 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003101 ReparseTranslationUnitInfo RTUI = {
3102 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003103 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
3105 if (getenv("LIBCLANG_NOTHREADS")) {
3106 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003107 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 }
3109
3110 llvm::CrashRecoveryContext CRC;
3111
3112 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3113 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003114 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003115 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3117 PrintLibclangResourceUsage(TU);
3118
Alp Toker5c532982014-07-07 22:42:03 +00003119 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120}
3121
3122
3123CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003124 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003125 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003126 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003127 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003128
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003129 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003130 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003131}
3132
3133CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003134 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003135 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003136 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003137 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003138
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003139 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3141}
3142
3143} // end: extern "C"
3144
3145//===----------------------------------------------------------------------===//
3146// CXFile Operations.
3147//===----------------------------------------------------------------------===//
3148
3149extern "C" {
3150CXString clang_getFileName(CXFile SFile) {
3151 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003152 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003153
3154 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003155 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003156}
3157
3158time_t clang_getFileTime(CXFile SFile) {
3159 if (!SFile)
3160 return 0;
3161
3162 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3163 return FEnt->getModificationTime();
3164}
3165
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003166CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003167 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003168 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003169 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003170 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003171
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003172 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003173
3174 FileManager &FMgr = CXXUnit->getFileManager();
3175 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3176}
3177
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003178unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3179 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003180 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003181 LOG_BAD_TU(TU);
3182 return 0;
3183 }
3184
3185 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return 0;
3187
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003188 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 FileEntry *FEnt = static_cast<FileEntry *>(file);
3190 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3191 .isFileMultipleIncludeGuarded(FEnt);
3192}
3193
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003194int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3195 if (!file || !outID)
3196 return 1;
3197
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003198 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003199 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3200 outID->data[0] = ID.getDevice();
3201 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003202 outID->data[2] = FEnt->getModificationTime();
3203 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003204}
3205
Guy Benyei11169dd2012-12-18 14:30:41 +00003206} // end: extern "C"
3207
3208//===----------------------------------------------------------------------===//
3209// CXCursor Operations.
3210//===----------------------------------------------------------------------===//
3211
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003212static const Decl *getDeclFromExpr(const Stmt *E) {
3213 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return getDeclFromExpr(CE->getSubExpr());
3215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003218 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003220 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003222 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 if (PRE->isExplicitProperty())
3224 return PRE->getExplicitProperty();
3225 // It could be messaging both getter and setter as in:
3226 // ++myobj.myprop;
3227 // in which case prefer to associate the setter since it is less obvious
3228 // from inspecting the source that the setter is going to get called.
3229 if (PRE->isMessagingSetter())
3230 return PRE->getImplicitPropertySetter();
3231 return PRE->getImplicitPropertyGetter();
3232 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003233 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003235 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 if (Expr *Src = OVE->getSourceExpr())
3237 return getDeclFromExpr(Src);
3238
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003239 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003241 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 if (!CE->isElidable())
3243 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003244 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 return OME->getMethodDecl();
3246
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003247 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003249 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3251 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003252 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3254 isa<ParmVarDecl>(SizeOfPack->getPack()))
3255 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003256
3257 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003258}
3259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003260static SourceLocation getLocationFromExpr(const Expr *E) {
3261 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return getLocationFromExpr(CE->getSubExpr());
3263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003264 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003266 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003268 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003270 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003272 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003274 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 return PropRef->getLocation();
3276
3277 return E->getLocStart();
3278}
3279
3280extern "C" {
3281
3282unsigned clang_visitChildren(CXCursor parent,
3283 CXCursorVisitor visitor,
3284 CXClientData client_data) {
3285 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3286 /*VisitPreprocessorLast=*/false);
3287 return CursorVis.VisitChildren(parent);
3288}
3289
3290#ifndef __has_feature
3291#define __has_feature(x) 0
3292#endif
3293#if __has_feature(blocks)
3294typedef enum CXChildVisitResult
3295 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3296
3297static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3298 CXClientData client_data) {
3299 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3300 return block(cursor, parent);
3301}
3302#else
3303// If we are compiled with a compiler that doesn't have native blocks support,
3304// define and call the block manually, so the
3305typedef struct _CXChildVisitResult
3306{
3307 void *isa;
3308 int flags;
3309 int reserved;
3310 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3311 CXCursor);
3312} *CXCursorVisitorBlock;
3313
3314static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3315 CXClientData client_data) {
3316 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3317 return block->invoke(block, cursor, parent);
3318}
3319#endif
3320
3321
3322unsigned clang_visitChildrenWithBlock(CXCursor parent,
3323 CXCursorVisitorBlock block) {
3324 return clang_visitChildren(parent, visitWithBlock, block);
3325}
3326
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003329 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003330
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003331 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003333 if (const ObjCPropertyImplDecl *PropImpl =
3334 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003336 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003337
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003338 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003341
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003342 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 }
3344
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003345 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003346 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003348 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3350 // and returns different names. NamedDecl returns the class name and
3351 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003352 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353
3354 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003355 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003356
3357 SmallString<1024> S;
3358 llvm::raw_svector_ostream os(S);
3359 ND->printName(os);
3360
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003361 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362}
3363
3364CXString clang_getCursorSpelling(CXCursor C) {
3365 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003366 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003367
3368 if (clang_isReference(C.kind)) {
3369 switch (C.kind) {
3370 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003371 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003372 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
3374 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003375 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003376 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 }
3378 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003379 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003381 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 }
3383 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003384 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003385 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003388 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 assert(Type && "Missing type decl");
3390
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003391 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 getAsString());
3393 }
3394 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003395 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 assert(Template && "Missing template decl");
3397
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003398 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400
3401 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003402 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 assert(NS && "Missing namespace decl");
3404
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003405 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 }
3407
3408 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003409 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 assert(Field && "Missing member decl");
3411
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003412 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414
3415 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003416 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 assert(Label && "Missing label");
3418
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003419 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 }
3421
3422 case CXCursor_OverloadedDeclRef: {
3423 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003424 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3425 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003426 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003427 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003429 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003430 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 OverloadedTemplateStorage *Ovl
3432 = Storage.get<OverloadedTemplateStorage*>();
3433 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003434 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003435 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 }
3437
3438 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003439 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 assert(Var && "Missing variable decl");
3441
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003442 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 }
3444
3445 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003446 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 }
3448 }
3449
3450 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003451 const Expr *E = getCursorExpr(C);
3452
3453 if (C.kind == CXCursor_ObjCStringLiteral ||
3454 C.kind == CXCursor_StringLiteral) {
3455 const StringLiteral *SLit;
3456 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3457 SLit = OSL->getString();
3458 } else {
3459 SLit = cast<StringLiteral>(E);
3460 }
3461 SmallString<256> Buf;
3462 llvm::raw_svector_ostream OS(Buf);
3463 SLit->outputString(OS);
3464 return cxstring::createDup(OS.str());
3465 }
3466
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003467 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 if (D)
3469 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003470 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 }
3472
3473 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 const Stmt *S = getCursorStmt(C);
3475 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003476 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003477
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003478 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 }
3480
3481 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003482 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 ->getNameStart());
3484
3485 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003486 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 ->getNameStart());
3488
3489 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003490 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003491
3492 if (clang_isDeclaration(C.kind))
3493 return getDeclSpelling(getCursorDecl(C));
3494
3495 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003496 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003497 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 }
3499
3500 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003501 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003502 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 }
3504
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003505 if (C.kind == CXCursor_PackedAttr) {
3506 return cxstring::createRef("packed");
3507 }
3508
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003509 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003510}
3511
3512CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3513 unsigned pieceIndex,
3514 unsigned options) {
3515 if (clang_Cursor_isNull(C))
3516 return clang_getNullRange();
3517
3518 ASTContext &Ctx = getCursorContext(C);
3519
3520 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003521 const Stmt *S = getCursorStmt(C);
3522 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 if (pieceIndex > 0)
3524 return clang_getNullRange();
3525 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3526 }
3527
3528 return clang_getNullRange();
3529 }
3530
3531 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003532 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3534 if (pieceIndex >= ME->getNumSelectorLocs())
3535 return clang_getNullRange();
3536 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3537 }
3538 }
3539
3540 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3541 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3544 if (pieceIndex >= MD->getNumSelectorLocs())
3545 return clang_getNullRange();
3546 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3547 }
3548 }
3549
3550 if (C.kind == CXCursor_ObjCCategoryDecl ||
3551 C.kind == CXCursor_ObjCCategoryImplDecl) {
3552 if (pieceIndex > 0)
3553 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3556 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003557 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3559 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3560 }
3561
3562 if (C.kind == CXCursor_ModuleImportDecl) {
3563 if (pieceIndex > 0)
3564 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003565 if (const ImportDecl *ImportD =
3566 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3568 if (!Locs.empty())
3569 return cxloc::translateSourceRange(Ctx,
3570 SourceRange(Locs.front(), Locs.back()));
3571 }
3572 return clang_getNullRange();
3573 }
3574
3575 // FIXME: A CXCursor_InclusionDirective should give the location of the
3576 // filename, but we don't keep track of this.
3577
3578 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3579 // but we don't keep track of this.
3580
3581 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3582 // but we don't keep track of this.
3583
3584 // Default handling, give the location of the cursor.
3585
3586 if (pieceIndex > 0)
3587 return clang_getNullRange();
3588
3589 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3590 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3591 return cxloc::translateSourceRange(Ctx, Loc);
3592}
3593
3594CXString clang_getCursorDisplayName(CXCursor C) {
3595 if (!clang_isDeclaration(C.kind))
3596 return clang_getCursorSpelling(C);
3597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003600 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003601
3602 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003603 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 D = FunTmpl->getTemplatedDecl();
3605
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003606 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 SmallString<64> Str;
3608 llvm::raw_svector_ostream OS(Str);
3609 OS << *Function;
3610 if (Function->getPrimaryTemplate())
3611 OS << "<>";
3612 OS << "(";
3613 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3614 if (I)
3615 OS << ", ";
3616 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3617 }
3618
3619 if (Function->isVariadic()) {
3620 if (Function->getNumParams())
3621 OS << ", ";
3622 OS << "...";
3623 }
3624 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003625 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 }
3627
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003628 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 SmallString<64> Str;
3630 llvm::raw_svector_ostream OS(Str);
3631 OS << *ClassTemplate;
3632 OS << "<";
3633 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3634 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3635 if (I)
3636 OS << ", ";
3637
3638 NamedDecl *Param = Params->getParam(I);
3639 if (Param->getIdentifier()) {
3640 OS << Param->getIdentifier()->getName();
3641 continue;
3642 }
3643
3644 // There is no parameter name, which makes this tricky. Try to come up
3645 // with something useful that isn't too long.
3646 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3647 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3648 else if (NonTypeTemplateParmDecl *NTTP
3649 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3650 OS << NTTP->getType().getAsString(Policy);
3651 else
3652 OS << "template<...> class";
3653 }
3654
3655 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003656 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 }
3658
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003659 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3661 // If the type was explicitly written, use that.
3662 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003663 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003664
Benjamin Kramer9170e912013-02-22 15:46:01 +00003665 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 llvm::raw_svector_ostream OS(Str);
3667 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003668 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 ClassSpec->getTemplateArgs().data(),
3670 ClassSpec->getTemplateArgs().size(),
3671 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003672 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 }
3674
3675 return clang_getCursorSpelling(C);
3676}
3677
3678CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3679 switch (Kind) {
3680 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003808 case CXCursor_ObjCSelfExpr:
3809 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003898 case CXCursor_SEHLeaveStmt:
3899 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003928 case CXCursor_PackedAttr:
3929 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003930 case CXCursor_PureAttr:
3931 return cxstring::createRef("attribute(pure)");
3932 case CXCursor_ConstAttr:
3933 return cxstring::createRef("attribute(const)");
3934 case CXCursor_NoDuplicateAttr:
3935 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003936 case CXCursor_CUDAConstantAttr:
3937 return cxstring::createRef("attribute(constant)");
3938 case CXCursor_CUDADeviceAttr:
3939 return cxstring::createRef("attribute(device)");
3940 case CXCursor_CUDAGlobalAttr:
3941 return cxstring::createRef("attribute(global)");
3942 case CXCursor_CUDAHostAttr:
3943 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003992 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003993 return cxstring::createRef("OMPParallelDirective");
3994 case CXCursor_OMPSimdDirective:
3995 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003996 case CXCursor_OMPForDirective:
3997 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003998 case CXCursor_OMPSectionsDirective:
3999 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004000 case CXCursor_OMPSectionDirective:
4001 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004002 case CXCursor_OMPSingleDirective:
4003 return cxstring::createRef("OMPSingleDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004004 case CXCursor_OMPParallelForDirective:
4005 return cxstring::createRef("OMPParallelForDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 }
4007
4008 llvm_unreachable("Unhandled CXCursorKind");
4009}
4010
4011struct GetCursorData {
4012 SourceLocation TokenBeginLoc;
4013 bool PointsAtMacroArgExpansion;
4014 bool VisitedObjCPropertyImplDecl;
4015 SourceLocation VisitedDeclaratorDeclStartLoc;
4016 CXCursor &BestCursor;
4017
4018 GetCursorData(SourceManager &SM,
4019 SourceLocation tokenBegin, CXCursor &outputCursor)
4020 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4021 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4022 VisitedObjCPropertyImplDecl = false;
4023 }
4024};
4025
4026static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4027 CXCursor parent,
4028 CXClientData client_data) {
4029 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4030 CXCursor *BestCursor = &Data->BestCursor;
4031
4032 // If we point inside a macro argument we should provide info of what the
4033 // token is so use the actual cursor, don't replace it with a macro expansion
4034 // cursor.
4035 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4036 return CXChildVisit_Recurse;
4037
4038 if (clang_isDeclaration(cursor.kind)) {
4039 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004040 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4042 if (MD->isImplicit())
4043 return CXChildVisit_Break;
4044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4047 // Check that when we have multiple @class references in the same line,
4048 // that later ones do not override the previous ones.
4049 // If we have:
4050 // @class Foo, Bar;
4051 // source ranges for both start at '@', so 'Bar' will end up overriding
4052 // 'Foo' even though the cursor location was at 'Foo'.
4053 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4054 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004055 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4057 if (PrevID != ID &&
4058 !PrevID->isThisDeclarationADefinition() &&
4059 !ID->isThisDeclarationADefinition())
4060 return CXChildVisit_Break;
4061 }
4062
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004063 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4065 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4066 // Check that when we have multiple declarators in the same line,
4067 // that later ones do not override the previous ones.
4068 // If we have:
4069 // int Foo, Bar;
4070 // source ranges for both start at 'int', so 'Bar' will end up overriding
4071 // 'Foo' even though the cursor location was at 'Foo'.
4072 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4073 return CXChildVisit_Break;
4074 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4075
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004076 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4078 (void)PropImp;
4079 // Check that when we have multiple @synthesize in the same line,
4080 // that later ones do not override the previous ones.
4081 // If we have:
4082 // @synthesize Foo, Bar;
4083 // source ranges for both start at '@', so 'Bar' will end up overriding
4084 // 'Foo' even though the cursor location was at 'Foo'.
4085 if (Data->VisitedObjCPropertyImplDecl)
4086 return CXChildVisit_Break;
4087 Data->VisitedObjCPropertyImplDecl = true;
4088 }
4089 }
4090
4091 if (clang_isExpression(cursor.kind) &&
4092 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004093 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 // Avoid having the cursor of an expression replace the declaration cursor
4095 // when the expression source range overlaps the declaration range.
4096 // This can happen for C++ constructor expressions whose range generally
4097 // include the variable declaration, e.g.:
4098 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4099 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4100 D->getLocation() == Data->TokenBeginLoc)
4101 return CXChildVisit_Break;
4102 }
4103 }
4104
4105 // If our current best cursor is the construction of a temporary object,
4106 // don't replace that cursor with a type reference, because we want
4107 // clang_getCursor() to point at the constructor.
4108 if (clang_isExpression(BestCursor->kind) &&
4109 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4110 cursor.kind == CXCursor_TypeRef) {
4111 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4112 // as having the actual point on the type reference.
4113 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4114 return CXChildVisit_Recurse;
4115 }
4116
4117 *BestCursor = cursor;
4118 return CXChildVisit_Recurse;
4119}
4120
4121CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004122 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004123 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004125 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004126
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004127 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4129
4130 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4131 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4132
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004133 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 CXFile SearchFile;
4135 unsigned SearchLine, SearchColumn;
4136 CXFile ResultFile;
4137 unsigned ResultLine, ResultColumn;
4138 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4139 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4140 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004141
4142 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4143 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004144 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004145 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 SearchFileName = clang_getFileName(SearchFile);
4147 ResultFileName = clang_getFileName(ResultFile);
4148 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4149 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004150 *Log << llvm::format("(%s:%d:%d) = %s",
4151 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4152 clang_getCString(KindSpelling))
4153 << llvm::format("(%s:%d:%d):%s%s",
4154 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4155 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 clang_disposeString(SearchFileName);
4157 clang_disposeString(ResultFileName);
4158 clang_disposeString(KindSpelling);
4159 clang_disposeString(USR);
4160
4161 CXCursor Definition = clang_getCursorDefinition(Result);
4162 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4163 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4164 CXString DefinitionKindSpelling
4165 = clang_getCursorKindSpelling(Definition.kind);
4166 CXFile DefinitionFile;
4167 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004168 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004169 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004171 *Log << llvm::format(" -> %s(%s:%d:%d)",
4172 clang_getCString(DefinitionKindSpelling),
4173 clang_getCString(DefinitionFileName),
4174 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 clang_disposeString(DefinitionFileName);
4176 clang_disposeString(DefinitionKindSpelling);
4177 }
4178 }
4179
4180 return Result;
4181}
4182
4183CXCursor clang_getNullCursor(void) {
4184 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4185}
4186
4187unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004188 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4189 // can't set consistently. For example, when visiting a DeclStmt we will set
4190 // it but we don't set it on the result of clang_getCursorDefinition for
4191 // a reference of the same declaration.
4192 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4193 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4194 // to provide that kind of info.
4195 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004196 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004197 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004198 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004199
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 return X == Y;
4201}
4202
4203unsigned clang_hashCursor(CXCursor C) {
4204 unsigned Index = 0;
4205 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4206 Index = 1;
4207
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004208 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 std::make_pair(C.kind, C.data[Index]));
4210}
4211
4212unsigned clang_isInvalid(enum CXCursorKind K) {
4213 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4214}
4215
4216unsigned clang_isDeclaration(enum CXCursorKind K) {
4217 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4218 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4219}
4220
4221unsigned clang_isReference(enum CXCursorKind K) {
4222 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4223}
4224
4225unsigned clang_isExpression(enum CXCursorKind K) {
4226 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4227}
4228
4229unsigned clang_isStatement(enum CXCursorKind K) {
4230 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4231}
4232
4233unsigned clang_isAttribute(enum CXCursorKind K) {
4234 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4235}
4236
4237unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4238 return K == CXCursor_TranslationUnit;
4239}
4240
4241unsigned clang_isPreprocessing(enum CXCursorKind K) {
4242 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4243}
4244
4245unsigned clang_isUnexposed(enum CXCursorKind K) {
4246 switch (K) {
4247 case CXCursor_UnexposedDecl:
4248 case CXCursor_UnexposedExpr:
4249 case CXCursor_UnexposedStmt:
4250 case CXCursor_UnexposedAttr:
4251 return true;
4252 default:
4253 return false;
4254 }
4255}
4256
4257CXCursorKind clang_getCursorKind(CXCursor C) {
4258 return C.kind;
4259}
4260
4261CXSourceLocation clang_getCursorLocation(CXCursor C) {
4262 if (clang_isReference(C.kind)) {
4263 switch (C.kind) {
4264 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004265 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 = getCursorObjCSuperClassRef(C);
4267 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4268 }
4269
4270 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004271 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 = getCursorObjCProtocolRef(C);
4273 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4274 }
4275
4276 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004277 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 = getCursorObjCClassRef(C);
4279 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4280 }
4281
4282 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004283 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4285 }
4286
4287 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004288 std::pair<const TemplateDecl *, SourceLocation> P =
4289 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4291 }
4292
4293 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004294 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4296 }
4297
4298 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004299 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4301 }
4302
4303 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004304 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4306 }
4307
4308 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004309 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 if (!BaseSpec)
4311 return clang_getNullLocation();
4312
4313 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4314 return cxloc::translateSourceLocation(getCursorContext(C),
4315 TSInfo->getTypeLoc().getBeginLoc());
4316
4317 return cxloc::translateSourceLocation(getCursorContext(C),
4318 BaseSpec->getLocStart());
4319 }
4320
4321 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004322 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4324 }
4325
4326 case CXCursor_OverloadedDeclRef:
4327 return cxloc::translateSourceLocation(getCursorContext(C),
4328 getCursorOverloadedDeclRef(C).second);
4329
4330 default:
4331 // FIXME: Need a way to enumerate all non-reference cases.
4332 llvm_unreachable("Missed a reference kind");
4333 }
4334 }
4335
4336 if (clang_isExpression(C.kind))
4337 return cxloc::translateSourceLocation(getCursorContext(C),
4338 getLocationFromExpr(getCursorExpr(C)));
4339
4340 if (clang_isStatement(C.kind))
4341 return cxloc::translateSourceLocation(getCursorContext(C),
4342 getCursorStmt(C)->getLocStart());
4343
4344 if (C.kind == CXCursor_PreprocessingDirective) {
4345 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4346 return cxloc::translateSourceLocation(getCursorContext(C), L);
4347 }
4348
4349 if (C.kind == CXCursor_MacroExpansion) {
4350 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004351 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 return cxloc::translateSourceLocation(getCursorContext(C), L);
4353 }
4354
4355 if (C.kind == CXCursor_MacroDefinition) {
4356 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4357 return cxloc::translateSourceLocation(getCursorContext(C), L);
4358 }
4359
4360 if (C.kind == CXCursor_InclusionDirective) {
4361 SourceLocation L
4362 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4363 return cxloc::translateSourceLocation(getCursorContext(C), L);
4364 }
4365
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004366 if (clang_isAttribute(C.kind)) {
4367 SourceLocation L
4368 = cxcursor::getCursorAttr(C)->getLocation();
4369 return cxloc::translateSourceLocation(getCursorContext(C), L);
4370 }
4371
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 if (!clang_isDeclaration(C.kind))
4373 return clang_getNullLocation();
4374
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 if (!D)
4377 return clang_getNullLocation();
4378
4379 SourceLocation Loc = D->getLocation();
4380 // FIXME: Multiple variables declared in a single declaration
4381 // currently lack the information needed to correctly determine their
4382 // ranges when accounting for the type-specifier. We use context
4383 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4384 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004385 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 if (!cxcursor::isFirstInDeclGroup(C))
4387 Loc = VD->getLocation();
4388 }
4389
4390 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004391 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 Loc = MD->getSelectorStartLoc();
4393
4394 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4395}
4396
4397} // end extern "C"
4398
4399CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4400 assert(TU);
4401
4402 // Guard against an invalid SourceLocation, or we may assert in one
4403 // of the following calls.
4404 if (SLoc.isInvalid())
4405 return clang_getNullCursor();
4406
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004407 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004408
4409 // Translate the given source location to make it point at the beginning of
4410 // the token under the cursor.
4411 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4412 CXXUnit->getASTContext().getLangOpts());
4413
4414 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4415 if (SLoc.isValid()) {
4416 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4417 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4418 /*VisitPreprocessorLast=*/true,
4419 /*VisitIncludedEntities=*/false,
4420 SourceLocation(SLoc));
4421 CursorVis.visitFileRegion();
4422 }
4423
4424 return Result;
4425}
4426
4427static SourceRange getRawCursorExtent(CXCursor C) {
4428 if (clang_isReference(C.kind)) {
4429 switch (C.kind) {
4430 case CXCursor_ObjCSuperClassRef:
4431 return getCursorObjCSuperClassRef(C).second;
4432
4433 case CXCursor_ObjCProtocolRef:
4434 return getCursorObjCProtocolRef(C).second;
4435
4436 case CXCursor_ObjCClassRef:
4437 return getCursorObjCClassRef(C).second;
4438
4439 case CXCursor_TypeRef:
4440 return getCursorTypeRef(C).second;
4441
4442 case CXCursor_TemplateRef:
4443 return getCursorTemplateRef(C).second;
4444
4445 case CXCursor_NamespaceRef:
4446 return getCursorNamespaceRef(C).second;
4447
4448 case CXCursor_MemberRef:
4449 return getCursorMemberRef(C).second;
4450
4451 case CXCursor_CXXBaseSpecifier:
4452 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4453
4454 case CXCursor_LabelRef:
4455 return getCursorLabelRef(C).second;
4456
4457 case CXCursor_OverloadedDeclRef:
4458 return getCursorOverloadedDeclRef(C).second;
4459
4460 case CXCursor_VariableRef:
4461 return getCursorVariableRef(C).second;
4462
4463 default:
4464 // FIXME: Need a way to enumerate all non-reference cases.
4465 llvm_unreachable("Missed a reference kind");
4466 }
4467 }
4468
4469 if (clang_isExpression(C.kind))
4470 return getCursorExpr(C)->getSourceRange();
4471
4472 if (clang_isStatement(C.kind))
4473 return getCursorStmt(C)->getSourceRange();
4474
4475 if (clang_isAttribute(C.kind))
4476 return getCursorAttr(C)->getRange();
4477
4478 if (C.kind == CXCursor_PreprocessingDirective)
4479 return cxcursor::getCursorPreprocessingDirective(C);
4480
4481 if (C.kind == CXCursor_MacroExpansion) {
4482 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004483 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 return TU->mapRangeFromPreamble(Range);
4485 }
4486
4487 if (C.kind == CXCursor_MacroDefinition) {
4488 ASTUnit *TU = getCursorASTUnit(C);
4489 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4490 return TU->mapRangeFromPreamble(Range);
4491 }
4492
4493 if (C.kind == CXCursor_InclusionDirective) {
4494 ASTUnit *TU = getCursorASTUnit(C);
4495 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4496 return TU->mapRangeFromPreamble(Range);
4497 }
4498
4499 if (C.kind == CXCursor_TranslationUnit) {
4500 ASTUnit *TU = getCursorASTUnit(C);
4501 FileID MainID = TU->getSourceManager().getMainFileID();
4502 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4503 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4504 return SourceRange(Start, End);
4505 }
4506
4507 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 if (!D)
4510 return SourceRange();
4511
4512 SourceRange R = D->getSourceRange();
4513 // FIXME: Multiple variables declared in a single declaration
4514 // currently lack the information needed to correctly determine their
4515 // ranges when accounting for the type-specifier. We use context
4516 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4517 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004518 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 if (!cxcursor::isFirstInDeclGroup(C))
4520 R.setBegin(VD->getLocation());
4521 }
4522 return R;
4523 }
4524 return SourceRange();
4525}
4526
4527/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4528/// the decl-specifier-seq for declarations.
4529static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4530 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004531 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 if (!D)
4533 return SourceRange();
4534
4535 SourceRange R = D->getSourceRange();
4536
4537 // Adjust the start of the location for declarations preceded by
4538 // declaration specifiers.
4539 SourceLocation StartLoc;
4540 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4541 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4542 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004543 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4545 StartLoc = TI->getTypeLoc().getLocStart();
4546 }
4547
4548 if (StartLoc.isValid() && R.getBegin().isValid() &&
4549 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4550 R.setBegin(StartLoc);
4551
4552 // FIXME: Multiple variables declared in a single declaration
4553 // currently lack the information needed to correctly determine their
4554 // ranges when accounting for the type-specifier. We use context
4555 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4556 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004557 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 if (!cxcursor::isFirstInDeclGroup(C))
4559 R.setBegin(VD->getLocation());
4560 }
4561
4562 return R;
4563 }
4564
4565 return getRawCursorExtent(C);
4566}
4567
4568extern "C" {
4569
4570CXSourceRange clang_getCursorExtent(CXCursor C) {
4571 SourceRange R = getRawCursorExtent(C);
4572 if (R.isInvalid())
4573 return clang_getNullRange();
4574
4575 return cxloc::translateSourceRange(getCursorContext(C), R);
4576}
4577
4578CXCursor clang_getCursorReferenced(CXCursor C) {
4579 if (clang_isInvalid(C.kind))
4580 return clang_getNullCursor();
4581
4582 CXTranslationUnit tu = getCursorTU(C);
4583 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004584 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 if (!D)
4586 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004587 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004589 if (const ObjCPropertyImplDecl *PropImpl =
4590 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4592 return MakeCXCursor(Property, tu);
4593
4594 return C;
4595 }
4596
4597 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004598 const Expr *E = getCursorExpr(C);
4599 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 if (D) {
4601 CXCursor declCursor = MakeCXCursor(D, tu);
4602 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4603 declCursor);
4604 return declCursor;
4605 }
4606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004607 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 return MakeCursorOverloadedDeclRef(Ovl, tu);
4609
4610 return clang_getNullCursor();
4611 }
4612
4613 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004614 const Stmt *S = getCursorStmt(C);
4615 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 if (LabelDecl *label = Goto->getLabel())
4617 if (LabelStmt *labelS = label->getStmt())
4618 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4619
4620 return clang_getNullCursor();
4621 }
4622
4623 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004624 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 return MakeMacroDefinitionCursor(Def, tu);
4626 }
4627
4628 if (!clang_isReference(C.kind))
4629 return clang_getNullCursor();
4630
4631 switch (C.kind) {
4632 case CXCursor_ObjCSuperClassRef:
4633 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4634
4635 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004636 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4637 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 return MakeCXCursor(Def, tu);
4639
4640 return MakeCXCursor(Prot, tu);
4641 }
4642
4643 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004644 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4645 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 return MakeCXCursor(Def, tu);
4647
4648 return MakeCXCursor(Class, tu);
4649 }
4650
4651 case CXCursor_TypeRef:
4652 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4653
4654 case CXCursor_TemplateRef:
4655 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4656
4657 case CXCursor_NamespaceRef:
4658 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4659
4660 case CXCursor_MemberRef:
4661 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4662
4663 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004664 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4666 tu ));
4667 }
4668
4669 case CXCursor_LabelRef:
4670 // FIXME: We end up faking the "parent" declaration here because we
4671 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004672 return MakeCXCursor(getCursorLabelRef(C).first,
4673 cxtu::getASTUnit(tu)->getASTContext()
4674 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 tu);
4676
4677 case CXCursor_OverloadedDeclRef:
4678 return C;
4679
4680 case CXCursor_VariableRef:
4681 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4682
4683 default:
4684 // We would prefer to enumerate all non-reference cursor kinds here.
4685 llvm_unreachable("Unhandled reference cursor kind");
4686 }
4687}
4688
4689CXCursor clang_getCursorDefinition(CXCursor C) {
4690 if (clang_isInvalid(C.kind))
4691 return clang_getNullCursor();
4692
4693 CXTranslationUnit TU = getCursorTU(C);
4694
4695 bool WasReference = false;
4696 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4697 C = clang_getCursorReferenced(C);
4698 WasReference = true;
4699 }
4700
4701 if (C.kind == CXCursor_MacroExpansion)
4702 return clang_getCursorReferenced(C);
4703
4704 if (!clang_isDeclaration(C.kind))
4705 return clang_getNullCursor();
4706
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004707 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 if (!D)
4709 return clang_getNullCursor();
4710
4711 switch (D->getKind()) {
4712 // Declaration kinds that don't really separate the notions of
4713 // declaration and definition.
4714 case Decl::Namespace:
4715 case Decl::Typedef:
4716 case Decl::TypeAlias:
4717 case Decl::TypeAliasTemplate:
4718 case Decl::TemplateTypeParm:
4719 case Decl::EnumConstant:
4720 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004721 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 case Decl::IndirectField:
4723 case Decl::ObjCIvar:
4724 case Decl::ObjCAtDefsField:
4725 case Decl::ImplicitParam:
4726 case Decl::ParmVar:
4727 case Decl::NonTypeTemplateParm:
4728 case Decl::TemplateTemplateParm:
4729 case Decl::ObjCCategoryImpl:
4730 case Decl::ObjCImplementation:
4731 case Decl::AccessSpec:
4732 case Decl::LinkageSpec:
4733 case Decl::ObjCPropertyImpl:
4734 case Decl::FileScopeAsm:
4735 case Decl::StaticAssert:
4736 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004737 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 case Decl::Label: // FIXME: Is this right??
4739 case Decl::ClassScopeFunctionSpecialization:
4740 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004741 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 return C;
4743
4744 // Declaration kinds that don't make any sense here, but are
4745 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004746 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case Decl::TranslationUnit:
4748 break;
4749
4750 // Declaration kinds for which the definition is not resolvable.
4751 case Decl::UnresolvedUsingTypename:
4752 case Decl::UnresolvedUsingValue:
4753 break;
4754
4755 case Decl::UsingDirective:
4756 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4757 TU);
4758
4759 case Decl::NamespaceAlias:
4760 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4761
4762 case Decl::Enum:
4763 case Decl::Record:
4764 case Decl::CXXRecord:
4765 case Decl::ClassTemplateSpecialization:
4766 case Decl::ClassTemplatePartialSpecialization:
4767 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4768 return MakeCXCursor(Def, TU);
4769 return clang_getNullCursor();
4770
4771 case Decl::Function:
4772 case Decl::CXXMethod:
4773 case Decl::CXXConstructor:
4774 case Decl::CXXDestructor:
4775 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004776 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004778 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 return clang_getNullCursor();
4780 }
4781
Larisse Voufo39a1e502013-08-06 01:03:05 +00004782 case Decl::Var:
4783 case Decl::VarTemplateSpecialization:
4784 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return MakeCXCursor(Def, TU);
4788 return clang_getNullCursor();
4789 }
4790
4791 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004792 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4794 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4795 return clang_getNullCursor();
4796 }
4797
4798 case Decl::ClassTemplate: {
4799 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4800 ->getDefinition())
4801 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4802 TU);
4803 return clang_getNullCursor();
4804 }
4805
Larisse Voufo39a1e502013-08-06 01:03:05 +00004806 case Decl::VarTemplate: {
4807 if (VarDecl *Def =
4808 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4809 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4810 return clang_getNullCursor();
4811 }
4812
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 case Decl::Using:
4814 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4815 D->getLocation(), TU);
4816
4817 case Decl::UsingShadow:
4818 return clang_getCursorDefinition(
4819 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4820 TU));
4821
4822 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004823 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 if (Method->isThisDeclarationADefinition())
4825 return C;
4826
4827 // Dig out the method definition in the associated
4828 // @implementation, if we have it.
4829 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004830 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4832 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4833 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4834 Method->isInstanceMethod()))
4835 if (Def->isThisDeclarationADefinition())
4836 return MakeCXCursor(Def, TU);
4837
4838 return clang_getNullCursor();
4839 }
4840
4841 case Decl::ObjCCategory:
4842 if (ObjCCategoryImplDecl *Impl
4843 = cast<ObjCCategoryDecl>(D)->getImplementation())
4844 return MakeCXCursor(Impl, TU);
4845 return clang_getNullCursor();
4846
4847 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 return MakeCXCursor(Def, TU);
4850 return clang_getNullCursor();
4851
4852 case Decl::ObjCInterface: {
4853 // There are two notions of a "definition" for an Objective-C
4854 // class: the interface and its implementation. When we resolved a
4855 // reference to an Objective-C class, produce the @interface as
4856 // the definition; when we were provided with the interface,
4857 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004860 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 return MakeCXCursor(Def, TU);
4862 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4863 return MakeCXCursor(Impl, TU);
4864 return clang_getNullCursor();
4865 }
4866
4867 case Decl::ObjCProperty:
4868 // FIXME: We don't really know where to find the
4869 // ObjCPropertyImplDecls that implement this property.
4870 return clang_getNullCursor();
4871
4872 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004873 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCXCursor(Def, TU);
4877
4878 return clang_getNullCursor();
4879
4880 case Decl::Friend:
4881 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4882 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4883 return clang_getNullCursor();
4884
4885 case Decl::FriendTemplate:
4886 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4887 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4888 return clang_getNullCursor();
4889 }
4890
4891 return clang_getNullCursor();
4892}
4893
4894unsigned clang_isCursorDefinition(CXCursor C) {
4895 if (!clang_isDeclaration(C.kind))
4896 return 0;
4897
4898 return clang_getCursorDefinition(C) == C;
4899}
4900
4901CXCursor clang_getCanonicalCursor(CXCursor C) {
4902 if (!clang_isDeclaration(C.kind))
4903 return C;
4904
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 if (const Decl *D = getCursorDecl(C)) {
4906 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4908 return MakeCXCursor(CatD, getCursorTU(C));
4909
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004910 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4911 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 return MakeCXCursor(IFD, getCursorTU(C));
4913
4914 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4915 }
4916
4917 return C;
4918}
4919
4920int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4921 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4922}
4923
4924unsigned clang_getNumOverloadedDecls(CXCursor C) {
4925 if (C.kind != CXCursor_OverloadedDeclRef)
4926 return 0;
4927
4928 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004929 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 return E->getNumDecls();
4931
4932 if (OverloadedTemplateStorage *S
4933 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4934 return S->size();
4935
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004936 const Decl *D = Storage.get<const Decl *>();
4937 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 return Using->shadow_size();
4939
4940 return 0;
4941}
4942
4943CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4944 if (cursor.kind != CXCursor_OverloadedDeclRef)
4945 return clang_getNullCursor();
4946
4947 if (index >= clang_getNumOverloadedDecls(cursor))
4948 return clang_getNullCursor();
4949
4950 CXTranslationUnit TU = getCursorTU(cursor);
4951 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 return MakeCXCursor(E->decls_begin()[index], TU);
4954
4955 if (OverloadedTemplateStorage *S
4956 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4957 return MakeCXCursor(S->begin()[index], TU);
4958
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004959 const Decl *D = Storage.get<const Decl *>();
4960 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 // FIXME: This is, unfortunately, linear time.
4962 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4963 std::advance(Pos, index);
4964 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4965 }
4966
4967 return clang_getNullCursor();
4968}
4969
4970void clang_getDefinitionSpellingAndExtent(CXCursor C,
4971 const char **startBuf,
4972 const char **endBuf,
4973 unsigned *startLine,
4974 unsigned *startColumn,
4975 unsigned *endLine,
4976 unsigned *endColumn) {
4977 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004978 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4980
4981 SourceManager &SM = FD->getASTContext().getSourceManager();
4982 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4983 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4984 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4985 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4986 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4987 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4988}
4989
4990
4991CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4992 unsigned PieceIndex) {
4993 RefNamePieces Pieces;
4994
4995 switch (C.kind) {
4996 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004997 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4999 E->getQualifierLoc().getSourceRange());
5000 break;
5001
5002 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005003 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5005 E->getQualifierLoc().getSourceRange(),
5006 E->getOptionalExplicitTemplateArgs());
5007 break;
5008
5009 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005010 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005011 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005012 const Expr *Callee = OCE->getCallee();
5013 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 Callee = ICE->getSubExpr();
5015
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005016 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5018 DRE->getQualifierLoc().getSourceRange());
5019 }
5020 break;
5021
5022 default:
5023 break;
5024 }
5025
5026 if (Pieces.empty()) {
5027 if (PieceIndex == 0)
5028 return clang_getCursorExtent(C);
5029 } else if (PieceIndex < Pieces.size()) {
5030 SourceRange R = Pieces[PieceIndex];
5031 if (R.isValid())
5032 return cxloc::translateSourceRange(getCursorContext(C), R);
5033 }
5034
5035 return clang_getNullRange();
5036}
5037
5038void clang_enableStackTraces(void) {
5039 llvm::sys::PrintStackTraceOnErrorSignal();
5040}
5041
5042void clang_executeOnThread(void (*fn)(void*), void *user_data,
5043 unsigned stack_size) {
5044 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5045}
5046
5047} // end: extern "C"
5048
5049//===----------------------------------------------------------------------===//
5050// Token-based Operations.
5051//===----------------------------------------------------------------------===//
5052
5053/* CXToken layout:
5054 * int_data[0]: a CXTokenKind
5055 * int_data[1]: starting token location
5056 * int_data[2]: token length
5057 * int_data[3]: reserved
5058 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5059 * otherwise unused.
5060 */
5061extern "C" {
5062
5063CXTokenKind clang_getTokenKind(CXToken CXTok) {
5064 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5065}
5066
5067CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5068 switch (clang_getTokenKind(CXTok)) {
5069 case CXToken_Identifier:
5070 case CXToken_Keyword:
5071 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005072 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 ->getNameStart());
5074
5075 case CXToken_Literal: {
5076 // We have stashed the starting pointer in the ptr_data field. Use it.
5077 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005078 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 }
5080
5081 case CXToken_Punctuation:
5082 case CXToken_Comment:
5083 break;
5084 }
5085
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005086 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005087 LOG_BAD_TU(TU);
5088 return cxstring::createEmpty();
5089 }
5090
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 // We have to find the starting buffer pointer the hard way, by
5092 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005093 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005095 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005096
5097 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5098 std::pair<FileID, unsigned> LocInfo
5099 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5100 bool Invalid = false;
5101 StringRef Buffer
5102 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5103 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005104 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005105
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005106 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005107}
5108
5109CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005110 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005111 LOG_BAD_TU(TU);
5112 return clang_getNullLocation();
5113 }
5114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005115 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 if (!CXXUnit)
5117 return clang_getNullLocation();
5118
5119 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5120 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5121}
5122
5123CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005124 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005125 LOG_BAD_TU(TU);
5126 return clang_getNullRange();
5127 }
5128
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005129 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 if (!CXXUnit)
5131 return clang_getNullRange();
5132
5133 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5134 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5135}
5136
5137static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5138 SmallVectorImpl<CXToken> &CXTokens) {
5139 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5140 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005141 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005143 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005144
5145 // Cannot tokenize across files.
5146 if (BeginLocInfo.first != EndLocInfo.first)
5147 return;
5148
5149 // Create a lexer
5150 bool Invalid = false;
5151 StringRef Buffer
5152 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5153 if (Invalid)
5154 return;
5155
5156 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5157 CXXUnit->getASTContext().getLangOpts(),
5158 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5159 Lex.SetCommentRetentionState(true);
5160
5161 // Lex tokens until we hit the end of the range.
5162 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5163 Token Tok;
5164 bool previousWasAt = false;
5165 do {
5166 // Lex the next token
5167 Lex.LexFromRawLexer(Tok);
5168 if (Tok.is(tok::eof))
5169 break;
5170
5171 // Initialize the CXToken.
5172 CXToken CXTok;
5173
5174 // - Common fields
5175 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5176 CXTok.int_data[2] = Tok.getLength();
5177 CXTok.int_data[3] = 0;
5178
5179 // - Kind-specific fields
5180 if (Tok.isLiteral()) {
5181 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005182 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 } else if (Tok.is(tok::raw_identifier)) {
5184 // Lookup the identifier to determine whether we have a keyword.
5185 IdentifierInfo *II
5186 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5187
5188 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5189 CXTok.int_data[0] = CXToken_Keyword;
5190 }
5191 else {
5192 CXTok.int_data[0] = Tok.is(tok::identifier)
5193 ? CXToken_Identifier
5194 : CXToken_Keyword;
5195 }
5196 CXTok.ptr_data = II;
5197 } else if (Tok.is(tok::comment)) {
5198 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005199 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 } else {
5201 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005202 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 }
5204 CXTokens.push_back(CXTok);
5205 previousWasAt = Tok.is(tok::at);
5206 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5207}
5208
5209void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5210 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005211 LOG_FUNC_SECTION {
5212 *Log << TU << ' ' << Range;
5213 }
5214
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005216 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 if (NumTokens)
5218 *NumTokens = 0;
5219
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005220 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005221 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005222 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005223 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005224
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005225 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 if (!CXXUnit || !Tokens || !NumTokens)
5227 return;
5228
5229 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5230
5231 SourceRange R = cxloc::translateCXSourceRange(Range);
5232 if (R.isInvalid())
5233 return;
5234
5235 SmallVector<CXToken, 32> CXTokens;
5236 getTokens(CXXUnit, R, CXTokens);
5237
5238 if (CXTokens.empty())
5239 return;
5240
5241 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5242 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5243 *NumTokens = CXTokens.size();
5244}
5245
5246void clang_disposeTokens(CXTranslationUnit TU,
5247 CXToken *Tokens, unsigned NumTokens) {
5248 free(Tokens);
5249}
5250
5251} // end: extern "C"
5252
5253//===----------------------------------------------------------------------===//
5254// Token annotation APIs.
5255//===----------------------------------------------------------------------===//
5256
Guy Benyei11169dd2012-12-18 14:30:41 +00005257static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5258 CXCursor parent,
5259 CXClientData client_data);
5260static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5261 CXClientData client_data);
5262
5263namespace {
5264class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 CXToken *Tokens;
5266 CXCursor *Cursors;
5267 unsigned NumTokens;
5268 unsigned TokIdx;
5269 unsigned PreprocessingTokIdx;
5270 CursorVisitor AnnotateVis;
5271 SourceManager &SrcMgr;
5272 bool HasContextSensitiveKeywords;
5273
5274 struct PostChildrenInfo {
5275 CXCursor Cursor;
5276 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005277 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 unsigned BeforeChildrenTokenIdx;
5279 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005280 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005281
5282 CXToken &getTok(unsigned Idx) {
5283 assert(Idx < NumTokens);
5284 return Tokens[Idx];
5285 }
5286 const CXToken &getTok(unsigned Idx) const {
5287 assert(Idx < NumTokens);
5288 return Tokens[Idx];
5289 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 bool MoreTokens() const { return TokIdx < NumTokens; }
5291 unsigned NextToken() const { return TokIdx; }
5292 void AdvanceToken() { ++TokIdx; }
5293 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005294 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 }
5296 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005297 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 }
5299 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005300 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 }
5302
5303 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005304 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 SourceRange);
5306
5307public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005308 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005309 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005310 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005312 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 AnnotateTokensVisitor, this,
5314 /*VisitPreprocessorLast=*/true,
5315 /*VisitIncludedEntities=*/false,
5316 RegionOfInterest,
5317 /*VisitDeclsOnly=*/false,
5318 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005319 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 HasContextSensitiveKeywords(false) { }
5321
5322 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5323 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5324 bool postVisitChildren(CXCursor cursor);
5325 void AnnotateTokens();
5326
5327 /// \brief Determine whether the annotator saw any cursors that have
5328 /// context-sensitive keywords.
5329 bool hasContextSensitiveKeywords() const {
5330 return HasContextSensitiveKeywords;
5331 }
5332
5333 ~AnnotateTokensWorker() {
5334 assert(PostChildrenInfos.empty());
5335 }
5336};
5337}
5338
5339void AnnotateTokensWorker::AnnotateTokens() {
5340 // Walk the AST within the region of interest, annotating tokens
5341 // along the way.
5342 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005343}
Guy Benyei11169dd2012-12-18 14:30:41 +00005344
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005345static inline void updateCursorAnnotation(CXCursor &Cursor,
5346 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005347 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005349 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005350}
5351
5352/// \brief It annotates and advances tokens with a cursor until the comparison
5353//// between the cursor location and the source range is the same as
5354/// \arg compResult.
5355///
5356/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5357/// Pass RangeOverlap to annotate tokens inside a range.
5358void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5359 RangeComparisonResult compResult,
5360 SourceRange range) {
5361 while (MoreTokens()) {
5362 const unsigned I = NextToken();
5363 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005364 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5365 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005366
5367 SourceLocation TokLoc = GetTokenLoc(I);
5368 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005369 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 AdvanceToken();
5371 continue;
5372 }
5373 break;
5374 }
5375}
5376
5377/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005378/// \returns true if it advanced beyond all macro tokens, false otherwise.
5379bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 CXCursor updateC,
5381 RangeComparisonResult compResult,
5382 SourceRange range) {
5383 assert(MoreTokens());
5384 assert(isFunctionMacroToken(NextToken()) &&
5385 "Should be called only for macro arg tokens");
5386
5387 // This works differently than annotateAndAdvanceTokens; because expanded
5388 // macro arguments can have arbitrary translation-unit source order, we do not
5389 // advance the token index one by one until a token fails the range test.
5390 // We only advance once past all of the macro arg tokens if all of them
5391 // pass the range test. If one of them fails we keep the token index pointing
5392 // at the start of the macro arg tokens so that the failing token will be
5393 // annotated by a subsequent annotation try.
5394
5395 bool atLeastOneCompFail = false;
5396
5397 unsigned I = NextToken();
5398 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5399 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5400 if (TokLoc.isFileID())
5401 continue; // not macro arg token, it's parens or comma.
5402 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5403 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5404 Cursors[I] = updateC;
5405 } else
5406 atLeastOneCompFail = true;
5407 }
5408
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005409 if (atLeastOneCompFail)
5410 return false;
5411
5412 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5413 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005414}
5415
5416enum CXChildVisitResult
5417AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 SourceRange cursorRange = getRawCursorExtent(cursor);
5419 if (cursorRange.isInvalid())
5420 return CXChildVisit_Recurse;
5421
5422 if (!HasContextSensitiveKeywords) {
5423 // Objective-C properties can have context-sensitive keywords.
5424 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5427 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5428 }
5429 // Objective-C methods can have context-sensitive keywords.
5430 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5431 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005432 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5434 if (Method->getObjCDeclQualifier())
5435 HasContextSensitiveKeywords = true;
5436 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005437 for (const auto *P : Method->params()) {
5438 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 HasContextSensitiveKeywords = true;
5440 break;
5441 }
5442 }
5443 }
5444 }
5445 }
5446 // C++ methods can have context-sensitive keywords.
5447 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005448 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5450 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5451 HasContextSensitiveKeywords = true;
5452 }
5453 }
5454 // C++ classes can have context-sensitive keywords.
5455 else if (cursor.kind == CXCursor_StructDecl ||
5456 cursor.kind == CXCursor_ClassDecl ||
5457 cursor.kind == CXCursor_ClassTemplate ||
5458 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005459 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 if (D->hasAttr<FinalAttr>())
5461 HasContextSensitiveKeywords = true;
5462 }
5463 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005464
5465 // Don't override a property annotation with its getter/setter method.
5466 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5467 parent.kind == CXCursor_ObjCPropertyDecl)
5468 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005469
5470 if (clang_isPreprocessing(cursor.kind)) {
5471 // Items in the preprocessing record are kept separate from items in
5472 // declarations, so we keep a separate token index.
5473 unsigned SavedTokIdx = TokIdx;
5474 TokIdx = PreprocessingTokIdx;
5475
5476 // Skip tokens up until we catch up to the beginning of the preprocessing
5477 // entry.
5478 while (MoreTokens()) {
5479 const unsigned I = NextToken();
5480 SourceLocation TokLoc = GetTokenLoc(I);
5481 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5482 case RangeBefore:
5483 AdvanceToken();
5484 continue;
5485 case RangeAfter:
5486 case RangeOverlap:
5487 break;
5488 }
5489 break;
5490 }
5491
5492 // Look at all of the tokens within this range.
5493 while (MoreTokens()) {
5494 const unsigned I = NextToken();
5495 SourceLocation TokLoc = GetTokenLoc(I);
5496 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5497 case RangeBefore:
5498 llvm_unreachable("Infeasible");
5499 case RangeAfter:
5500 break;
5501 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005502 // For macro expansions, just note where the beginning of the macro
5503 // expansion occurs.
5504 if (cursor.kind == CXCursor_MacroExpansion) {
5505 if (TokLoc == cursorRange.getBegin())
5506 Cursors[I] = cursor;
5507 AdvanceToken();
5508 break;
5509 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005510 // We may have already annotated macro names inside macro definitions.
5511 if (Cursors[I].kind != CXCursor_MacroExpansion)
5512 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 continue;
5515 }
5516 break;
5517 }
5518
5519 // Save the preprocessing token index; restore the non-preprocessing
5520 // token index.
5521 PreprocessingTokIdx = TokIdx;
5522 TokIdx = SavedTokIdx;
5523 return CXChildVisit_Recurse;
5524 }
5525
5526 if (cursorRange.isInvalid())
5527 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005528
5529 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 const enum CXCursorKind K = clang_getCursorKind(parent);
5532 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005533 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5534 // Attributes are annotated out-of-order, skip tokens until we reach it.
5535 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005536 ? clang_getNullCursor() : parent;
5537
5538 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5539
5540 // Avoid having the cursor of an expression "overwrite" the annotation of the
5541 // variable declaration that it belongs to.
5542 // This can happen for C++ constructor expressions whose range generally
5543 // include the variable declaration, e.g.:
5544 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005545 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005546 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005547 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 const unsigned I = NextToken();
5549 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5550 E->getLocStart() == D->getLocation() &&
5551 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005552 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 AdvanceToken();
5554 }
5555 }
5556 }
5557
5558 // Before recursing into the children keep some state that we are going
5559 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5560 // extra work after the child nodes are visited.
5561 // Note that we don't call VisitChildren here to avoid traversing statements
5562 // code-recursively which can blow the stack.
5563
5564 PostChildrenInfo Info;
5565 Info.Cursor = cursor;
5566 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005567 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 Info.BeforeChildrenTokenIdx = NextToken();
5569 PostChildrenInfos.push_back(Info);
5570
5571 return CXChildVisit_Recurse;
5572}
5573
5574bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5575 if (PostChildrenInfos.empty())
5576 return false;
5577 const PostChildrenInfo &Info = PostChildrenInfos.back();
5578 if (!clang_equalCursors(Info.Cursor, cursor))
5579 return false;
5580
5581 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5582 const unsigned AfterChildren = NextToken();
5583 SourceRange cursorRange = Info.CursorRange;
5584
5585 // Scan the tokens that are at the end of the cursor, but are not captured
5586 // but the child cursors.
5587 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5588
5589 // Scan the tokens that are at the beginning of the cursor, but are not
5590 // capture by the child cursors.
5591 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5592 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5593 break;
5594
5595 Cursors[I] = cursor;
5596 }
5597
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005598 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5599 // encountered the attribute cursor.
5600 if (clang_isAttribute(cursor.kind))
5601 TokIdx = Info.BeforeReachingCursorIdx;
5602
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 PostChildrenInfos.pop_back();
5604 return false;
5605}
5606
5607static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5608 CXCursor parent,
5609 CXClientData client_data) {
5610 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5611}
5612
5613static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5614 CXClientData client_data) {
5615 return static_cast<AnnotateTokensWorker*>(client_data)->
5616 postVisitChildren(cursor);
5617}
5618
5619namespace {
5620
5621/// \brief Uses the macro expansions in the preprocessing record to find
5622/// and mark tokens that are macro arguments. This info is used by the
5623/// AnnotateTokensWorker.
5624class MarkMacroArgTokensVisitor {
5625 SourceManager &SM;
5626 CXToken *Tokens;
5627 unsigned NumTokens;
5628 unsigned CurIdx;
5629
5630public:
5631 MarkMacroArgTokensVisitor(SourceManager &SM,
5632 CXToken *tokens, unsigned numTokens)
5633 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5634
5635 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5636 if (cursor.kind != CXCursor_MacroExpansion)
5637 return CXChildVisit_Continue;
5638
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005639 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 if (macroRange.getBegin() == macroRange.getEnd())
5641 return CXChildVisit_Continue; // it's not a function macro.
5642
5643 for (; CurIdx < NumTokens; ++CurIdx) {
5644 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5645 macroRange.getBegin()))
5646 break;
5647 }
5648
5649 if (CurIdx == NumTokens)
5650 return CXChildVisit_Break;
5651
5652 for (; CurIdx < NumTokens; ++CurIdx) {
5653 SourceLocation tokLoc = getTokenLoc(CurIdx);
5654 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5655 break;
5656
5657 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5658 }
5659
5660 if (CurIdx == NumTokens)
5661 return CXChildVisit_Break;
5662
5663 return CXChildVisit_Continue;
5664 }
5665
5666private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005667 CXToken &getTok(unsigned Idx) {
5668 assert(Idx < NumTokens);
5669 return Tokens[Idx];
5670 }
5671 const CXToken &getTok(unsigned Idx) const {
5672 assert(Idx < NumTokens);
5673 return Tokens[Idx];
5674 }
5675
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005677 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 }
5679
5680 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5681 // The third field is reserved and currently not used. Use it here
5682 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005683 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 }
5685};
5686
5687} // end anonymous namespace
5688
5689static CXChildVisitResult
5690MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5691 CXClientData client_data) {
5692 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5693 parent);
5694}
5695
5696namespace {
5697 struct clang_annotateTokens_Data {
5698 CXTranslationUnit TU;
5699 ASTUnit *CXXUnit;
5700 CXToken *Tokens;
5701 unsigned NumTokens;
5702 CXCursor *Cursors;
5703 };
5704}
5705
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005706/// \brief Used by \c annotatePreprocessorTokens.
5707/// \returns true if lexing was finished, false otherwise.
5708static bool lexNext(Lexer &Lex, Token &Tok,
5709 unsigned &NextIdx, unsigned NumTokens) {
5710 if (NextIdx >= NumTokens)
5711 return true;
5712
5713 ++NextIdx;
5714 Lex.LexFromRawLexer(Tok);
5715 if (Tok.is(tok::eof))
5716 return true;
5717
5718 return false;
5719}
5720
Guy Benyei11169dd2012-12-18 14:30:41 +00005721static void annotatePreprocessorTokens(CXTranslationUnit TU,
5722 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005723 CXCursor *Cursors,
5724 CXToken *Tokens,
5725 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005726 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005727
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005728 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5730 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005731 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005733 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005734
5735 if (BeginLocInfo.first != EndLocInfo.first)
5736 return;
5737
5738 StringRef Buffer;
5739 bool Invalid = false;
5740 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5741 if (Buffer.empty() || Invalid)
5742 return;
5743
5744 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5745 CXXUnit->getASTContext().getLangOpts(),
5746 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5747 Buffer.end());
5748 Lex.SetCommentRetentionState(true);
5749
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005750 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005751 // Lex tokens in raw mode until we hit the end of the range, to avoid
5752 // entering #includes or expanding macros.
5753 while (true) {
5754 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005755 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5756 break;
5757 unsigned TokIdx = NextIdx-1;
5758 assert(Tok.getLocation() ==
5759 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005760
5761 reprocess:
5762 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005763 // We have found a preprocessing directive. Annotate the tokens
5764 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 //
5766 // FIXME: Some simple tests here could identify macro definitions and
5767 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005768
5769 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005770 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5771 break;
5772
Craig Topper69186e72014-06-08 08:38:04 +00005773 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005774 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005775 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5776 break;
5777
5778 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005779 IdentifierInfo &II =
5780 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005781 SourceLocation MappedTokLoc =
5782 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5783 MI = getMacroInfo(II, MappedTokLoc, TU);
5784 }
5785 }
5786
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005787 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005789 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5790 finished = true;
5791 break;
5792 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005793 // If we are in a macro definition, check if the token was ever a
5794 // macro name and annotate it if that's the case.
5795 if (MI) {
5796 SourceLocation SaveLoc = Tok.getLocation();
5797 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5798 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5799 Tok.setLocation(SaveLoc);
5800 if (MacroDef)
5801 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5802 Tok.getLocation(), TU);
5803 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005804 } while (!Tok.isAtStartOfLine());
5805
5806 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5807 assert(TokIdx <= LastIdx);
5808 SourceLocation EndLoc =
5809 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5810 CXCursor Cursor =
5811 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5812
5813 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005814 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005815
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005816 if (finished)
5817 break;
5818 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 }
5821}
5822
5823// This gets run a separate thread to avoid stack blowout.
5824static void clang_annotateTokensImpl(void *UserData) {
5825 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5826 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5827 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5828 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5829 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5830
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005831 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005832 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5833 setThreadBackgroundPriority();
5834
5835 // Determine the region of interest, which contains all of the tokens.
5836 SourceRange RegionOfInterest;
5837 RegionOfInterest.setBegin(
5838 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5839 RegionOfInterest.setEnd(
5840 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5841 Tokens[NumTokens-1])));
5842
Guy Benyei11169dd2012-12-18 14:30:41 +00005843 // Relex the tokens within the source range to look for preprocessing
5844 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005845 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005846
5847 // If begin location points inside a macro argument, set it to the expansion
5848 // location so we can have the full context when annotating semantically.
5849 {
5850 SourceManager &SM = CXXUnit->getSourceManager();
5851 SourceLocation Loc =
5852 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5853 if (Loc.isMacroID())
5854 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5855 }
5856
Guy Benyei11169dd2012-12-18 14:30:41 +00005857 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5858 // Search and mark tokens that are macro argument expansions.
5859 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5860 Tokens, NumTokens);
5861 CursorVisitor MacroArgMarker(TU,
5862 MarkMacroArgTokensVisitorDelegate, &Visitor,
5863 /*VisitPreprocessorLast=*/true,
5864 /*VisitIncludedEntities=*/false,
5865 RegionOfInterest);
5866 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5867 }
5868
5869 // Annotate all of the source locations in the region of interest that map to
5870 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005871 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005872
5873 // FIXME: We use a ridiculous stack size here because the data-recursion
5874 // algorithm uses a large stack frame than the non-data recursive version,
5875 // and AnnotationTokensWorker currently transforms the data-recursion
5876 // algorithm back into a traditional recursion by explicitly calling
5877 // VisitChildren(). We will need to remove this explicit recursive call.
5878 W.AnnotateTokens();
5879
5880 // If we ran into any entities that involve context-sensitive keywords,
5881 // take another pass through the tokens to mark them as such.
5882 if (W.hasContextSensitiveKeywords()) {
5883 for (unsigned I = 0; I != NumTokens; ++I) {
5884 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5885 continue;
5886
5887 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5888 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005889 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5891 if (Property->getPropertyAttributesAsWritten() != 0 &&
5892 llvm::StringSwitch<bool>(II->getName())
5893 .Case("readonly", true)
5894 .Case("assign", true)
5895 .Case("unsafe_unretained", true)
5896 .Case("readwrite", true)
5897 .Case("retain", true)
5898 .Case("copy", true)
5899 .Case("nonatomic", true)
5900 .Case("atomic", true)
5901 .Case("getter", true)
5902 .Case("setter", true)
5903 .Case("strong", true)
5904 .Case("weak", true)
5905 .Default(false))
5906 Tokens[I].int_data[0] = CXToken_Keyword;
5907 }
5908 continue;
5909 }
5910
5911 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5912 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5913 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5914 if (llvm::StringSwitch<bool>(II->getName())
5915 .Case("in", true)
5916 .Case("out", true)
5917 .Case("inout", true)
5918 .Case("oneway", true)
5919 .Case("bycopy", true)
5920 .Case("byref", true)
5921 .Default(false))
5922 Tokens[I].int_data[0] = CXToken_Keyword;
5923 continue;
5924 }
5925
5926 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5927 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5928 Tokens[I].int_data[0] = CXToken_Keyword;
5929 continue;
5930 }
5931 }
5932 }
5933}
5934
5935extern "C" {
5936
5937void clang_annotateTokens(CXTranslationUnit TU,
5938 CXToken *Tokens, unsigned NumTokens,
5939 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005940 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005941 LOG_BAD_TU(TU);
5942 return;
5943 }
5944 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005945 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005947 }
5948
5949 LOG_FUNC_SECTION {
5950 *Log << TU << ' ';
5951 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5952 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5953 *Log << clang_getRange(bloc, eloc);
5954 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005955
5956 // Any token we don't specifically annotate will have a NULL cursor.
5957 CXCursor C = clang_getNullCursor();
5958 for (unsigned I = 0; I != NumTokens; ++I)
5959 Cursors[I] = C;
5960
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005961 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005962 if (!CXXUnit)
5963 return;
5964
5965 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5966
5967 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5968 llvm::CrashRecoveryContext CRC;
5969 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5970 GetSafetyThreadStackSize() * 2)) {
5971 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5972 }
5973}
5974
5975} // end: extern "C"
5976
5977//===----------------------------------------------------------------------===//
5978// Operations for querying linkage of a cursor.
5979//===----------------------------------------------------------------------===//
5980
5981extern "C" {
5982CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5983 if (!clang_isDeclaration(cursor.kind))
5984 return CXLinkage_Invalid;
5985
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005986 const Decl *D = cxcursor::getCursorDecl(cursor);
5987 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005988 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005989 case NoLinkage:
5990 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005991 case InternalLinkage: return CXLinkage_Internal;
5992 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5993 case ExternalLinkage: return CXLinkage_External;
5994 };
5995
5996 return CXLinkage_Invalid;
5997}
5998} // end: extern "C"
5999
6000//===----------------------------------------------------------------------===//
6001// Operations for querying language of a cursor.
6002//===----------------------------------------------------------------------===//
6003
6004static CXLanguageKind getDeclLanguage(const Decl *D) {
6005 if (!D)
6006 return CXLanguage_C;
6007
6008 switch (D->getKind()) {
6009 default:
6010 break;
6011 case Decl::ImplicitParam:
6012 case Decl::ObjCAtDefsField:
6013 case Decl::ObjCCategory:
6014 case Decl::ObjCCategoryImpl:
6015 case Decl::ObjCCompatibleAlias:
6016 case Decl::ObjCImplementation:
6017 case Decl::ObjCInterface:
6018 case Decl::ObjCIvar:
6019 case Decl::ObjCMethod:
6020 case Decl::ObjCProperty:
6021 case Decl::ObjCPropertyImpl:
6022 case Decl::ObjCProtocol:
6023 return CXLanguage_ObjC;
6024 case Decl::CXXConstructor:
6025 case Decl::CXXConversion:
6026 case Decl::CXXDestructor:
6027 case Decl::CXXMethod:
6028 case Decl::CXXRecord:
6029 case Decl::ClassTemplate:
6030 case Decl::ClassTemplatePartialSpecialization:
6031 case Decl::ClassTemplateSpecialization:
6032 case Decl::Friend:
6033 case Decl::FriendTemplate:
6034 case Decl::FunctionTemplate:
6035 case Decl::LinkageSpec:
6036 case Decl::Namespace:
6037 case Decl::NamespaceAlias:
6038 case Decl::NonTypeTemplateParm:
6039 case Decl::StaticAssert:
6040 case Decl::TemplateTemplateParm:
6041 case Decl::TemplateTypeParm:
6042 case Decl::UnresolvedUsingTypename:
6043 case Decl::UnresolvedUsingValue:
6044 case Decl::Using:
6045 case Decl::UsingDirective:
6046 case Decl::UsingShadow:
6047 return CXLanguage_CPlusPlus;
6048 }
6049
6050 return CXLanguage_C;
6051}
6052
6053extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006054
6055static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6056 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6057 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006058
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006059 switch (D->getAvailability()) {
6060 case AR_Available:
6061 case AR_NotYetIntroduced:
6062 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006063 return getCursorAvailabilityForDecl(
6064 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006065 return CXAvailability_Available;
6066
6067 case AR_Deprecated:
6068 return CXAvailability_Deprecated;
6069
6070 case AR_Unavailable:
6071 return CXAvailability_NotAvailable;
6072 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006073
6074 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006075}
6076
Guy Benyei11169dd2012-12-18 14:30:41 +00006077enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6078 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006079 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6080 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006081
6082 return CXAvailability_Available;
6083}
6084
6085static CXVersion convertVersion(VersionTuple In) {
6086 CXVersion Out = { -1, -1, -1 };
6087 if (In.empty())
6088 return Out;
6089
6090 Out.Major = In.getMajor();
6091
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006092 Optional<unsigned> Minor = In.getMinor();
6093 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 Out.Minor = *Minor;
6095 else
6096 return Out;
6097
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006098 Optional<unsigned> Subminor = In.getSubminor();
6099 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006100 Out.Subminor = *Subminor;
6101
6102 return Out;
6103}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104
6105static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6106 int *always_deprecated,
6107 CXString *deprecated_message,
6108 int *always_unavailable,
6109 CXString *unavailable_message,
6110 CXPlatformAvailability *availability,
6111 int availability_size) {
6112 bool HadAvailAttr = false;
6113 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006114 for (auto A : D->attrs()) {
6115 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006116 HadAvailAttr = true;
6117 if (always_deprecated)
6118 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006119 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006120 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006121 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006122 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006123 continue;
6124 }
6125
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006126 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006127 HadAvailAttr = true;
6128 if (always_unavailable)
6129 *always_unavailable = 1;
6130 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006131 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006132 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6133 }
6134 continue;
6135 }
6136
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006137 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006138 HadAvailAttr = true;
6139 if (N < availability_size) {
6140 availability[N].Platform
6141 = cxstring::createDup(Avail->getPlatform()->getName());
6142 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6143 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6144 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6145 availability[N].Unavailable = Avail->getUnavailable();
6146 availability[N].Message = cxstring::createDup(Avail->getMessage());
6147 }
6148 ++N;
6149 }
6150 }
6151
6152 if (!HadAvailAttr)
6153 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6154 return getCursorPlatformAvailabilityForDecl(
6155 cast<Decl>(EnumConst->getDeclContext()),
6156 always_deprecated,
6157 deprecated_message,
6158 always_unavailable,
6159 unavailable_message,
6160 availability,
6161 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006162
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006163 return N;
6164}
6165
Guy Benyei11169dd2012-12-18 14:30:41 +00006166int clang_getCursorPlatformAvailability(CXCursor cursor,
6167 int *always_deprecated,
6168 CXString *deprecated_message,
6169 int *always_unavailable,
6170 CXString *unavailable_message,
6171 CXPlatformAvailability *availability,
6172 int availability_size) {
6173 if (always_deprecated)
6174 *always_deprecated = 0;
6175 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006176 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006177 if (always_unavailable)
6178 *always_unavailable = 0;
6179 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006180 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006181
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 if (!clang_isDeclaration(cursor.kind))
6183 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006184
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006185 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006186 if (!D)
6187 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006188
6189 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6190 deprecated_message,
6191 always_unavailable,
6192 unavailable_message,
6193 availability,
6194 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006195}
6196
6197void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6198 clang_disposeString(availability->Platform);
6199 clang_disposeString(availability->Message);
6200}
6201
6202CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6203 if (clang_isDeclaration(cursor.kind))
6204 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6205
6206 return CXLanguage_Invalid;
6207}
6208
6209 /// \brief If the given cursor is the "templated" declaration
6210 /// descibing a class or function template, return the class or
6211 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006212static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006214 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6218 return FunTmpl;
6219
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006220 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6222 return ClassTmpl;
6223
6224 return D;
6225}
6226
6227CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6228 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006229 if (const Decl *D = getCursorDecl(cursor)) {
6230 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 if (!DC)
6232 return clang_getNullCursor();
6233
6234 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6235 getCursorTU(cursor));
6236 }
6237 }
6238
6239 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006240 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006241 return MakeCXCursor(D, getCursorTU(cursor));
6242 }
6243
6244 return clang_getNullCursor();
6245}
6246
6247CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6248 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006249 if (const Decl *D = getCursorDecl(cursor)) {
6250 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006251 if (!DC)
6252 return clang_getNullCursor();
6253
6254 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6255 getCursorTU(cursor));
6256 }
6257 }
6258
6259 // FIXME: Note that we can't easily compute the lexical context of a
6260 // statement or expression, so we return nothing.
6261 return clang_getNullCursor();
6262}
6263
6264CXFile clang_getIncludedFile(CXCursor cursor) {
6265 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006266 return nullptr;
6267
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006268 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006269 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006270}
6271
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006272unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6273 if (C.kind != CXCursor_ObjCPropertyDecl)
6274 return CXObjCPropertyAttr_noattr;
6275
6276 unsigned Result = CXObjCPropertyAttr_noattr;
6277 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6278 ObjCPropertyDecl::PropertyAttributeKind Attr =
6279 PD->getPropertyAttributesAsWritten();
6280
6281#define SET_CXOBJCPROP_ATTR(A) \
6282 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6283 Result |= CXObjCPropertyAttr_##A
6284 SET_CXOBJCPROP_ATTR(readonly);
6285 SET_CXOBJCPROP_ATTR(getter);
6286 SET_CXOBJCPROP_ATTR(assign);
6287 SET_CXOBJCPROP_ATTR(readwrite);
6288 SET_CXOBJCPROP_ATTR(retain);
6289 SET_CXOBJCPROP_ATTR(copy);
6290 SET_CXOBJCPROP_ATTR(nonatomic);
6291 SET_CXOBJCPROP_ATTR(setter);
6292 SET_CXOBJCPROP_ATTR(atomic);
6293 SET_CXOBJCPROP_ATTR(weak);
6294 SET_CXOBJCPROP_ATTR(strong);
6295 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6296#undef SET_CXOBJCPROP_ATTR
6297
6298 return Result;
6299}
6300
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006301unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6302 if (!clang_isDeclaration(C.kind))
6303 return CXObjCDeclQualifier_None;
6304
6305 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6306 const Decl *D = getCursorDecl(C);
6307 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6308 QT = MD->getObjCDeclQualifier();
6309 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6310 QT = PD->getObjCDeclQualifier();
6311 if (QT == Decl::OBJC_TQ_None)
6312 return CXObjCDeclQualifier_None;
6313
6314 unsigned Result = CXObjCDeclQualifier_None;
6315 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6316 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6317 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6318 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6319 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6320 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6321
6322 return Result;
6323}
6324
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006325unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6326 if (!clang_isDeclaration(C.kind))
6327 return 0;
6328
6329 const Decl *D = getCursorDecl(C);
6330 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6331 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6332 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6333 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6334
6335 return 0;
6336}
6337
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006338unsigned clang_Cursor_isVariadic(CXCursor C) {
6339 if (!clang_isDeclaration(C.kind))
6340 return 0;
6341
6342 const Decl *D = getCursorDecl(C);
6343 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6344 return FD->isVariadic();
6345 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6346 return MD->isVariadic();
6347
6348 return 0;
6349}
6350
Guy Benyei11169dd2012-12-18 14:30:41 +00006351CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6352 if (!clang_isDeclaration(C.kind))
6353 return clang_getNullRange();
6354
6355 const Decl *D = getCursorDecl(C);
6356 ASTContext &Context = getCursorContext(C);
6357 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6358 if (!RC)
6359 return clang_getNullRange();
6360
6361 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6362}
6363
6364CXString clang_Cursor_getRawCommentText(CXCursor C) {
6365 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006366 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006367
6368 const Decl *D = getCursorDecl(C);
6369 ASTContext &Context = getCursorContext(C);
6370 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6371 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6372 StringRef();
6373
6374 // Don't duplicate the string because RawText points directly into source
6375 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006376 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006377}
6378
6379CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6380 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006381 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382
6383 const Decl *D = getCursorDecl(C);
6384 const ASTContext &Context = getCursorContext(C);
6385 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6386
6387 if (RC) {
6388 StringRef BriefText = RC->getBriefText(Context);
6389
6390 // Don't duplicate the string because RawComment ensures that this memory
6391 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006392 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 }
6394
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006395 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006396}
6397
Guy Benyei11169dd2012-12-18 14:30:41 +00006398CXModule clang_Cursor_getModule(CXCursor C) {
6399 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006400 if (const ImportDecl *ImportD =
6401 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006402 return ImportD->getImportedModule();
6403 }
6404
Craig Topper69186e72014-06-08 08:38:04 +00006405 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006406}
6407
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006408CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6409 if (isNotUsableTU(TU)) {
6410 LOG_BAD_TU(TU);
6411 return nullptr;
6412 }
6413 if (!File)
6414 return nullptr;
6415 FileEntry *FE = static_cast<FileEntry *>(File);
6416
6417 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6418 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6419 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6420
6421 if (Module *Mod = Header.getModule()) {
6422 if (Header.getRole() != ModuleMap::ExcludedHeader)
6423 return Mod;
6424 }
6425 return nullptr;
6426}
6427
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006428CXFile clang_Module_getASTFile(CXModule CXMod) {
6429 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006430 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006431 Module *Mod = static_cast<Module*>(CXMod);
6432 return const_cast<FileEntry *>(Mod->getASTFile());
6433}
6434
Guy Benyei11169dd2012-12-18 14:30:41 +00006435CXModule clang_Module_getParent(CXModule CXMod) {
6436 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006437 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 Module *Mod = static_cast<Module*>(CXMod);
6439 return Mod->Parent;
6440}
6441
6442CXString clang_Module_getName(CXModule CXMod) {
6443 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006444 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006445 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006446 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006447}
6448
6449CXString clang_Module_getFullName(CXModule CXMod) {
6450 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006453 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006454}
6455
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006456int clang_Module_isSystem(CXModule CXMod) {
6457 if (!CXMod)
6458 return 0;
6459 Module *Mod = static_cast<Module*>(CXMod);
6460 return Mod->IsSystem;
6461}
6462
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006463unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6464 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006465 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006466 LOG_BAD_TU(TU);
6467 return 0;
6468 }
6469 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 return 0;
6471 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006472 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6473 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6474 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006475}
6476
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006477CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6478 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006479 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006480 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006481 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006482 }
6483 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006484 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006486 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006487
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006488 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6489 if (Index < TopHeaders.size())
6490 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006491
Craig Topper69186e72014-06-08 08:38:04 +00006492 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006493}
6494
6495} // end: extern "C"
6496
6497//===----------------------------------------------------------------------===//
6498// C++ AST instrospection.
6499//===----------------------------------------------------------------------===//
6500
6501extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006502unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6503 if (!clang_isDeclaration(C.kind))
6504 return 0;
6505
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006506 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006507 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006508 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006509 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6510}
6511
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006512unsigned clang_CXXMethod_isConst(CXCursor C) {
6513 if (!clang_isDeclaration(C.kind))
6514 return 0;
6515
6516 const Decl *D = cxcursor::getCursorDecl(C);
6517 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006518 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006519 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6520}
6521
Guy Benyei11169dd2012-12-18 14:30:41 +00006522unsigned clang_CXXMethod_isStatic(CXCursor C) {
6523 if (!clang_isDeclaration(C.kind))
6524 return 0;
6525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006526 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006527 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006528 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 return (Method && Method->isStatic()) ? 1 : 0;
6530}
6531
6532unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6533 if (!clang_isDeclaration(C.kind))
6534 return 0;
6535
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006536 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006537 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006538 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006539 return (Method && Method->isVirtual()) ? 1 : 0;
6540}
6541} // end: extern "C"
6542
6543//===----------------------------------------------------------------------===//
6544// Attribute introspection.
6545//===----------------------------------------------------------------------===//
6546
6547extern "C" {
6548CXType clang_getIBOutletCollectionType(CXCursor C) {
6549 if (C.kind != CXCursor_IBOutletCollectionAttr)
6550 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6551
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006552 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006553 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6554
6555 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6556}
6557} // end: extern "C"
6558
6559//===----------------------------------------------------------------------===//
6560// Inspecting memory usage.
6561//===----------------------------------------------------------------------===//
6562
6563typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6564
6565static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6566 enum CXTUResourceUsageKind k,
6567 unsigned long amount) {
6568 CXTUResourceUsageEntry entry = { k, amount };
6569 entries.push_back(entry);
6570}
6571
6572extern "C" {
6573
6574const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6575 const char *str = "";
6576 switch (kind) {
6577 case CXTUResourceUsage_AST:
6578 str = "ASTContext: expressions, declarations, and types";
6579 break;
6580 case CXTUResourceUsage_Identifiers:
6581 str = "ASTContext: identifiers";
6582 break;
6583 case CXTUResourceUsage_Selectors:
6584 str = "ASTContext: selectors";
6585 break;
6586 case CXTUResourceUsage_GlobalCompletionResults:
6587 str = "Code completion: cached global results";
6588 break;
6589 case CXTUResourceUsage_SourceManagerContentCache:
6590 str = "SourceManager: content cache allocator";
6591 break;
6592 case CXTUResourceUsage_AST_SideTables:
6593 str = "ASTContext: side tables";
6594 break;
6595 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6596 str = "SourceManager: malloc'ed memory buffers";
6597 break;
6598 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6599 str = "SourceManager: mmap'ed memory buffers";
6600 break;
6601 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6602 str = "ExternalASTSource: malloc'ed memory buffers";
6603 break;
6604 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6605 str = "ExternalASTSource: mmap'ed memory buffers";
6606 break;
6607 case CXTUResourceUsage_Preprocessor:
6608 str = "Preprocessor: malloc'ed memory";
6609 break;
6610 case CXTUResourceUsage_PreprocessingRecord:
6611 str = "Preprocessor: PreprocessingRecord";
6612 break;
6613 case CXTUResourceUsage_SourceManager_DataStructures:
6614 str = "SourceManager: data structures and tables";
6615 break;
6616 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6617 str = "Preprocessor: header search tables";
6618 break;
6619 }
6620 return str;
6621}
6622
6623CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006624 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006625 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006626 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 return usage;
6628 }
6629
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006630 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006631 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006632 ASTContext &astContext = astUnit->getASTContext();
6633
6634 // How much memory is used by AST nodes and types?
6635 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6636 (unsigned long) astContext.getASTAllocatedMemory());
6637
6638 // How much memory is used by identifiers?
6639 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6640 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6641
6642 // How much memory is used for selectors?
6643 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6644 (unsigned long) astContext.Selectors.getTotalMemory());
6645
6646 // How much memory is used by ASTContext's side tables?
6647 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6648 (unsigned long) astContext.getSideTableAllocatedMemory());
6649
6650 // How much memory is used for caching global code completion results?
6651 unsigned long completionBytes = 0;
6652 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006653 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006654 completionBytes = completionAllocator->getTotalMemory();
6655 }
6656 createCXTUResourceUsageEntry(*entries,
6657 CXTUResourceUsage_GlobalCompletionResults,
6658 completionBytes);
6659
6660 // How much memory is being used by SourceManager's content cache?
6661 createCXTUResourceUsageEntry(*entries,
6662 CXTUResourceUsage_SourceManagerContentCache,
6663 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6664
6665 // How much memory is being used by the MemoryBuffer's in SourceManager?
6666 const SourceManager::MemoryBufferSizes &srcBufs =
6667 astUnit->getSourceManager().getMemoryBufferSizes();
6668
6669 createCXTUResourceUsageEntry(*entries,
6670 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6671 (unsigned long) srcBufs.malloc_bytes);
6672 createCXTUResourceUsageEntry(*entries,
6673 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6674 (unsigned long) srcBufs.mmap_bytes);
6675 createCXTUResourceUsageEntry(*entries,
6676 CXTUResourceUsage_SourceManager_DataStructures,
6677 (unsigned long) astContext.getSourceManager()
6678 .getDataStructureSizes());
6679
6680 // How much memory is being used by the ExternalASTSource?
6681 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6682 const ExternalASTSource::MemoryBufferSizes &sizes =
6683 esrc->getMemoryBufferSizes();
6684
6685 createCXTUResourceUsageEntry(*entries,
6686 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6687 (unsigned long) sizes.malloc_bytes);
6688 createCXTUResourceUsageEntry(*entries,
6689 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6690 (unsigned long) sizes.mmap_bytes);
6691 }
6692
6693 // How much memory is being used by the Preprocessor?
6694 Preprocessor &pp = astUnit->getPreprocessor();
6695 createCXTUResourceUsageEntry(*entries,
6696 CXTUResourceUsage_Preprocessor,
6697 pp.getTotalMemory());
6698
6699 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6700 createCXTUResourceUsageEntry(*entries,
6701 CXTUResourceUsage_PreprocessingRecord,
6702 pRec->getTotalMemory());
6703 }
6704
6705 createCXTUResourceUsageEntry(*entries,
6706 CXTUResourceUsage_Preprocessor_HeaderSearch,
6707 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006708
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 CXTUResourceUsage usage = { (void*) entries.get(),
6710 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006711 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006712 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006713 return usage;
6714}
6715
6716void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6717 if (usage.data)
6718 delete (MemUsageEntries*) usage.data;
6719}
6720
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006721CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6722 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006723 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006724 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006725
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006726 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006727 LOG_BAD_TU(TU);
6728 return skipped;
6729 }
6730
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006731 if (!file)
6732 return skipped;
6733
6734 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6735 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6736 if (!ppRec)
6737 return skipped;
6738
6739 ASTContext &Ctx = astUnit->getASTContext();
6740 SourceManager &sm = Ctx.getSourceManager();
6741 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6742 FileID wantedFileID = sm.translateFile(fileEntry);
6743
6744 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6745 std::vector<SourceRange> wantedRanges;
6746 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6747 i != ei; ++i) {
6748 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6749 wantedRanges.push_back(*i);
6750 }
6751
6752 skipped->count = wantedRanges.size();
6753 skipped->ranges = new CXSourceRange[skipped->count];
6754 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6755 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6756
6757 return skipped;
6758}
6759
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006760void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6761 if (ranges) {
6762 delete[] ranges->ranges;
6763 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006764 }
6765}
6766
Guy Benyei11169dd2012-12-18 14:30:41 +00006767} // end extern "C"
6768
6769void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6770 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6771 for (unsigned I = 0; I != Usage.numEntries; ++I)
6772 fprintf(stderr, " %s: %lu\n",
6773 clang_getTUResourceUsageName(Usage.entries[I].kind),
6774 Usage.entries[I].amount);
6775
6776 clang_disposeCXTUResourceUsage(Usage);
6777}
6778
6779//===----------------------------------------------------------------------===//
6780// Misc. utility functions.
6781//===----------------------------------------------------------------------===//
6782
6783/// Default to using an 8 MB stack size on "safety" threads.
6784static unsigned SafetyStackThreadSize = 8 << 20;
6785
6786namespace clang {
6787
6788bool RunSafely(llvm::CrashRecoveryContext &CRC,
6789 void (*Fn)(void*), void *UserData,
6790 unsigned Size) {
6791 if (!Size)
6792 Size = GetSafetyThreadStackSize();
6793 if (Size)
6794 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6795 return CRC.RunSafely(Fn, UserData);
6796}
6797
6798unsigned GetSafetyThreadStackSize() {
6799 return SafetyStackThreadSize;
6800}
6801
6802void SetSafetyThreadStackSize(unsigned Value) {
6803 SafetyStackThreadSize = Value;
6804}
6805
6806}
6807
6808void clang::setThreadBackgroundPriority() {
6809 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6810 return;
6811
Alp Toker1a86ad22014-07-06 06:24:00 +00006812#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6814#endif
6815}
6816
6817void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6818 if (!Unit)
6819 return;
6820
6821 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6822 DEnd = Unit->stored_diag_end();
6823 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006824 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006825 CXString Msg = clang_formatDiagnostic(&Diag,
6826 clang_defaultDiagnosticDisplayOptions());
6827 fprintf(stderr, "%s\n", clang_getCString(Msg));
6828 clang_disposeString(Msg);
6829 }
6830#ifdef LLVM_ON_WIN32
6831 // On Windows, force a flush, since there may be multiple copies of
6832 // stderr and stdout in the file system, all with different buffers
6833 // but writing to the same device.
6834 fflush(stderr);
6835#endif
6836}
6837
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006838MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6839 SourceLocation MacroDefLoc,
6840 CXTranslationUnit TU){
6841 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006842 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006843 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006844 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006845
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006846 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006847 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006848 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006849 if (MD) {
6850 for (MacroDirective::DefInfo
6851 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6852 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6853 return Def.getMacroInfo();
6854 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006855 }
6856
Craig Topper69186e72014-06-08 08:38:04 +00006857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858}
6859
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006860const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6861 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006862 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006863 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006864 const IdentifierInfo *II = MacroDef->getName();
6865 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006866 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006867
6868 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6869}
6870
6871MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6872 const Token &Tok,
6873 CXTranslationUnit TU) {
6874 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006875 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006876 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006877 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006878
6879 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006881 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6882 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006883 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884
6885 // Check that the token is inside the definition and not its argument list.
6886 SourceManager &SM = Unit->getSourceManager();
6887 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006888 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006889 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006890 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006891
6892 Preprocessor &PP = Unit->getPreprocessor();
6893 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6894 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006895 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006896
Alp Toker2d57cea2014-05-17 04:53:25 +00006897 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006898 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006899 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006900
6901 // Check that the identifier is not one of the macro arguments.
6902 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006903 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006904
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006905 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6906 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006908
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006909 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006910}
6911
6912MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6913 SourceLocation Loc,
6914 CXTranslationUnit TU) {
6915 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006916 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006917
6918 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006919 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006920 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006921 Preprocessor &PP = Unit->getPreprocessor();
6922 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006923 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006924 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6925 Token Tok;
6926 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006927 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006928
6929 return checkForMacroInMacroDefinition(MI, Tok, TU);
6930}
6931
Guy Benyei11169dd2012-12-18 14:30:41 +00006932extern "C" {
6933
6934CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006935 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006936}
6937
6938} // end: extern "C"
6939
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006940Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6941 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006942 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006943 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006944 if (Unit->isMainFileAST())
6945 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006946 return *this;
6947 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006948 } else {
6949 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006950 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006951 return *this;
6952}
6953
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006954Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6955 *this << FE->getName();
6956 return *this;
6957}
6958
6959Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6960 CXString cursorName = clang_getCursorDisplayName(cursor);
6961 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6962 clang_disposeString(cursorName);
6963 return *this;
6964}
6965
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006966Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6967 CXFile File;
6968 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006969 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006970 CXString FileName = clang_getFileName(File);
6971 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6972 clang_disposeString(FileName);
6973 return *this;
6974}
6975
6976Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6977 CXSourceLocation BLoc = clang_getRangeStart(range);
6978 CXSourceLocation ELoc = clang_getRangeEnd(range);
6979
6980 CXFile BFile;
6981 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006982 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006983
6984 CXFile EFile;
6985 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006986 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006987
6988 CXString BFileName = clang_getFileName(BFile);
6989 if (BFile == EFile) {
6990 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6991 BLine, BColumn, ELine, EColumn);
6992 } else {
6993 CXString EFileName = clang_getFileName(EFile);
6994 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6995 BLine, BColumn)
6996 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6997 ELine, EColumn);
6998 clang_disposeString(EFileName);
6999 }
7000 clang_disposeString(BFileName);
7001 return *this;
7002}
7003
7004Logger &cxindex::Logger::operator<<(CXString Str) {
7005 *this << clang_getCString(Str);
7006 return *this;
7007}
7008
7009Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7010 LogOS << Fmt;
7011 return *this;
7012}
7013
Chandler Carruth37ad2582014-06-27 15:14:39 +00007014static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7015
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007016cxindex::Logger::~Logger() {
7017 LogOS.flush();
7018
Chandler Carruth37ad2582014-06-27 15:14:39 +00007019 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007020
7021 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7022
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007023 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007024 OS << "[libclang:" << Name << ':';
7025
Alp Toker1a86ad22014-07-06 06:24:00 +00007026#ifdef USE_DARWIN_THREADS
7027 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007028 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7029 OS << tid << ':';
7030#endif
7031
7032 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7033 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7034 OS << Msg.str() << '\n';
7035
7036 if (Trace) {
7037 llvm::sys::PrintStackTrace(stderr);
7038 OS << "--------------------------------------------------\n";
7039 }
7040}