blob: f008cfcd56858d9fe3811f76a1b1c12170733556 [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863
Guy Benyei11169dd2012-12-18 14:30:41 +00001864private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1867 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1869 void AddStmt(const Stmt *S);
1870 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001871 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001873 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001874};
1875} // end anonyous namespace
1876
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 // 'S' should always be non-null, since it comes from the
1879 // statement we are visiting.
1880 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1881}
1882
1883void
1884EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1885 if (Qualifier)
1886 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1887}
1888
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 if (S)
1891 WL.push_back(StmtVisit(S, Parent));
1892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(DeclVisit(D, Parent, isFirst));
1896}
1897void EnqueueVisitor::
1898 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1899 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001901}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (D)
1904 WL.push_back(MemberRefVisit(D, L, Parent));
1905}
1906void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1907 if (TI)
1908 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1909 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 AddStmt(*Child);
1914 }
1915 if (size == WL.size())
1916 return;
1917 // Now reverse the entries we just added. This will match the DFS
1918 // ordering performed by the worklist.
1919 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1920 std::reverse(I, E);
1921}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001922namespace {
1923class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1924 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001925 /// \brief Process clauses with list of variables.
1926 template <typename T>
1927 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001928public:
1929 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1930#define OPENMP_CLAUSE(Name, Class) \
1931 void Visit##Class(const Class *C);
1932#include "clang/Basic/OpenMPKinds.def"
1933};
1934
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001935void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1936 Visitor->AddStmt(C->getCondition());
1937}
1938
Alexey Bataev568a8332014-03-06 06:15:19 +00001939void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1940 Visitor->AddStmt(C->getNumThreads());
1941}
1942
Alexey Bataev62c87d22014-03-21 04:51:18 +00001943void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1944 Visitor->AddStmt(C->getSafelen());
1945}
1946
Alexander Musman8bd31e62014-05-27 15:12:19 +00001947void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1948 Visitor->AddStmt(C->getNumForLoops());
1949}
1950
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001952
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001953void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1954
Alexey Bataev56dafe82014-06-20 07:16:17 +00001955void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1956 Visitor->AddStmt(C->getChunkSize());
1957}
1958
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001959void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1960
Alexey Bataev236070f2014-06-20 11:19:47 +00001961void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1962
Alexey Bataev756c1962013-09-24 03:17:45 +00001963template<typename T>
1964void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001965 for (const auto *I : Node->varlists())
1966 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001967}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968
1969void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001970 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001971}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001972void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1973 const OMPFirstprivateClause *C) {
1974 VisitOMPClauseList(C);
1975}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001976void OMPClauseEnqueue::VisitOMPLastprivateClause(
1977 const OMPLastprivateClause *C) {
1978 VisitOMPClauseList(C);
1979}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001980void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001981 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001982}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001983void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1984 VisitOMPClauseList(C);
1985}
Alexander Musman8dba6642014-04-22 13:09:42 +00001986void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1987 VisitOMPClauseList(C);
1988 Visitor->AddStmt(C->getStep());
1989}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001990void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1991 VisitOMPClauseList(C);
1992 Visitor->AddStmt(C->getAlignment());
1993}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001994void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1995 VisitOMPClauseList(C);
1996}
Alexey Bataevbae9a792014-06-27 10:37:06 +00001997void
1998OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
1999 VisitOMPClauseList(C);
2000}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002001}
Alexey Bataev756c1962013-09-24 03:17:45 +00002002
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2004 unsigned size = WL.size();
2005 OMPClauseEnqueue Visitor(this);
2006 Visitor.Visit(S);
2007 if (size == WL.size())
2008 return;
2009 // Now reverse the entries we just added. This will match the DFS
2010 // ordering performed by the worklist.
2011 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2012 std::reverse(I, E);
2013}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002015 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2016}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002017void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002018 AddDecl(B->getBlockDecl());
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 EnqueueChildren(E);
2022 AddTypeLoc(E->getTypeSourceInfo());
2023}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002024void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2025 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002026 E = S->body_rend(); I != E; ++I) {
2027 AddStmt(*I);
2028 }
2029}
2030void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002031VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002032 AddStmt(S->getSubStmt());
2033 AddDeclarationNameInfo(S);
2034 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2035 AddNestedNameSpecifierLoc(QualifierLoc);
2036}
2037
2038void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2041 AddDeclarationNameInfo(E);
2042 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2043 AddNestedNameSpecifierLoc(QualifierLoc);
2044 if (!E->isImplicitAccess())
2045 AddStmt(E->getBase());
2046}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 // Enqueue the initializer , if any.
2049 AddStmt(E->getInitializer());
2050 // Enqueue the array size, if any.
2051 AddStmt(E->getArraySize());
2052 // Enqueue the allocated type.
2053 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2054 // Enqueue the placement arguments.
2055 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2056 AddStmt(E->getPlacementArg(I-1));
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2060 AddStmt(CE->getArg(I-1));
2061 AddStmt(CE->getCallee());
2062 AddStmt(CE->getArg(0));
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2065 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 // Visit the name of the type being destroyed.
2067 AddTypeLoc(E->getDestroyedTypeInfo());
2068 // Visit the scope type that looks disturbingly like the nested-name-specifier
2069 // but isn't.
2070 AddTypeLoc(E->getScopeTypeInfo());
2071 // Visit the nested-name-specifier.
2072 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2073 AddNestedNameSpecifierLoc(QualifierLoc);
2074 // Visit base expression.
2075 AddStmt(E->getBase());
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2078 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 AddTypeLoc(E->getTypeSourceInfo());
2080}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2082 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 EnqueueChildren(E);
2084 AddTypeLoc(E->getTypeSourceInfo());
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 EnqueueChildren(E);
2088 if (E->isTypeOperand())
2089 AddTypeLoc(E->getTypeOperandSourceInfo());
2090}
2091
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2093 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 EnqueueChildren(E);
2095 AddTypeLoc(E->getTypeSourceInfo());
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 EnqueueChildren(E);
2099 if (E->isTypeOperand())
2100 AddTypeLoc(E->getTypeOperandSourceInfo());
2101}
2102
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 EnqueueChildren(S);
2105 AddDecl(S->getExceptionDecl());
2106}
2107
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 if (DR->hasExplicitTemplateArgs()) {
2110 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2111 }
2112 WL.push_back(DeclRefExprParts(DR, Parent));
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2115 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2117 AddDeclarationNameInfo(E);
2118 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 unsigned size = WL.size();
2122 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002123 for (const auto *D : S->decls()) {
2124 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 isFirst = false;
2126 }
2127 if (size == WL.size())
2128 return;
2129 // Now reverse the entries we just added. This will match the DFS
2130 // ordering performed by the worklist.
2131 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2132 std::reverse(I, E);
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 D = E->designators_rbegin(), DEnd = E->designators_rend();
2138 D != DEnd; ++D) {
2139 if (D->isFieldDesignator()) {
2140 if (FieldDecl *Field = D->getField())
2141 AddMemberRef(Field, D->getFieldLoc());
2142 continue;
2143 }
2144 if (D->isArrayDesignator()) {
2145 AddStmt(E->getArrayIndex(*D));
2146 continue;
2147 }
2148 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2149 AddStmt(E->getArrayRangeEnd(*D));
2150 AddStmt(E->getArrayRangeStart(*D));
2151 }
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 EnqueueChildren(E);
2155 AddTypeLoc(E->getTypeInfoAsWritten());
2156}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 AddStmt(FS->getBody());
2159 AddStmt(FS->getInc());
2160 AddStmt(FS->getCond());
2161 AddDecl(FS->getConditionVariable());
2162 AddStmt(FS->getInit());
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 AddStmt(If->getElse());
2169 AddStmt(If->getThen());
2170 AddStmt(If->getCond());
2171 AddDecl(If->getConditionVariable());
2172}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 // We care about the syntactic form of the initializer list, only.
2175 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2176 IE = Syntactic;
2177 EnqueueChildren(IE);
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 WL.push_back(MemberExprParts(M, Parent));
2181
2182 // If the base of the member access expression is an implicit 'this', don't
2183 // visit it.
2184 // FIXME: If we ever want to show these implicit accesses, this will be
2185 // unfortunate. However, clang_getCursor() relies on this behavior.
2186 if (!M->isImplicitAccess())
2187 AddStmt(M->getBase());
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddTypeLoc(E->getEncodedTypeSourceInfo());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 EnqueueChildren(M);
2194 AddTypeLoc(M->getClassReceiverTypeInfo());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 // Visit the components of the offsetof expression.
2198 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2199 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2200 const OffsetOfNode &Node = E->getComponent(I-1);
2201 switch (Node.getKind()) {
2202 case OffsetOfNode::Array:
2203 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2204 break;
2205 case OffsetOfNode::Field:
2206 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2207 break;
2208 case OffsetOfNode::Identifier:
2209 case OffsetOfNode::Base:
2210 continue;
2211 }
2212 }
2213 // Visit the type into which we're computing the offset.
2214 AddTypeLoc(E->getTypeSourceInfo());
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2218 WL.push_back(OverloadExprParts(E, Parent));
2219}
2220void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 EnqueueChildren(E);
2223 if (E->isArgumentType())
2224 AddTypeLoc(E->getArgumentTypeInfo());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 EnqueueChildren(S);
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 AddStmt(S->getBody());
2231 AddStmt(S->getCond());
2232 AddDecl(S->getConditionVariable());
2233}
2234
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddStmt(W->getBody());
2237 AddStmt(W->getCond());
2238 AddDecl(W->getConditionVariable());
2239}
2240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 for (unsigned I = E->getNumArgs(); I > 0; --I)
2243 AddTypeLoc(E->getArg(I-1));
2244}
2245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 AddTypeLoc(E->getQueriedTypeSourceInfo());
2248}
2249
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueChildren(E);
2252}
2253
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 VisitOverloadExpr(U);
2256 if (!U->isImplicitAccess())
2257 AddStmt(U->getBase());
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 AddStmt(E->getSubExpr());
2261 AddTypeLoc(E->getWrittenTypeInfo());
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 WL.push_back(SizeOfPackExprParts(E, Parent));
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 // If the opaque value has a source expression, just transparently
2268 // visit that. This is useful for (e.g.) pseudo-object expressions.
2269 if (Expr *SourceExpr = E->getSourceExpr())
2270 return Visit(SourceExpr);
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddStmt(E->getBody());
2274 WL.push_back(LambdaExprParts(E, Parent));
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 // Treat the expression like its syntactic form.
2278 Visit(E->getSyntacticForm());
2279}
2280
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002281void EnqueueVisitor::VisitOMPExecutableDirective(
2282 const OMPExecutableDirective *D) {
2283 EnqueueChildren(D);
2284 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2285 E = D->clauses().end();
2286 I != E; ++I)
2287 EnqueueChildren(*I);
2288}
2289
2290void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2291 VisitOMPExecutableDirective(D);
2292}
2293
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002294void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2295 VisitOMPExecutableDirective(D);
2296}
2297
Alexey Bataevf29276e2014-06-18 04:14:57 +00002298void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2299 VisitOMPExecutableDirective(D);
2300}
2301
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002302void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2303 VisitOMPExecutableDirective(D);
2304}
2305
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002306void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2307 VisitOMPExecutableDirective(D);
2308}
2309
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002310void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2311 VisitOMPExecutableDirective(D);
2312}
2313
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2316}
2317
2318bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2319 if (RegionOfInterest.isValid()) {
2320 SourceRange Range = getRawCursorExtent(C);
2321 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2322 return false;
2323 }
2324 return true;
2325}
2326
2327bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2328 while (!WL.empty()) {
2329 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002330 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002331
2332 // Set the Parent field, then back to its old value once we're done.
2333 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2334
2335 switch (LI.getKind()) {
2336 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 if (!D)
2339 continue;
2340
2341 // For now, perform default visitation for Decls.
2342 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2343 cast<DeclVisit>(&LI)->isFirst())))
2344 return true;
2345
2346 continue;
2347 }
2348 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2349 const ASTTemplateArgumentListInfo *ArgList =
2350 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2351 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2352 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2353 Arg != ArgEnd; ++Arg) {
2354 if (VisitTemplateArgumentLoc(*Arg))
2355 return true;
2356 }
2357 continue;
2358 }
2359 case VisitorJob::TypeLocVisitKind: {
2360 // Perform default visitation for TypeLocs.
2361 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2362 return true;
2363 continue;
2364 }
2365 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002366 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002367 if (LabelStmt *stmt = LS->getStmt()) {
2368 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2369 TU))) {
2370 return true;
2371 }
2372 }
2373 continue;
2374 }
2375
2376 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2377 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2378 if (VisitNestedNameSpecifierLoc(V->get()))
2379 return true;
2380 continue;
2381 }
2382
2383 case VisitorJob::DeclarationNameInfoVisitKind: {
2384 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2385 ->get()))
2386 return true;
2387 continue;
2388 }
2389 case VisitorJob::MemberRefVisitKind: {
2390 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2391 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2392 return true;
2393 continue;
2394 }
2395 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 if (!S)
2398 continue;
2399
2400 // Update the current cursor.
2401 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2402 if (!IsInRegionOfInterest(Cursor))
2403 continue;
2404 switch (Visitor(Cursor, Parent, ClientData)) {
2405 case CXChildVisit_Break: return true;
2406 case CXChildVisit_Continue: break;
2407 case CXChildVisit_Recurse:
2408 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002409 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 EnqueueWorkList(WL, S);
2411 break;
2412 }
2413 continue;
2414 }
2415 case VisitorJob::MemberExprPartsKind: {
2416 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002418
2419 // Visit the nested-name-specifier
2420 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2421 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2422 return true;
2423
2424 // Visit the declaration name.
2425 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2426 return true;
2427
2428 // Visit the explicitly-specified template arguments, if any.
2429 if (M->hasExplicitTemplateArgs()) {
2430 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2431 *ArgEnd = Arg + M->getNumTemplateArgs();
2432 Arg != ArgEnd; ++Arg) {
2433 if (VisitTemplateArgumentLoc(*Arg))
2434 return true;
2435 }
2436 }
2437 continue;
2438 }
2439 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 // Visit nested-name-specifier, if present.
2442 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2443 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2444 return true;
2445 // Visit declaration name.
2446 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2447 return true;
2448 continue;
2449 }
2450 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 // Visit the nested-name-specifier.
2453 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2454 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2455 return true;
2456 // Visit the declaration name.
2457 if (VisitDeclarationNameInfo(O->getNameInfo()))
2458 return true;
2459 // Visit the overloaded declaration reference.
2460 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2461 return true;
2462 continue;
2463 }
2464 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 NamedDecl *Pack = E->getPack();
2467 if (isa<TemplateTypeParmDecl>(Pack)) {
2468 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2469 E->getPackLoc(), TU)))
2470 return true;
2471
2472 continue;
2473 }
2474
2475 if (isa<TemplateTemplateParmDecl>(Pack)) {
2476 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2477 E->getPackLoc(), TU)))
2478 return true;
2479
2480 continue;
2481 }
2482
2483 // Non-type template parameter packs and function parameter packs are
2484 // treated like DeclRefExpr cursors.
2485 continue;
2486 }
2487
2488 case VisitorJob::LambdaExprPartsKind: {
2489 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2492 CEnd = E->explicit_capture_end();
2493 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002494 // FIXME: Lambda init-captures.
2495 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002497
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2499 C->getLocation(),
2500 TU)))
2501 return true;
2502 }
2503
2504 // Visit parameters and return type, if present.
2505 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2506 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2507 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2508 // Visit the whole type.
2509 if (Visit(TL))
2510 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002511 } else if (FunctionProtoTypeLoc Proto =
2512 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002513 if (E->hasExplicitParameters()) {
2514 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002515 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2516 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002517 return true;
2518 } else {
2519 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002520 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 return true;
2522 }
2523 }
2524 }
2525 break;
2526 }
2527
2528 case VisitorJob::PostChildrenVisitKind:
2529 if (PostChildrenVisitor(Parent, ClientData))
2530 return true;
2531 break;
2532 }
2533 }
2534 return false;
2535}
2536
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002537bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002538 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002539 if (!WorkListFreeList.empty()) {
2540 WL = WorkListFreeList.back();
2541 WL->clear();
2542 WorkListFreeList.pop_back();
2543 }
2544 else {
2545 WL = new VisitorWorkList();
2546 WorkListCache.push_back(WL);
2547 }
2548 EnqueueWorkList(*WL, S);
2549 bool result = RunVisitorWorkList(*WL);
2550 WorkListFreeList.push_back(WL);
2551 return result;
2552}
2553
2554namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002555typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002556RefNamePieces
2557buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2558 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2559 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2561 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2562 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2563
2564 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2565
2566 RefNamePieces Pieces;
2567
2568 if (WantQualifier && QLoc.isValid())
2569 Pieces.push_back(QLoc);
2570
2571 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2572 Pieces.push_back(NI.getLoc());
2573
2574 if (WantTemplateArgs && TemplateArgs)
2575 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2576 TemplateArgs->RAngleLoc));
2577
2578 if (Kind == DeclarationName::CXXOperatorName) {
2579 Pieces.push_back(SourceLocation::getFromRawEncoding(
2580 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2581 Pieces.push_back(SourceLocation::getFromRawEncoding(
2582 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2583 }
2584
2585 if (WantSinglePiece) {
2586 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2587 Pieces.clear();
2588 Pieces.push_back(R);
2589 }
2590
2591 return Pieces;
2592}
2593}
2594
2595//===----------------------------------------------------------------------===//
2596// Misc. API hooks.
2597//===----------------------------------------------------------------------===//
2598
Chad Rosier05c71aa2013-03-27 18:28:23 +00002599static void fatal_error_handler(void *user_data, const std::string& reason,
2600 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 // Write the result out to stderr avoiding errs() because raw_ostreams can
2602 // call report_fatal_error.
2603 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2604 ::abort();
2605}
2606
Chandler Carruth66660742014-06-27 16:37:27 +00002607namespace {
2608struct RegisterFatalErrorHandler {
2609 RegisterFatalErrorHandler() {
2610 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2611 }
2612};
2613}
2614
2615static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2616
Guy Benyei11169dd2012-12-18 14:30:41 +00002617extern "C" {
2618CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2619 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002620 // We use crash recovery to make some of our APIs more reliable, implicitly
2621 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002622 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2623 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002624
Chandler Carruth66660742014-06-27 16:37:27 +00002625 // Look through the managed static to trigger construction of the managed
2626 // static which registers our fatal error handler. This ensures it is only
2627 // registered once.
2628 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002629
2630 CIndexer *CIdxr = new CIndexer();
2631 if (excludeDeclarationsFromPCH)
2632 CIdxr->setOnlyLocalDecls();
2633 if (displayDiagnostics)
2634 CIdxr->setDisplayDiagnostics();
2635
2636 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2637 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2638 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2639 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2640 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2641 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2642
2643 return CIdxr;
2644}
2645
2646void clang_disposeIndex(CXIndex CIdx) {
2647 if (CIdx)
2648 delete static_cast<CIndexer *>(CIdx);
2649}
2650
2651void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2652 if (CIdx)
2653 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2654}
2655
2656unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2657 if (CIdx)
2658 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2659 return 0;
2660}
2661
2662void clang_toggleCrashRecovery(unsigned isEnabled) {
2663 if (isEnabled)
2664 llvm::CrashRecoveryContext::Enable();
2665 else
2666 llvm::CrashRecoveryContext::Disable();
2667}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668
Guy Benyei11169dd2012-12-18 14:30:41 +00002669CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2670 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002671 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002672 enum CXErrorCode Result =
2673 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002674 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002675 assert((TU && Result == CXError_Success) ||
2676 (!TU && Result != CXError_Success));
2677 return TU;
2678}
2679
2680enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2681 const char *ast_filename,
2682 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002683 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002684 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002685
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002686 if (!CIdx || !ast_filename || !out_TU)
2687 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002689 LOG_FUNC_SECTION {
2690 *Log << ast_filename;
2691 }
2692
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2694 FileSystemOptions FileSystemOpts;
2695
2696 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002697 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002698 CXXIdx->getOnlyLocalDecls(), None,
2699 /*CaptureDiagnostics=*/true,
2700 /*AllowPCHWithCompilerErrors=*/true,
2701 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002702 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2703 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002704}
2705
2706unsigned clang_defaultEditingTranslationUnitOptions() {
2707 return CXTranslationUnit_PrecompiledPreamble |
2708 CXTranslationUnit_CacheCompletionResults;
2709}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002710
Guy Benyei11169dd2012-12-18 14:30:41 +00002711CXTranslationUnit
2712clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2713 const char *source_filename,
2714 int num_command_line_args,
2715 const char * const *command_line_args,
2716 unsigned num_unsaved_files,
2717 struct CXUnsavedFile *unsaved_files) {
2718 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2719 return clang_parseTranslationUnit(CIdx, source_filename,
2720 command_line_args, num_command_line_args,
2721 unsaved_files, num_unsaved_files,
2722 Options);
2723}
2724
2725struct ParseTranslationUnitInfo {
2726 CXIndex CIdx;
2727 const char *source_filename;
2728 const char *const *command_line_args;
2729 int num_command_line_args;
2730 struct CXUnsavedFile *unsaved_files;
2731 unsigned num_unsaved_files;
2732 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002733 CXTranslationUnit *out_TU;
2734 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002735};
2736static void clang_parseTranslationUnit_Impl(void *UserData) {
2737 ParseTranslationUnitInfo *PTUI =
2738 static_cast<ParseTranslationUnitInfo*>(UserData);
2739 CXIndex CIdx = PTUI->CIdx;
2740 const char *source_filename = PTUI->source_filename;
2741 const char * const *command_line_args = PTUI->command_line_args;
2742 int num_command_line_args = PTUI->num_command_line_args;
2743 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2744 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2745 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002746 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002747
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002748 // Set up the initial return values.
2749 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002750 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002751 PTUI->result = CXError_Failure;
2752
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002753 // Check arguments.
2754 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002755 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002756 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002757 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002758 }
2759
Guy Benyei11169dd2012-12-18 14:30:41 +00002760 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2761
2762 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2763 setThreadBackgroundPriority();
2764
2765 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2766 // FIXME: Add a flag for modules.
2767 TranslationUnitKind TUKind
2768 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002769 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 = options & CXTranslationUnit_CacheCompletionResults;
2771 bool IncludeBriefCommentsInCodeCompletion
2772 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2773 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2774 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2775
2776 // Configure the diagnostics.
2777 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002778 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002779
2780 // Recover resources if we crash before exiting this function.
2781 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2782 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002783 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002784
Ahmed Charlesb8984322014-03-07 20:03:18 +00002785 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2786 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002787
2788 // Recover resources if we crash before exiting this function.
2789 llvm::CrashRecoveryContextCleanupRegistrar<
2790 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2791
2792 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2793 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
David Blaikie66cc07b2014-06-27 17:40:03 +00002794 llvm::MemoryBuffer *Buffer =
2795 llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2797 Buffer));
2798 }
2799
Ahmed Charlesb8984322014-03-07 20:03:18 +00002800 std::unique_ptr<std::vector<const char *>> Args(
2801 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002802
2803 // Recover resources if we crash before exiting this method.
2804 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2805 ArgsCleanup(Args.get());
2806
2807 // Since the Clang C library is primarily used by batch tools dealing with
2808 // (often very broken) source code, where spell-checking can have a
2809 // significant negative impact on performance (particularly when
2810 // precompiled headers are involved), we disable it by default.
2811 // Only do this if we haven't found a spell-checking-related argument.
2812 bool FoundSpellCheckingArgument = false;
2813 for (int I = 0; I != num_command_line_args; ++I) {
2814 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2815 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2816 FoundSpellCheckingArgument = true;
2817 break;
2818 }
2819 }
2820 if (!FoundSpellCheckingArgument)
2821 Args->push_back("-fno-spell-checking");
2822
2823 Args->insert(Args->end(), command_line_args,
2824 command_line_args + num_command_line_args);
2825
2826 // The 'source_filename' argument is optional. If the caller does not
2827 // specify it then it is assumed that the source file is specified
2828 // in the actual argument list.
2829 // Put the source file after command_line_args otherwise if '-x' flag is
2830 // present it will be unused.
2831 if (source_filename)
2832 Args->push_back(source_filename);
2833
2834 // Do we need the detailed preprocessing record?
2835 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2836 Args->push_back("-Xclang");
2837 Args->push_back("-detailed-preprocessing-record");
2838 }
2839
2840 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002841 std::unique_ptr<ASTUnit> ErrUnit;
2842 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002843 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002844 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2845 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2846 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2847 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2848 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2849 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002850
2851 if (NumErrors != Diags->getClient()->getNumErrors()) {
2852 // Make sure to check that 'Unit' is non-NULL.
2853 if (CXXIdx->getDisplayDiagnostics())
2854 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2855 }
2856
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2858 PTUI->result = CXError_ASTReadError;
2859 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002860 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002861 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2862 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002863}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002864
2865CXTranslationUnit
2866clang_parseTranslationUnit(CXIndex CIdx,
2867 const char *source_filename,
2868 const char *const *command_line_args,
2869 int num_command_line_args,
2870 struct CXUnsavedFile *unsaved_files,
2871 unsigned num_unsaved_files,
2872 unsigned options) {
2873 CXTranslationUnit TU;
2874 enum CXErrorCode Result = clang_parseTranslationUnit2(
2875 CIdx, source_filename, command_line_args, num_command_line_args,
2876 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002877 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002878 assert((TU && Result == CXError_Success) ||
2879 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002880 return TU;
2881}
2882
2883enum CXErrorCode clang_parseTranslationUnit2(
2884 CXIndex CIdx,
2885 const char *source_filename,
2886 const char *const *command_line_args,
2887 int num_command_line_args,
2888 struct CXUnsavedFile *unsaved_files,
2889 unsigned num_unsaved_files,
2890 unsigned options,
2891 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002892 LOG_FUNC_SECTION {
2893 *Log << source_filename << ": ";
2894 for (int i = 0; i != num_command_line_args; ++i)
2895 *Log << command_line_args[i] << " ";
2896 }
2897
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2899 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002900 num_unsaved_files, options, out_TU,
2901 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002902 llvm::CrashRecoveryContext CRC;
2903
2904 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2905 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2906 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2907 fprintf(stderr, " 'command_line_args' : [");
2908 for (int i = 0; i != num_command_line_args; ++i) {
2909 if (i)
2910 fprintf(stderr, ", ");
2911 fprintf(stderr, "'%s'", command_line_args[i]);
2912 }
2913 fprintf(stderr, "],\n");
2914 fprintf(stderr, " 'unsaved_files' : [");
2915 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2916 if (i)
2917 fprintf(stderr, ", ");
2918 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2919 unsaved_files[i].Length);
2920 }
2921 fprintf(stderr, "],\n");
2922 fprintf(stderr, " 'options' : %d,\n", options);
2923 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002924
2925 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002926 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002927 if (CXTranslationUnit *TU = PTUI.out_TU)
2928 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 }
2930
2931 return PTUI.result;
2932}
2933
2934unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2935 return CXSaveTranslationUnit_None;
2936}
2937
2938namespace {
2939
2940struct SaveTranslationUnitInfo {
2941 CXTranslationUnit TU;
2942 const char *FileName;
2943 unsigned options;
2944 CXSaveError result;
2945};
2946
2947}
2948
2949static void clang_saveTranslationUnit_Impl(void *UserData) {
2950 SaveTranslationUnitInfo *STUI =
2951 static_cast<SaveTranslationUnitInfo*>(UserData);
2952
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002953 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002954 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2955 setThreadBackgroundPriority();
2956
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002957 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002958 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2959}
2960
2961int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2962 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002963 LOG_FUNC_SECTION {
2964 *Log << TU << ' ' << FileName;
2965 }
2966
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002967 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002968 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002970 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002971
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002972 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2974 if (!CXXUnit->hasSema())
2975 return CXSaveError_InvalidTU;
2976
2977 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2978
2979 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2980 getenv("LIBCLANG_NOTHREADS")) {
2981 clang_saveTranslationUnit_Impl(&STUI);
2982
2983 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2984 PrintLibclangResourceUsage(TU);
2985
2986 return STUI.result;
2987 }
2988
2989 // We have an AST that has invalid nodes due to compiler errors.
2990 // Use a crash recovery thread for protection.
2991
2992 llvm::CrashRecoveryContext CRC;
2993
2994 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2995 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2996 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2997 fprintf(stderr, " 'options' : %d,\n", options);
2998 fprintf(stderr, "}\n");
2999
3000 return CXSaveError_Unknown;
3001
3002 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3003 PrintLibclangResourceUsage(TU);
3004 }
3005
3006 return STUI.result;
3007}
3008
3009void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3010 if (CTUnit) {
3011 // If the translation unit has been marked as unsafe to free, just discard
3012 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003013 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3014 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 return;
3016
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003017 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003018 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003019 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3020 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003021 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003022 delete CTUnit;
3023 }
3024}
3025
3026unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3027 return CXReparse_None;
3028}
3029
3030struct ReparseTranslationUnitInfo {
3031 CXTranslationUnit TU;
3032 unsigned num_unsaved_files;
3033 struct CXUnsavedFile *unsaved_files;
3034 unsigned options;
3035 int result;
3036};
3037
3038static void clang_reparseTranslationUnit_Impl(void *UserData) {
3039 ReparseTranslationUnitInfo *RTUI =
3040 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003042
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003044 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3045 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3046 unsigned options = RTUI->options;
3047 (void) options;
3048
3049 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003050 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003051 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052 RTUI->result = CXError_InvalidArguments;
3053 return;
3054 }
Craig Topper69186e72014-06-08 08:38:04 +00003055 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003057 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003058 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003059
3060 // Reset the associated diagnostics.
3061 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003062 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003063
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003064 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003065 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3066 setThreadBackgroundPriority();
3067
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003068 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003070
3071 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3072 new std::vector<ASTUnit::RemappedFile>());
3073
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 // Recover resources if we crash before exiting this function.
3075 llvm::CrashRecoveryContextCleanupRegistrar<
3076 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3077
3078 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3079 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
David Blaikie66cc07b2014-06-27 17:40:03 +00003080 llvm::MemoryBuffer *Buffer =
3081 llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3083 Buffer));
3084 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003085
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003086 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003087 RTUI->result = CXError_Success;
3088 else if (isASTReadError(CXXUnit))
3089 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003090}
3091
3092int clang_reparseTranslationUnit(CXTranslationUnit TU,
3093 unsigned num_unsaved_files,
3094 struct CXUnsavedFile *unsaved_files,
3095 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003096 LOG_FUNC_SECTION {
3097 *Log << TU;
3098 }
3099
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003101 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003102
3103 if (getenv("LIBCLANG_NOTHREADS")) {
3104 clang_reparseTranslationUnit_Impl(&RTUI);
3105 return RTUI.result;
3106 }
3107
3108 llvm::CrashRecoveryContext CRC;
3109
3110 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3111 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003112 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003113 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3115 PrintLibclangResourceUsage(TU);
3116
3117 return RTUI.result;
3118}
3119
3120
3121CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003122 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003123 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003124 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003125 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003126
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003127 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003128 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003129}
3130
3131CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003132 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003133 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003134 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003135 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003137 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3139}
3140
3141} // end: extern "C"
3142
3143//===----------------------------------------------------------------------===//
3144// CXFile Operations.
3145//===----------------------------------------------------------------------===//
3146
3147extern "C" {
3148CXString clang_getFileName(CXFile SFile) {
3149 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003150 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003151
3152 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003153 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003154}
3155
3156time_t clang_getFileTime(CXFile SFile) {
3157 if (!SFile)
3158 return 0;
3159
3160 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3161 return FEnt->getModificationTime();
3162}
3163
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003164CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003165 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003166 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003167 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003168 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003169
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003170 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003171
3172 FileManager &FMgr = CXXUnit->getFileManager();
3173 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3174}
3175
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003176unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3177 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003178 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003179 LOG_BAD_TU(TU);
3180 return 0;
3181 }
3182
3183 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return 0;
3185
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003186 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 FileEntry *FEnt = static_cast<FileEntry *>(file);
3188 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3189 .isFileMultipleIncludeGuarded(FEnt);
3190}
3191
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003192int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3193 if (!file || !outID)
3194 return 1;
3195
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003196 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003197 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3198 outID->data[0] = ID.getDevice();
3199 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003200 outID->data[2] = FEnt->getModificationTime();
3201 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003202}
3203
Guy Benyei11169dd2012-12-18 14:30:41 +00003204} // end: extern "C"
3205
3206//===----------------------------------------------------------------------===//
3207// CXCursor Operations.
3208//===----------------------------------------------------------------------===//
3209
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003210static const Decl *getDeclFromExpr(const Stmt *E) {
3211 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return getDeclFromExpr(CE->getSubExpr());
3213
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003214 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003218 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003220 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 if (PRE->isExplicitProperty())
3222 return PRE->getExplicitProperty();
3223 // It could be messaging both getter and setter as in:
3224 // ++myobj.myprop;
3225 // in which case prefer to associate the setter since it is less obvious
3226 // from inspecting the source that the setter is going to get called.
3227 if (PRE->isMessagingSetter())
3228 return PRE->getImplicitPropertySetter();
3229 return PRE->getImplicitPropertyGetter();
3230 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003231 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003233 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 if (Expr *Src = OVE->getSourceExpr())
3235 return getDeclFromExpr(Src);
3236
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003237 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003239 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 if (!CE->isElidable())
3241 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003242 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 return OME->getMethodDecl();
3244
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003245 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003247 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3249 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003250 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3252 isa<ParmVarDecl>(SizeOfPack->getPack()))
3253 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003254
3255 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003256}
3257
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003258static SourceLocation getLocationFromExpr(const Expr *E) {
3259 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return getLocationFromExpr(CE->getSubExpr());
3261
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003262 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003264 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003266 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003268 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003270 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003272 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 return PropRef->getLocation();
3274
3275 return E->getLocStart();
3276}
3277
3278extern "C" {
3279
3280unsigned clang_visitChildren(CXCursor parent,
3281 CXCursorVisitor visitor,
3282 CXClientData client_data) {
3283 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3284 /*VisitPreprocessorLast=*/false);
3285 return CursorVis.VisitChildren(parent);
3286}
3287
3288#ifndef __has_feature
3289#define __has_feature(x) 0
3290#endif
3291#if __has_feature(blocks)
3292typedef enum CXChildVisitResult
3293 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3294
3295static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3296 CXClientData client_data) {
3297 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3298 return block(cursor, parent);
3299}
3300#else
3301// If we are compiled with a compiler that doesn't have native blocks support,
3302// define and call the block manually, so the
3303typedef struct _CXChildVisitResult
3304{
3305 void *isa;
3306 int flags;
3307 int reserved;
3308 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3309 CXCursor);
3310} *CXCursorVisitorBlock;
3311
3312static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3313 CXClientData client_data) {
3314 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3315 return block->invoke(block, cursor, parent);
3316}
3317#endif
3318
3319
3320unsigned clang_visitChildrenWithBlock(CXCursor parent,
3321 CXCursorVisitorBlock block) {
3322 return clang_visitChildren(parent, visitWithBlock, block);
3323}
3324
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003327 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003331 if (const ObjCPropertyImplDecl *PropImpl =
3332 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003334 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003336 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003338 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003339
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003340 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 }
3342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003344 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003345
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003346 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3348 // and returns different names. NamedDecl returns the class name and
3349 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003350 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351
3352 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003353 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
3355 SmallString<1024> S;
3356 llvm::raw_svector_ostream os(S);
3357 ND->printName(os);
3358
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003359 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003360}
3361
3362CXString clang_getCursorSpelling(CXCursor C) {
3363 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003364 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003365
3366 if (clang_isReference(C.kind)) {
3367 switch (C.kind) {
3368 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003369 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003370 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
3372 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003373 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003374 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 }
3376 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003377 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003379 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003382 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003383 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 }
3385 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003386 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 assert(Type && "Missing type decl");
3388
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003389 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 getAsString());
3391 }
3392 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003393 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 assert(Template && "Missing template decl");
3395
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003396 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398
3399 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003400 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 assert(NS && "Missing namespace decl");
3402
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003403 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 }
3405
3406 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003407 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 assert(Field && "Missing member decl");
3409
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003410 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 }
3412
3413 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003414 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 assert(Label && "Missing label");
3416
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003417 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 }
3419
3420 case CXCursor_OverloadedDeclRef: {
3421 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003422 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3423 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003424 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003425 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003427 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003428 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 OverloadedTemplateStorage *Ovl
3430 = Storage.get<OverloadedTemplateStorage*>();
3431 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003432 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 }
3435
3436 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003437 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 assert(Var && "Missing variable decl");
3439
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003440 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 }
3442
3443 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003444 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 }
3446 }
3447
3448 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003449 const Expr *E = getCursorExpr(C);
3450
3451 if (C.kind == CXCursor_ObjCStringLiteral ||
3452 C.kind == CXCursor_StringLiteral) {
3453 const StringLiteral *SLit;
3454 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3455 SLit = OSL->getString();
3456 } else {
3457 SLit = cast<StringLiteral>(E);
3458 }
3459 SmallString<256> Buf;
3460 llvm::raw_svector_ostream OS(Buf);
3461 SLit->outputString(OS);
3462 return cxstring::createDup(OS.str());
3463 }
3464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 if (D)
3467 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003468 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 }
3470
3471 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003472 const Stmt *S = getCursorStmt(C);
3473 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003474 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003475
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003476 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 }
3478
3479 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003480 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 ->getNameStart());
3482
3483 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003484 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 ->getNameStart());
3486
3487 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003488 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003489
3490 if (clang_isDeclaration(C.kind))
3491 return getDeclSpelling(getCursorDecl(C));
3492
3493 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003494 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003495 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 }
3497
3498 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003499 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003500 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 }
3502
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003503 if (C.kind == CXCursor_PackedAttr) {
3504 return cxstring::createRef("packed");
3505 }
3506
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003507 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003508}
3509
3510CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3511 unsigned pieceIndex,
3512 unsigned options) {
3513 if (clang_Cursor_isNull(C))
3514 return clang_getNullRange();
3515
3516 ASTContext &Ctx = getCursorContext(C);
3517
3518 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003519 const Stmt *S = getCursorStmt(C);
3520 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 if (pieceIndex > 0)
3522 return clang_getNullRange();
3523 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3524 }
3525
3526 return clang_getNullRange();
3527 }
3528
3529 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003530 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3532 if (pieceIndex >= ME->getNumSelectorLocs())
3533 return clang_getNullRange();
3534 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3535 }
3536 }
3537
3538 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3539 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003540 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3542 if (pieceIndex >= MD->getNumSelectorLocs())
3543 return clang_getNullRange();
3544 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3545 }
3546 }
3547
3548 if (C.kind == CXCursor_ObjCCategoryDecl ||
3549 C.kind == CXCursor_ObjCCategoryImplDecl) {
3550 if (pieceIndex > 0)
3551 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003552 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3554 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3557 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3558 }
3559
3560 if (C.kind == CXCursor_ModuleImportDecl) {
3561 if (pieceIndex > 0)
3562 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003563 if (const ImportDecl *ImportD =
3564 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3566 if (!Locs.empty())
3567 return cxloc::translateSourceRange(Ctx,
3568 SourceRange(Locs.front(), Locs.back()));
3569 }
3570 return clang_getNullRange();
3571 }
3572
3573 // FIXME: A CXCursor_InclusionDirective should give the location of the
3574 // filename, but we don't keep track of this.
3575
3576 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3577 // but we don't keep track of this.
3578
3579 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3580 // but we don't keep track of this.
3581
3582 // Default handling, give the location of the cursor.
3583
3584 if (pieceIndex > 0)
3585 return clang_getNullRange();
3586
3587 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3588 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3589 return cxloc::translateSourceRange(Ctx, Loc);
3590}
3591
3592CXString clang_getCursorDisplayName(CXCursor C) {
3593 if (!clang_isDeclaration(C.kind))
3594 return clang_getCursorSpelling(C);
3595
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003596 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003598 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003599
3600 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 D = FunTmpl->getTemplatedDecl();
3603
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003604 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 SmallString<64> Str;
3606 llvm::raw_svector_ostream OS(Str);
3607 OS << *Function;
3608 if (Function->getPrimaryTemplate())
3609 OS << "<>";
3610 OS << "(";
3611 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3612 if (I)
3613 OS << ", ";
3614 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3615 }
3616
3617 if (Function->isVariadic()) {
3618 if (Function->getNumParams())
3619 OS << ", ";
3620 OS << "...";
3621 }
3622 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003623 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 }
3625
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003626 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 SmallString<64> Str;
3628 llvm::raw_svector_ostream OS(Str);
3629 OS << *ClassTemplate;
3630 OS << "<";
3631 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3632 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3633 if (I)
3634 OS << ", ";
3635
3636 NamedDecl *Param = Params->getParam(I);
3637 if (Param->getIdentifier()) {
3638 OS << Param->getIdentifier()->getName();
3639 continue;
3640 }
3641
3642 // There is no parameter name, which makes this tricky. Try to come up
3643 // with something useful that isn't too long.
3644 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3645 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3646 else if (NonTypeTemplateParmDecl *NTTP
3647 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3648 OS << NTTP->getType().getAsString(Policy);
3649 else
3650 OS << "template<...> class";
3651 }
3652
3653 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003654 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 }
3656
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003657 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3659 // If the type was explicitly written, use that.
3660 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003661 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003662
Benjamin Kramer9170e912013-02-22 15:46:01 +00003663 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 llvm::raw_svector_ostream OS(Str);
3665 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003666 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 ClassSpec->getTemplateArgs().data(),
3668 ClassSpec->getTemplateArgs().size(),
3669 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003670 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 }
3672
3673 return clang_getCursorSpelling(C);
3674}
3675
3676CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3677 switch (Kind) {
3678 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003806 case CXCursor_ObjCSelfExpr:
3807 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003896 case CXCursor_SEHLeaveStmt:
3897 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003926 case CXCursor_PackedAttr:
3927 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003928 case CXCursor_PureAttr:
3929 return cxstring::createRef("attribute(pure)");
3930 case CXCursor_ConstAttr:
3931 return cxstring::createRef("attribute(const)");
3932 case CXCursor_NoDuplicateAttr:
3933 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003934 case CXCursor_CUDAConstantAttr:
3935 return cxstring::createRef("attribute(constant)");
3936 case CXCursor_CUDADeviceAttr:
3937 return cxstring::createRef("attribute(device)");
3938 case CXCursor_CUDAGlobalAttr:
3939 return cxstring::createRef("attribute(global)");
3940 case CXCursor_CUDAHostAttr:
3941 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003990 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003991 return cxstring::createRef("OMPParallelDirective");
3992 case CXCursor_OMPSimdDirective:
3993 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003994 case CXCursor_OMPForDirective:
3995 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003996 case CXCursor_OMPSectionsDirective:
3997 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003998 case CXCursor_OMPSectionDirective:
3999 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004000 case CXCursor_OMPSingleDirective:
4001 return cxstring::createRef("OMPSingleDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 }
4003
4004 llvm_unreachable("Unhandled CXCursorKind");
4005}
4006
4007struct GetCursorData {
4008 SourceLocation TokenBeginLoc;
4009 bool PointsAtMacroArgExpansion;
4010 bool VisitedObjCPropertyImplDecl;
4011 SourceLocation VisitedDeclaratorDeclStartLoc;
4012 CXCursor &BestCursor;
4013
4014 GetCursorData(SourceManager &SM,
4015 SourceLocation tokenBegin, CXCursor &outputCursor)
4016 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4017 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4018 VisitedObjCPropertyImplDecl = false;
4019 }
4020};
4021
4022static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4023 CXCursor parent,
4024 CXClientData client_data) {
4025 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4026 CXCursor *BestCursor = &Data->BestCursor;
4027
4028 // If we point inside a macro argument we should provide info of what the
4029 // token is so use the actual cursor, don't replace it with a macro expansion
4030 // cursor.
4031 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4032 return CXChildVisit_Recurse;
4033
4034 if (clang_isDeclaration(cursor.kind)) {
4035 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004036 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4038 if (MD->isImplicit())
4039 return CXChildVisit_Break;
4040
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004041 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4043 // Check that when we have multiple @class references in the same line,
4044 // that later ones do not override the previous ones.
4045 // If we have:
4046 // @class Foo, Bar;
4047 // source ranges for both start at '@', so 'Bar' will end up overriding
4048 // 'Foo' even though the cursor location was at 'Foo'.
4049 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4050 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004051 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4053 if (PrevID != ID &&
4054 !PrevID->isThisDeclarationADefinition() &&
4055 !ID->isThisDeclarationADefinition())
4056 return CXChildVisit_Break;
4057 }
4058
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004059 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4061 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4062 // Check that when we have multiple declarators in the same line,
4063 // that later ones do not override the previous ones.
4064 // If we have:
4065 // int Foo, Bar;
4066 // source ranges for both start at 'int', so 'Bar' will end up overriding
4067 // 'Foo' even though the cursor location was at 'Foo'.
4068 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4069 return CXChildVisit_Break;
4070 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004072 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4074 (void)PropImp;
4075 // Check that when we have multiple @synthesize in the same line,
4076 // that later ones do not override the previous ones.
4077 // If we have:
4078 // @synthesize Foo, Bar;
4079 // source ranges for both start at '@', so 'Bar' will end up overriding
4080 // 'Foo' even though the cursor location was at 'Foo'.
4081 if (Data->VisitedObjCPropertyImplDecl)
4082 return CXChildVisit_Break;
4083 Data->VisitedObjCPropertyImplDecl = true;
4084 }
4085 }
4086
4087 if (clang_isExpression(cursor.kind) &&
4088 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004089 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 // Avoid having the cursor of an expression replace the declaration cursor
4091 // when the expression source range overlaps the declaration range.
4092 // This can happen for C++ constructor expressions whose range generally
4093 // include the variable declaration, e.g.:
4094 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4095 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4096 D->getLocation() == Data->TokenBeginLoc)
4097 return CXChildVisit_Break;
4098 }
4099 }
4100
4101 // If our current best cursor is the construction of a temporary object,
4102 // don't replace that cursor with a type reference, because we want
4103 // clang_getCursor() to point at the constructor.
4104 if (clang_isExpression(BestCursor->kind) &&
4105 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4106 cursor.kind == CXCursor_TypeRef) {
4107 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4108 // as having the actual point on the type reference.
4109 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4110 return CXChildVisit_Recurse;
4111 }
4112
4113 *BestCursor = cursor;
4114 return CXChildVisit_Recurse;
4115}
4116
4117CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004118 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004119 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004121 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004122
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004123 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4125
4126 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4127 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4128
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004129 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 CXFile SearchFile;
4131 unsigned SearchLine, SearchColumn;
4132 CXFile ResultFile;
4133 unsigned ResultLine, ResultColumn;
4134 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4135 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4136 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004137
4138 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4139 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004140 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004141 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 SearchFileName = clang_getFileName(SearchFile);
4143 ResultFileName = clang_getFileName(ResultFile);
4144 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4145 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004146 *Log << llvm::format("(%s:%d:%d) = %s",
4147 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4148 clang_getCString(KindSpelling))
4149 << llvm::format("(%s:%d:%d):%s%s",
4150 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4151 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 clang_disposeString(SearchFileName);
4153 clang_disposeString(ResultFileName);
4154 clang_disposeString(KindSpelling);
4155 clang_disposeString(USR);
4156
4157 CXCursor Definition = clang_getCursorDefinition(Result);
4158 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4159 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4160 CXString DefinitionKindSpelling
4161 = clang_getCursorKindSpelling(Definition.kind);
4162 CXFile DefinitionFile;
4163 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004164 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004165 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004167 *Log << llvm::format(" -> %s(%s:%d:%d)",
4168 clang_getCString(DefinitionKindSpelling),
4169 clang_getCString(DefinitionFileName),
4170 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 clang_disposeString(DefinitionFileName);
4172 clang_disposeString(DefinitionKindSpelling);
4173 }
4174 }
4175
4176 return Result;
4177}
4178
4179CXCursor clang_getNullCursor(void) {
4180 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4181}
4182
4183unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004184 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4185 // can't set consistently. For example, when visiting a DeclStmt we will set
4186 // it but we don't set it on the result of clang_getCursorDefinition for
4187 // a reference of the same declaration.
4188 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4189 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4190 // to provide that kind of info.
4191 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004192 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004193 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004194 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004195
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 return X == Y;
4197}
4198
4199unsigned clang_hashCursor(CXCursor C) {
4200 unsigned Index = 0;
4201 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4202 Index = 1;
4203
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 std::make_pair(C.kind, C.data[Index]));
4206}
4207
4208unsigned clang_isInvalid(enum CXCursorKind K) {
4209 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4210}
4211
4212unsigned clang_isDeclaration(enum CXCursorKind K) {
4213 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4214 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4215}
4216
4217unsigned clang_isReference(enum CXCursorKind K) {
4218 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4219}
4220
4221unsigned clang_isExpression(enum CXCursorKind K) {
4222 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4223}
4224
4225unsigned clang_isStatement(enum CXCursorKind K) {
4226 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4227}
4228
4229unsigned clang_isAttribute(enum CXCursorKind K) {
4230 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4231}
4232
4233unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4234 return K == CXCursor_TranslationUnit;
4235}
4236
4237unsigned clang_isPreprocessing(enum CXCursorKind K) {
4238 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4239}
4240
4241unsigned clang_isUnexposed(enum CXCursorKind K) {
4242 switch (K) {
4243 case CXCursor_UnexposedDecl:
4244 case CXCursor_UnexposedExpr:
4245 case CXCursor_UnexposedStmt:
4246 case CXCursor_UnexposedAttr:
4247 return true;
4248 default:
4249 return false;
4250 }
4251}
4252
4253CXCursorKind clang_getCursorKind(CXCursor C) {
4254 return C.kind;
4255}
4256
4257CXSourceLocation clang_getCursorLocation(CXCursor C) {
4258 if (clang_isReference(C.kind)) {
4259 switch (C.kind) {
4260 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004261 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 = getCursorObjCSuperClassRef(C);
4263 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4264 }
4265
4266 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004267 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 = getCursorObjCProtocolRef(C);
4269 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4270 }
4271
4272 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004273 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 = getCursorObjCClassRef(C);
4275 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4276 }
4277
4278 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004279 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4281 }
4282
4283 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004284 std::pair<const TemplateDecl *, SourceLocation> P =
4285 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4287 }
4288
4289 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004290 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4292 }
4293
4294 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004295 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4297 }
4298
4299 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004300 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4302 }
4303
4304 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004305 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 if (!BaseSpec)
4307 return clang_getNullLocation();
4308
4309 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4310 return cxloc::translateSourceLocation(getCursorContext(C),
4311 TSInfo->getTypeLoc().getBeginLoc());
4312
4313 return cxloc::translateSourceLocation(getCursorContext(C),
4314 BaseSpec->getLocStart());
4315 }
4316
4317 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004318 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4320 }
4321
4322 case CXCursor_OverloadedDeclRef:
4323 return cxloc::translateSourceLocation(getCursorContext(C),
4324 getCursorOverloadedDeclRef(C).second);
4325
4326 default:
4327 // FIXME: Need a way to enumerate all non-reference cases.
4328 llvm_unreachable("Missed a reference kind");
4329 }
4330 }
4331
4332 if (clang_isExpression(C.kind))
4333 return cxloc::translateSourceLocation(getCursorContext(C),
4334 getLocationFromExpr(getCursorExpr(C)));
4335
4336 if (clang_isStatement(C.kind))
4337 return cxloc::translateSourceLocation(getCursorContext(C),
4338 getCursorStmt(C)->getLocStart());
4339
4340 if (C.kind == CXCursor_PreprocessingDirective) {
4341 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4342 return cxloc::translateSourceLocation(getCursorContext(C), L);
4343 }
4344
4345 if (C.kind == CXCursor_MacroExpansion) {
4346 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004347 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004348 return cxloc::translateSourceLocation(getCursorContext(C), L);
4349 }
4350
4351 if (C.kind == CXCursor_MacroDefinition) {
4352 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4353 return cxloc::translateSourceLocation(getCursorContext(C), L);
4354 }
4355
4356 if (C.kind == CXCursor_InclusionDirective) {
4357 SourceLocation L
4358 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4359 return cxloc::translateSourceLocation(getCursorContext(C), L);
4360 }
4361
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004362 if (clang_isAttribute(C.kind)) {
4363 SourceLocation L
4364 = cxcursor::getCursorAttr(C)->getLocation();
4365 return cxloc::translateSourceLocation(getCursorContext(C), L);
4366 }
4367
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 if (!clang_isDeclaration(C.kind))
4369 return clang_getNullLocation();
4370
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004371 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 if (!D)
4373 return clang_getNullLocation();
4374
4375 SourceLocation Loc = D->getLocation();
4376 // FIXME: Multiple variables declared in a single declaration
4377 // currently lack the information needed to correctly determine their
4378 // ranges when accounting for the type-specifier. We use context
4379 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4380 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004381 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 if (!cxcursor::isFirstInDeclGroup(C))
4383 Loc = VD->getLocation();
4384 }
4385
4386 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004387 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 Loc = MD->getSelectorStartLoc();
4389
4390 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4391}
4392
4393} // end extern "C"
4394
4395CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4396 assert(TU);
4397
4398 // Guard against an invalid SourceLocation, or we may assert in one
4399 // of the following calls.
4400 if (SLoc.isInvalid())
4401 return clang_getNullCursor();
4402
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004403 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004404
4405 // Translate the given source location to make it point at the beginning of
4406 // the token under the cursor.
4407 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4408 CXXUnit->getASTContext().getLangOpts());
4409
4410 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4411 if (SLoc.isValid()) {
4412 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4413 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4414 /*VisitPreprocessorLast=*/true,
4415 /*VisitIncludedEntities=*/false,
4416 SourceLocation(SLoc));
4417 CursorVis.visitFileRegion();
4418 }
4419
4420 return Result;
4421}
4422
4423static SourceRange getRawCursorExtent(CXCursor C) {
4424 if (clang_isReference(C.kind)) {
4425 switch (C.kind) {
4426 case CXCursor_ObjCSuperClassRef:
4427 return getCursorObjCSuperClassRef(C).second;
4428
4429 case CXCursor_ObjCProtocolRef:
4430 return getCursorObjCProtocolRef(C).second;
4431
4432 case CXCursor_ObjCClassRef:
4433 return getCursorObjCClassRef(C).second;
4434
4435 case CXCursor_TypeRef:
4436 return getCursorTypeRef(C).second;
4437
4438 case CXCursor_TemplateRef:
4439 return getCursorTemplateRef(C).second;
4440
4441 case CXCursor_NamespaceRef:
4442 return getCursorNamespaceRef(C).second;
4443
4444 case CXCursor_MemberRef:
4445 return getCursorMemberRef(C).second;
4446
4447 case CXCursor_CXXBaseSpecifier:
4448 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4449
4450 case CXCursor_LabelRef:
4451 return getCursorLabelRef(C).second;
4452
4453 case CXCursor_OverloadedDeclRef:
4454 return getCursorOverloadedDeclRef(C).second;
4455
4456 case CXCursor_VariableRef:
4457 return getCursorVariableRef(C).second;
4458
4459 default:
4460 // FIXME: Need a way to enumerate all non-reference cases.
4461 llvm_unreachable("Missed a reference kind");
4462 }
4463 }
4464
4465 if (clang_isExpression(C.kind))
4466 return getCursorExpr(C)->getSourceRange();
4467
4468 if (clang_isStatement(C.kind))
4469 return getCursorStmt(C)->getSourceRange();
4470
4471 if (clang_isAttribute(C.kind))
4472 return getCursorAttr(C)->getRange();
4473
4474 if (C.kind == CXCursor_PreprocessingDirective)
4475 return cxcursor::getCursorPreprocessingDirective(C);
4476
4477 if (C.kind == CXCursor_MacroExpansion) {
4478 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004479 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 return TU->mapRangeFromPreamble(Range);
4481 }
4482
4483 if (C.kind == CXCursor_MacroDefinition) {
4484 ASTUnit *TU = getCursorASTUnit(C);
4485 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4486 return TU->mapRangeFromPreamble(Range);
4487 }
4488
4489 if (C.kind == CXCursor_InclusionDirective) {
4490 ASTUnit *TU = getCursorASTUnit(C);
4491 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4492 return TU->mapRangeFromPreamble(Range);
4493 }
4494
4495 if (C.kind == CXCursor_TranslationUnit) {
4496 ASTUnit *TU = getCursorASTUnit(C);
4497 FileID MainID = TU->getSourceManager().getMainFileID();
4498 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4499 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4500 return SourceRange(Start, End);
4501 }
4502
4503 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004504 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 if (!D)
4506 return SourceRange();
4507
4508 SourceRange R = D->getSourceRange();
4509 // FIXME: Multiple variables declared in a single declaration
4510 // currently lack the information needed to correctly determine their
4511 // ranges when accounting for the type-specifier. We use context
4512 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4513 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (!cxcursor::isFirstInDeclGroup(C))
4516 R.setBegin(VD->getLocation());
4517 }
4518 return R;
4519 }
4520 return SourceRange();
4521}
4522
4523/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4524/// the decl-specifier-seq for declarations.
4525static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4526 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004527 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 if (!D)
4529 return SourceRange();
4530
4531 SourceRange R = D->getSourceRange();
4532
4533 // Adjust the start of the location for declarations preceded by
4534 // declaration specifiers.
4535 SourceLocation StartLoc;
4536 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4537 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4538 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004539 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4541 StartLoc = TI->getTypeLoc().getLocStart();
4542 }
4543
4544 if (StartLoc.isValid() && R.getBegin().isValid() &&
4545 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4546 R.setBegin(StartLoc);
4547
4548 // FIXME: Multiple variables declared in a single declaration
4549 // currently lack the information needed to correctly determine their
4550 // ranges when accounting for the type-specifier. We use context
4551 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4552 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 if (!cxcursor::isFirstInDeclGroup(C))
4555 R.setBegin(VD->getLocation());
4556 }
4557
4558 return R;
4559 }
4560
4561 return getRawCursorExtent(C);
4562}
4563
4564extern "C" {
4565
4566CXSourceRange clang_getCursorExtent(CXCursor C) {
4567 SourceRange R = getRawCursorExtent(C);
4568 if (R.isInvalid())
4569 return clang_getNullRange();
4570
4571 return cxloc::translateSourceRange(getCursorContext(C), R);
4572}
4573
4574CXCursor clang_getCursorReferenced(CXCursor C) {
4575 if (clang_isInvalid(C.kind))
4576 return clang_getNullCursor();
4577
4578 CXTranslationUnit tu = getCursorTU(C);
4579 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004580 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 if (!D)
4582 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004583 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004585 if (const ObjCPropertyImplDecl *PropImpl =
4586 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4588 return MakeCXCursor(Property, tu);
4589
4590 return C;
4591 }
4592
4593 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 const Expr *E = getCursorExpr(C);
4595 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 if (D) {
4597 CXCursor declCursor = MakeCXCursor(D, tu);
4598 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4599 declCursor);
4600 return declCursor;
4601 }
4602
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004603 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 return MakeCursorOverloadedDeclRef(Ovl, tu);
4605
4606 return clang_getNullCursor();
4607 }
4608
4609 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004610 const Stmt *S = getCursorStmt(C);
4611 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 if (LabelDecl *label = Goto->getLabel())
4613 if (LabelStmt *labelS = label->getStmt())
4614 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4615
4616 return clang_getNullCursor();
4617 }
4618
4619 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 return MakeMacroDefinitionCursor(Def, tu);
4622 }
4623
4624 if (!clang_isReference(C.kind))
4625 return clang_getNullCursor();
4626
4627 switch (C.kind) {
4628 case CXCursor_ObjCSuperClassRef:
4629 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4630
4631 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004632 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4633 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 return MakeCXCursor(Def, tu);
4635
4636 return MakeCXCursor(Prot, tu);
4637 }
4638
4639 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004640 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4641 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 return MakeCXCursor(Def, tu);
4643
4644 return MakeCXCursor(Class, tu);
4645 }
4646
4647 case CXCursor_TypeRef:
4648 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4649
4650 case CXCursor_TemplateRef:
4651 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4652
4653 case CXCursor_NamespaceRef:
4654 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4655
4656 case CXCursor_MemberRef:
4657 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4658
4659 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004660 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4662 tu ));
4663 }
4664
4665 case CXCursor_LabelRef:
4666 // FIXME: We end up faking the "parent" declaration here because we
4667 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004668 return MakeCXCursor(getCursorLabelRef(C).first,
4669 cxtu::getASTUnit(tu)->getASTContext()
4670 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 tu);
4672
4673 case CXCursor_OverloadedDeclRef:
4674 return C;
4675
4676 case CXCursor_VariableRef:
4677 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4678
4679 default:
4680 // We would prefer to enumerate all non-reference cursor kinds here.
4681 llvm_unreachable("Unhandled reference cursor kind");
4682 }
4683}
4684
4685CXCursor clang_getCursorDefinition(CXCursor C) {
4686 if (clang_isInvalid(C.kind))
4687 return clang_getNullCursor();
4688
4689 CXTranslationUnit TU = getCursorTU(C);
4690
4691 bool WasReference = false;
4692 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4693 C = clang_getCursorReferenced(C);
4694 WasReference = true;
4695 }
4696
4697 if (C.kind == CXCursor_MacroExpansion)
4698 return clang_getCursorReferenced(C);
4699
4700 if (!clang_isDeclaration(C.kind))
4701 return clang_getNullCursor();
4702
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004703 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 if (!D)
4705 return clang_getNullCursor();
4706
4707 switch (D->getKind()) {
4708 // Declaration kinds that don't really separate the notions of
4709 // declaration and definition.
4710 case Decl::Namespace:
4711 case Decl::Typedef:
4712 case Decl::TypeAlias:
4713 case Decl::TypeAliasTemplate:
4714 case Decl::TemplateTypeParm:
4715 case Decl::EnumConstant:
4716 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004717 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 case Decl::IndirectField:
4719 case Decl::ObjCIvar:
4720 case Decl::ObjCAtDefsField:
4721 case Decl::ImplicitParam:
4722 case Decl::ParmVar:
4723 case Decl::NonTypeTemplateParm:
4724 case Decl::TemplateTemplateParm:
4725 case Decl::ObjCCategoryImpl:
4726 case Decl::ObjCImplementation:
4727 case Decl::AccessSpec:
4728 case Decl::LinkageSpec:
4729 case Decl::ObjCPropertyImpl:
4730 case Decl::FileScopeAsm:
4731 case Decl::StaticAssert:
4732 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004733 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case Decl::Label: // FIXME: Is this right??
4735 case Decl::ClassScopeFunctionSpecialization:
4736 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004737 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 return C;
4739
4740 // Declaration kinds that don't make any sense here, but are
4741 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004742 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case Decl::TranslationUnit:
4744 break;
4745
4746 // Declaration kinds for which the definition is not resolvable.
4747 case Decl::UnresolvedUsingTypename:
4748 case Decl::UnresolvedUsingValue:
4749 break;
4750
4751 case Decl::UsingDirective:
4752 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4753 TU);
4754
4755 case Decl::NamespaceAlias:
4756 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4757
4758 case Decl::Enum:
4759 case Decl::Record:
4760 case Decl::CXXRecord:
4761 case Decl::ClassTemplateSpecialization:
4762 case Decl::ClassTemplatePartialSpecialization:
4763 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4764 return MakeCXCursor(Def, TU);
4765 return clang_getNullCursor();
4766
4767 case Decl::Function:
4768 case Decl::CXXMethod:
4769 case Decl::CXXConstructor:
4770 case Decl::CXXDestructor:
4771 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004772 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004774 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 return clang_getNullCursor();
4776 }
4777
Larisse Voufo39a1e502013-08-06 01:03:05 +00004778 case Decl::Var:
4779 case Decl::VarTemplateSpecialization:
4780 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004782 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 return MakeCXCursor(Def, TU);
4784 return clang_getNullCursor();
4785 }
4786
4787 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004788 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4790 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4791 return clang_getNullCursor();
4792 }
4793
4794 case Decl::ClassTemplate: {
4795 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4796 ->getDefinition())
4797 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4798 TU);
4799 return clang_getNullCursor();
4800 }
4801
Larisse Voufo39a1e502013-08-06 01:03:05 +00004802 case Decl::VarTemplate: {
4803 if (VarDecl *Def =
4804 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4805 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4806 return clang_getNullCursor();
4807 }
4808
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 case Decl::Using:
4810 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4811 D->getLocation(), TU);
4812
4813 case Decl::UsingShadow:
4814 return clang_getCursorDefinition(
4815 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4816 TU));
4817
4818 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004819 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 if (Method->isThisDeclarationADefinition())
4821 return C;
4822
4823 // Dig out the method definition in the associated
4824 // @implementation, if we have it.
4825 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004826 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4828 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4829 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4830 Method->isInstanceMethod()))
4831 if (Def->isThisDeclarationADefinition())
4832 return MakeCXCursor(Def, TU);
4833
4834 return clang_getNullCursor();
4835 }
4836
4837 case Decl::ObjCCategory:
4838 if (ObjCCategoryImplDecl *Impl
4839 = cast<ObjCCategoryDecl>(D)->getImplementation())
4840 return MakeCXCursor(Impl, TU);
4841 return clang_getNullCursor();
4842
4843 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 return MakeCXCursor(Def, TU);
4846 return clang_getNullCursor();
4847
4848 case Decl::ObjCInterface: {
4849 // There are two notions of a "definition" for an Objective-C
4850 // class: the interface and its implementation. When we resolved a
4851 // reference to an Objective-C class, produce the @interface as
4852 // the definition; when we were provided with the interface,
4853 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004854 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 return MakeCXCursor(Def, TU);
4858 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4859 return MakeCXCursor(Impl, TU);
4860 return clang_getNullCursor();
4861 }
4862
4863 case Decl::ObjCProperty:
4864 // FIXME: We don't really know where to find the
4865 // ObjCPropertyImplDecls that implement this property.
4866 return clang_getNullCursor();
4867
4868 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004870 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004871 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 return MakeCXCursor(Def, TU);
4873
4874 return clang_getNullCursor();
4875
4876 case Decl::Friend:
4877 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4878 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4879 return clang_getNullCursor();
4880
4881 case Decl::FriendTemplate:
4882 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4883 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4884 return clang_getNullCursor();
4885 }
4886
4887 return clang_getNullCursor();
4888}
4889
4890unsigned clang_isCursorDefinition(CXCursor C) {
4891 if (!clang_isDeclaration(C.kind))
4892 return 0;
4893
4894 return clang_getCursorDefinition(C) == C;
4895}
4896
4897CXCursor clang_getCanonicalCursor(CXCursor C) {
4898 if (!clang_isDeclaration(C.kind))
4899 return C;
4900
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 if (const Decl *D = getCursorDecl(C)) {
4902 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4904 return MakeCXCursor(CatD, getCursorTU(C));
4905
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004906 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4907 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 return MakeCXCursor(IFD, getCursorTU(C));
4909
4910 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4911 }
4912
4913 return C;
4914}
4915
4916int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4917 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4918}
4919
4920unsigned clang_getNumOverloadedDecls(CXCursor C) {
4921 if (C.kind != CXCursor_OverloadedDeclRef)
4922 return 0;
4923
4924 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004925 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 return E->getNumDecls();
4927
4928 if (OverloadedTemplateStorage *S
4929 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4930 return S->size();
4931
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004932 const Decl *D = Storage.get<const Decl *>();
4933 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 return Using->shadow_size();
4935
4936 return 0;
4937}
4938
4939CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4940 if (cursor.kind != CXCursor_OverloadedDeclRef)
4941 return clang_getNullCursor();
4942
4943 if (index >= clang_getNumOverloadedDecls(cursor))
4944 return clang_getNullCursor();
4945
4946 CXTranslationUnit TU = getCursorTU(cursor);
4947 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004948 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 return MakeCXCursor(E->decls_begin()[index], TU);
4950
4951 if (OverloadedTemplateStorage *S
4952 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4953 return MakeCXCursor(S->begin()[index], TU);
4954
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 const Decl *D = Storage.get<const Decl *>();
4956 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 // FIXME: This is, unfortunately, linear time.
4958 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4959 std::advance(Pos, index);
4960 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4961 }
4962
4963 return clang_getNullCursor();
4964}
4965
4966void clang_getDefinitionSpellingAndExtent(CXCursor C,
4967 const char **startBuf,
4968 const char **endBuf,
4969 unsigned *startLine,
4970 unsigned *startColumn,
4971 unsigned *endLine,
4972 unsigned *endColumn) {
4973 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004974 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4976
4977 SourceManager &SM = FD->getASTContext().getSourceManager();
4978 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4979 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4980 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4981 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4982 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4983 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4984}
4985
4986
4987CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4988 unsigned PieceIndex) {
4989 RefNamePieces Pieces;
4990
4991 switch (C.kind) {
4992 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004993 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4995 E->getQualifierLoc().getSourceRange());
4996 break;
4997
4998 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004999 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5001 E->getQualifierLoc().getSourceRange(),
5002 E->getOptionalExplicitTemplateArgs());
5003 break;
5004
5005 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005006 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005008 const Expr *Callee = OCE->getCallee();
5009 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 Callee = ICE->getSubExpr();
5011
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005012 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5014 DRE->getQualifierLoc().getSourceRange());
5015 }
5016 break;
5017
5018 default:
5019 break;
5020 }
5021
5022 if (Pieces.empty()) {
5023 if (PieceIndex == 0)
5024 return clang_getCursorExtent(C);
5025 } else if (PieceIndex < Pieces.size()) {
5026 SourceRange R = Pieces[PieceIndex];
5027 if (R.isValid())
5028 return cxloc::translateSourceRange(getCursorContext(C), R);
5029 }
5030
5031 return clang_getNullRange();
5032}
5033
5034void clang_enableStackTraces(void) {
5035 llvm::sys::PrintStackTraceOnErrorSignal();
5036}
5037
5038void clang_executeOnThread(void (*fn)(void*), void *user_data,
5039 unsigned stack_size) {
5040 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5041}
5042
5043} // end: extern "C"
5044
5045//===----------------------------------------------------------------------===//
5046// Token-based Operations.
5047//===----------------------------------------------------------------------===//
5048
5049/* CXToken layout:
5050 * int_data[0]: a CXTokenKind
5051 * int_data[1]: starting token location
5052 * int_data[2]: token length
5053 * int_data[3]: reserved
5054 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5055 * otherwise unused.
5056 */
5057extern "C" {
5058
5059CXTokenKind clang_getTokenKind(CXToken CXTok) {
5060 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5061}
5062
5063CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5064 switch (clang_getTokenKind(CXTok)) {
5065 case CXToken_Identifier:
5066 case CXToken_Keyword:
5067 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005068 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 ->getNameStart());
5070
5071 case CXToken_Literal: {
5072 // We have stashed the starting pointer in the ptr_data field. Use it.
5073 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005074 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 }
5076
5077 case CXToken_Punctuation:
5078 case CXToken_Comment:
5079 break;
5080 }
5081
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005082 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005083 LOG_BAD_TU(TU);
5084 return cxstring::createEmpty();
5085 }
5086
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 // We have to find the starting buffer pointer the hard way, by
5088 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005089 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005091 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005092
5093 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5094 std::pair<FileID, unsigned> LocInfo
5095 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5096 bool Invalid = false;
5097 StringRef Buffer
5098 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5099 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005100 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005101
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005102 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005103}
5104
5105CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005106 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005107 LOG_BAD_TU(TU);
5108 return clang_getNullLocation();
5109 }
5110
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005111 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 if (!CXXUnit)
5113 return clang_getNullLocation();
5114
5115 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5116 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5117}
5118
5119CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005120 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005121 LOG_BAD_TU(TU);
5122 return clang_getNullRange();
5123 }
5124
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005125 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 if (!CXXUnit)
5127 return clang_getNullRange();
5128
5129 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5130 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5131}
5132
5133static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5134 SmallVectorImpl<CXToken> &CXTokens) {
5135 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5136 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005137 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005139 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005140
5141 // Cannot tokenize across files.
5142 if (BeginLocInfo.first != EndLocInfo.first)
5143 return;
5144
5145 // Create a lexer
5146 bool Invalid = false;
5147 StringRef Buffer
5148 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5149 if (Invalid)
5150 return;
5151
5152 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5153 CXXUnit->getASTContext().getLangOpts(),
5154 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5155 Lex.SetCommentRetentionState(true);
5156
5157 // Lex tokens until we hit the end of the range.
5158 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5159 Token Tok;
5160 bool previousWasAt = false;
5161 do {
5162 // Lex the next token
5163 Lex.LexFromRawLexer(Tok);
5164 if (Tok.is(tok::eof))
5165 break;
5166
5167 // Initialize the CXToken.
5168 CXToken CXTok;
5169
5170 // - Common fields
5171 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5172 CXTok.int_data[2] = Tok.getLength();
5173 CXTok.int_data[3] = 0;
5174
5175 // - Kind-specific fields
5176 if (Tok.isLiteral()) {
5177 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005178 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 } else if (Tok.is(tok::raw_identifier)) {
5180 // Lookup the identifier to determine whether we have a keyword.
5181 IdentifierInfo *II
5182 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5183
5184 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5185 CXTok.int_data[0] = CXToken_Keyword;
5186 }
5187 else {
5188 CXTok.int_data[0] = Tok.is(tok::identifier)
5189 ? CXToken_Identifier
5190 : CXToken_Keyword;
5191 }
5192 CXTok.ptr_data = II;
5193 } else if (Tok.is(tok::comment)) {
5194 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005195 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 } else {
5197 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005198 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 }
5200 CXTokens.push_back(CXTok);
5201 previousWasAt = Tok.is(tok::at);
5202 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5203}
5204
5205void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5206 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005207 LOG_FUNC_SECTION {
5208 *Log << TU << ' ' << Range;
5209 }
5210
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005212 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 if (NumTokens)
5214 *NumTokens = 0;
5215
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005216 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005217 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005218 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005219 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 if (!CXXUnit || !Tokens || !NumTokens)
5223 return;
5224
5225 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5226
5227 SourceRange R = cxloc::translateCXSourceRange(Range);
5228 if (R.isInvalid())
5229 return;
5230
5231 SmallVector<CXToken, 32> CXTokens;
5232 getTokens(CXXUnit, R, CXTokens);
5233
5234 if (CXTokens.empty())
5235 return;
5236
5237 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5238 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5239 *NumTokens = CXTokens.size();
5240}
5241
5242void clang_disposeTokens(CXTranslationUnit TU,
5243 CXToken *Tokens, unsigned NumTokens) {
5244 free(Tokens);
5245}
5246
5247} // end: extern "C"
5248
5249//===----------------------------------------------------------------------===//
5250// Token annotation APIs.
5251//===----------------------------------------------------------------------===//
5252
Guy Benyei11169dd2012-12-18 14:30:41 +00005253static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5254 CXCursor parent,
5255 CXClientData client_data);
5256static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5257 CXClientData client_data);
5258
5259namespace {
5260class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 CXToken *Tokens;
5262 CXCursor *Cursors;
5263 unsigned NumTokens;
5264 unsigned TokIdx;
5265 unsigned PreprocessingTokIdx;
5266 CursorVisitor AnnotateVis;
5267 SourceManager &SrcMgr;
5268 bool HasContextSensitiveKeywords;
5269
5270 struct PostChildrenInfo {
5271 CXCursor Cursor;
5272 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005273 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 unsigned BeforeChildrenTokenIdx;
5275 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005276 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005277
5278 CXToken &getTok(unsigned Idx) {
5279 assert(Idx < NumTokens);
5280 return Tokens[Idx];
5281 }
5282 const CXToken &getTok(unsigned Idx) const {
5283 assert(Idx < NumTokens);
5284 return Tokens[Idx];
5285 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 bool MoreTokens() const { return TokIdx < NumTokens; }
5287 unsigned NextToken() const { return TokIdx; }
5288 void AdvanceToken() { ++TokIdx; }
5289 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005290 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 }
5292 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005293 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 }
5295 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005296 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005297 }
5298
5299 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005300 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 SourceRange);
5302
5303public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005304 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005305 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005306 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005308 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 AnnotateTokensVisitor, this,
5310 /*VisitPreprocessorLast=*/true,
5311 /*VisitIncludedEntities=*/false,
5312 RegionOfInterest,
5313 /*VisitDeclsOnly=*/false,
5314 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005315 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 HasContextSensitiveKeywords(false) { }
5317
5318 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5319 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5320 bool postVisitChildren(CXCursor cursor);
5321 void AnnotateTokens();
5322
5323 /// \brief Determine whether the annotator saw any cursors that have
5324 /// context-sensitive keywords.
5325 bool hasContextSensitiveKeywords() const {
5326 return HasContextSensitiveKeywords;
5327 }
5328
5329 ~AnnotateTokensWorker() {
5330 assert(PostChildrenInfos.empty());
5331 }
5332};
5333}
5334
5335void AnnotateTokensWorker::AnnotateTokens() {
5336 // Walk the AST within the region of interest, annotating tokens
5337 // along the way.
5338 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005339}
Guy Benyei11169dd2012-12-18 14:30:41 +00005340
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005341static inline void updateCursorAnnotation(CXCursor &Cursor,
5342 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005343 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005345 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005346}
5347
5348/// \brief It annotates and advances tokens with a cursor until the comparison
5349//// between the cursor location and the source range is the same as
5350/// \arg compResult.
5351///
5352/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5353/// Pass RangeOverlap to annotate tokens inside a range.
5354void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5355 RangeComparisonResult compResult,
5356 SourceRange range) {
5357 while (MoreTokens()) {
5358 const unsigned I = NextToken();
5359 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005360 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5361 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005362
5363 SourceLocation TokLoc = GetTokenLoc(I);
5364 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005365 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 AdvanceToken();
5367 continue;
5368 }
5369 break;
5370 }
5371}
5372
5373/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005374/// \returns true if it advanced beyond all macro tokens, false otherwise.
5375bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 CXCursor updateC,
5377 RangeComparisonResult compResult,
5378 SourceRange range) {
5379 assert(MoreTokens());
5380 assert(isFunctionMacroToken(NextToken()) &&
5381 "Should be called only for macro arg tokens");
5382
5383 // This works differently than annotateAndAdvanceTokens; because expanded
5384 // macro arguments can have arbitrary translation-unit source order, we do not
5385 // advance the token index one by one until a token fails the range test.
5386 // We only advance once past all of the macro arg tokens if all of them
5387 // pass the range test. If one of them fails we keep the token index pointing
5388 // at the start of the macro arg tokens so that the failing token will be
5389 // annotated by a subsequent annotation try.
5390
5391 bool atLeastOneCompFail = false;
5392
5393 unsigned I = NextToken();
5394 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5395 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5396 if (TokLoc.isFileID())
5397 continue; // not macro arg token, it's parens or comma.
5398 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5399 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5400 Cursors[I] = updateC;
5401 } else
5402 atLeastOneCompFail = true;
5403 }
5404
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005405 if (atLeastOneCompFail)
5406 return false;
5407
5408 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5409 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005410}
5411
5412enum CXChildVisitResult
5413AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 SourceRange cursorRange = getRawCursorExtent(cursor);
5415 if (cursorRange.isInvalid())
5416 return CXChildVisit_Recurse;
5417
5418 if (!HasContextSensitiveKeywords) {
5419 // Objective-C properties can have context-sensitive keywords.
5420 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005421 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5423 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5424 }
5425 // Objective-C methods can have context-sensitive keywords.
5426 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5427 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005428 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5430 if (Method->getObjCDeclQualifier())
5431 HasContextSensitiveKeywords = true;
5432 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005433 for (const auto *P : Method->params()) {
5434 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 HasContextSensitiveKeywords = true;
5436 break;
5437 }
5438 }
5439 }
5440 }
5441 }
5442 // C++ methods can have context-sensitive keywords.
5443 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005444 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5446 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5447 HasContextSensitiveKeywords = true;
5448 }
5449 }
5450 // C++ classes can have context-sensitive keywords.
5451 else if (cursor.kind == CXCursor_StructDecl ||
5452 cursor.kind == CXCursor_ClassDecl ||
5453 cursor.kind == CXCursor_ClassTemplate ||
5454 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005455 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 if (D->hasAttr<FinalAttr>())
5457 HasContextSensitiveKeywords = true;
5458 }
5459 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005460
5461 // Don't override a property annotation with its getter/setter method.
5462 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5463 parent.kind == CXCursor_ObjCPropertyDecl)
5464 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005465
5466 if (clang_isPreprocessing(cursor.kind)) {
5467 // Items in the preprocessing record are kept separate from items in
5468 // declarations, so we keep a separate token index.
5469 unsigned SavedTokIdx = TokIdx;
5470 TokIdx = PreprocessingTokIdx;
5471
5472 // Skip tokens up until we catch up to the beginning of the preprocessing
5473 // entry.
5474 while (MoreTokens()) {
5475 const unsigned I = NextToken();
5476 SourceLocation TokLoc = GetTokenLoc(I);
5477 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5478 case RangeBefore:
5479 AdvanceToken();
5480 continue;
5481 case RangeAfter:
5482 case RangeOverlap:
5483 break;
5484 }
5485 break;
5486 }
5487
5488 // Look at all of the tokens within this range.
5489 while (MoreTokens()) {
5490 const unsigned I = NextToken();
5491 SourceLocation TokLoc = GetTokenLoc(I);
5492 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5493 case RangeBefore:
5494 llvm_unreachable("Infeasible");
5495 case RangeAfter:
5496 break;
5497 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005498 // For macro expansions, just note where the beginning of the macro
5499 // expansion occurs.
5500 if (cursor.kind == CXCursor_MacroExpansion) {
5501 if (TokLoc == cursorRange.getBegin())
5502 Cursors[I] = cursor;
5503 AdvanceToken();
5504 break;
5505 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005506 // We may have already annotated macro names inside macro definitions.
5507 if (Cursors[I].kind != CXCursor_MacroExpansion)
5508 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 continue;
5511 }
5512 break;
5513 }
5514
5515 // Save the preprocessing token index; restore the non-preprocessing
5516 // token index.
5517 PreprocessingTokIdx = TokIdx;
5518 TokIdx = SavedTokIdx;
5519 return CXChildVisit_Recurse;
5520 }
5521
5522 if (cursorRange.isInvalid())
5523 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005524
5525 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 const enum CXCursorKind K = clang_getCursorKind(parent);
5528 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005529 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5530 // Attributes are annotated out-of-order, skip tokens until we reach it.
5531 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 ? clang_getNullCursor() : parent;
5533
5534 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5535
5536 // Avoid having the cursor of an expression "overwrite" the annotation of the
5537 // variable declaration that it belongs to.
5538 // This can happen for C++ constructor expressions whose range generally
5539 // include the variable declaration, e.g.:
5540 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005541 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005542 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005543 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 const unsigned I = NextToken();
5545 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5546 E->getLocStart() == D->getLocation() &&
5547 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005548 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 AdvanceToken();
5550 }
5551 }
5552 }
5553
5554 // Before recursing into the children keep some state that we are going
5555 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5556 // extra work after the child nodes are visited.
5557 // Note that we don't call VisitChildren here to avoid traversing statements
5558 // code-recursively which can blow the stack.
5559
5560 PostChildrenInfo Info;
5561 Info.Cursor = cursor;
5562 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005563 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 Info.BeforeChildrenTokenIdx = NextToken();
5565 PostChildrenInfos.push_back(Info);
5566
5567 return CXChildVisit_Recurse;
5568}
5569
5570bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5571 if (PostChildrenInfos.empty())
5572 return false;
5573 const PostChildrenInfo &Info = PostChildrenInfos.back();
5574 if (!clang_equalCursors(Info.Cursor, cursor))
5575 return false;
5576
5577 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5578 const unsigned AfterChildren = NextToken();
5579 SourceRange cursorRange = Info.CursorRange;
5580
5581 // Scan the tokens that are at the end of the cursor, but are not captured
5582 // but the child cursors.
5583 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5584
5585 // Scan the tokens that are at the beginning of the cursor, but are not
5586 // capture by the child cursors.
5587 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5588 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5589 break;
5590
5591 Cursors[I] = cursor;
5592 }
5593
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005594 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5595 // encountered the attribute cursor.
5596 if (clang_isAttribute(cursor.kind))
5597 TokIdx = Info.BeforeReachingCursorIdx;
5598
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 PostChildrenInfos.pop_back();
5600 return false;
5601}
5602
5603static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5604 CXCursor parent,
5605 CXClientData client_data) {
5606 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5607}
5608
5609static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5610 CXClientData client_data) {
5611 return static_cast<AnnotateTokensWorker*>(client_data)->
5612 postVisitChildren(cursor);
5613}
5614
5615namespace {
5616
5617/// \brief Uses the macro expansions in the preprocessing record to find
5618/// and mark tokens that are macro arguments. This info is used by the
5619/// AnnotateTokensWorker.
5620class MarkMacroArgTokensVisitor {
5621 SourceManager &SM;
5622 CXToken *Tokens;
5623 unsigned NumTokens;
5624 unsigned CurIdx;
5625
5626public:
5627 MarkMacroArgTokensVisitor(SourceManager &SM,
5628 CXToken *tokens, unsigned numTokens)
5629 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5630
5631 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5632 if (cursor.kind != CXCursor_MacroExpansion)
5633 return CXChildVisit_Continue;
5634
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005635 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 if (macroRange.getBegin() == macroRange.getEnd())
5637 return CXChildVisit_Continue; // it's not a function macro.
5638
5639 for (; CurIdx < NumTokens; ++CurIdx) {
5640 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5641 macroRange.getBegin()))
5642 break;
5643 }
5644
5645 if (CurIdx == NumTokens)
5646 return CXChildVisit_Break;
5647
5648 for (; CurIdx < NumTokens; ++CurIdx) {
5649 SourceLocation tokLoc = getTokenLoc(CurIdx);
5650 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5651 break;
5652
5653 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5654 }
5655
5656 if (CurIdx == NumTokens)
5657 return CXChildVisit_Break;
5658
5659 return CXChildVisit_Continue;
5660 }
5661
5662private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005663 CXToken &getTok(unsigned Idx) {
5664 assert(Idx < NumTokens);
5665 return Tokens[Idx];
5666 }
5667 const CXToken &getTok(unsigned Idx) const {
5668 assert(Idx < NumTokens);
5669 return Tokens[Idx];
5670 }
5671
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005673 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 }
5675
5676 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5677 // The third field is reserved and currently not used. Use it here
5678 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005679 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 }
5681};
5682
5683} // end anonymous namespace
5684
5685static CXChildVisitResult
5686MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5687 CXClientData client_data) {
5688 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5689 parent);
5690}
5691
5692namespace {
5693 struct clang_annotateTokens_Data {
5694 CXTranslationUnit TU;
5695 ASTUnit *CXXUnit;
5696 CXToken *Tokens;
5697 unsigned NumTokens;
5698 CXCursor *Cursors;
5699 };
5700}
5701
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005702/// \brief Used by \c annotatePreprocessorTokens.
5703/// \returns true if lexing was finished, false otherwise.
5704static bool lexNext(Lexer &Lex, Token &Tok,
5705 unsigned &NextIdx, unsigned NumTokens) {
5706 if (NextIdx >= NumTokens)
5707 return true;
5708
5709 ++NextIdx;
5710 Lex.LexFromRawLexer(Tok);
5711 if (Tok.is(tok::eof))
5712 return true;
5713
5714 return false;
5715}
5716
Guy Benyei11169dd2012-12-18 14:30:41 +00005717static void annotatePreprocessorTokens(CXTranslationUnit TU,
5718 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005719 CXCursor *Cursors,
5720 CXToken *Tokens,
5721 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005722 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005723
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005724 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5726 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005727 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005729 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005730
5731 if (BeginLocInfo.first != EndLocInfo.first)
5732 return;
5733
5734 StringRef Buffer;
5735 bool Invalid = false;
5736 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5737 if (Buffer.empty() || Invalid)
5738 return;
5739
5740 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5741 CXXUnit->getASTContext().getLangOpts(),
5742 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5743 Buffer.end());
5744 Lex.SetCommentRetentionState(true);
5745
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005746 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 // Lex tokens in raw mode until we hit the end of the range, to avoid
5748 // entering #includes or expanding macros.
5749 while (true) {
5750 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5752 break;
5753 unsigned TokIdx = NextIdx-1;
5754 assert(Tok.getLocation() ==
5755 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005756
5757 reprocess:
5758 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005759 // We have found a preprocessing directive. Annotate the tokens
5760 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 //
5762 // FIXME: Some simple tests here could identify macro definitions and
5763 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005764
5765 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005766 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5767 break;
5768
Craig Topper69186e72014-06-08 08:38:04 +00005769 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005770 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005771 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5772 break;
5773
5774 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005775 IdentifierInfo &II =
5776 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005777 SourceLocation MappedTokLoc =
5778 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5779 MI = getMacroInfo(II, MappedTokLoc, TU);
5780 }
5781 }
5782
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005783 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005785 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5786 finished = true;
5787 break;
5788 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005789 // If we are in a macro definition, check if the token was ever a
5790 // macro name and annotate it if that's the case.
5791 if (MI) {
5792 SourceLocation SaveLoc = Tok.getLocation();
5793 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5794 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5795 Tok.setLocation(SaveLoc);
5796 if (MacroDef)
5797 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5798 Tok.getLocation(), TU);
5799 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005800 } while (!Tok.isAtStartOfLine());
5801
5802 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5803 assert(TokIdx <= LastIdx);
5804 SourceLocation EndLoc =
5805 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5806 CXCursor Cursor =
5807 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5808
5809 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005810 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005811
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005812 if (finished)
5813 break;
5814 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 }
5817}
5818
5819// This gets run a separate thread to avoid stack blowout.
5820static void clang_annotateTokensImpl(void *UserData) {
5821 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5822 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5823 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5824 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5825 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5826
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005827 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5829 setThreadBackgroundPriority();
5830
5831 // Determine the region of interest, which contains all of the tokens.
5832 SourceRange RegionOfInterest;
5833 RegionOfInterest.setBegin(
5834 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5835 RegionOfInterest.setEnd(
5836 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5837 Tokens[NumTokens-1])));
5838
Guy Benyei11169dd2012-12-18 14:30:41 +00005839 // Relex the tokens within the source range to look for preprocessing
5840 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005841 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005842
5843 // If begin location points inside a macro argument, set it to the expansion
5844 // location so we can have the full context when annotating semantically.
5845 {
5846 SourceManager &SM = CXXUnit->getSourceManager();
5847 SourceLocation Loc =
5848 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5849 if (Loc.isMacroID())
5850 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5851 }
5852
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5854 // Search and mark tokens that are macro argument expansions.
5855 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5856 Tokens, NumTokens);
5857 CursorVisitor MacroArgMarker(TU,
5858 MarkMacroArgTokensVisitorDelegate, &Visitor,
5859 /*VisitPreprocessorLast=*/true,
5860 /*VisitIncludedEntities=*/false,
5861 RegionOfInterest);
5862 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5863 }
5864
5865 // Annotate all of the source locations in the region of interest that map to
5866 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005867 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005868
5869 // FIXME: We use a ridiculous stack size here because the data-recursion
5870 // algorithm uses a large stack frame than the non-data recursive version,
5871 // and AnnotationTokensWorker currently transforms the data-recursion
5872 // algorithm back into a traditional recursion by explicitly calling
5873 // VisitChildren(). We will need to remove this explicit recursive call.
5874 W.AnnotateTokens();
5875
5876 // If we ran into any entities that involve context-sensitive keywords,
5877 // take another pass through the tokens to mark them as such.
5878 if (W.hasContextSensitiveKeywords()) {
5879 for (unsigned I = 0; I != NumTokens; ++I) {
5880 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5881 continue;
5882
5883 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5884 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005885 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005886 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5887 if (Property->getPropertyAttributesAsWritten() != 0 &&
5888 llvm::StringSwitch<bool>(II->getName())
5889 .Case("readonly", true)
5890 .Case("assign", true)
5891 .Case("unsafe_unretained", true)
5892 .Case("readwrite", true)
5893 .Case("retain", true)
5894 .Case("copy", true)
5895 .Case("nonatomic", true)
5896 .Case("atomic", true)
5897 .Case("getter", true)
5898 .Case("setter", true)
5899 .Case("strong", true)
5900 .Case("weak", true)
5901 .Default(false))
5902 Tokens[I].int_data[0] = CXToken_Keyword;
5903 }
5904 continue;
5905 }
5906
5907 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5908 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5909 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5910 if (llvm::StringSwitch<bool>(II->getName())
5911 .Case("in", true)
5912 .Case("out", true)
5913 .Case("inout", true)
5914 .Case("oneway", true)
5915 .Case("bycopy", true)
5916 .Case("byref", true)
5917 .Default(false))
5918 Tokens[I].int_data[0] = CXToken_Keyword;
5919 continue;
5920 }
5921
5922 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5923 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5924 Tokens[I].int_data[0] = CXToken_Keyword;
5925 continue;
5926 }
5927 }
5928 }
5929}
5930
5931extern "C" {
5932
5933void clang_annotateTokens(CXTranslationUnit TU,
5934 CXToken *Tokens, unsigned NumTokens,
5935 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005936 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005937 LOG_BAD_TU(TU);
5938 return;
5939 }
5940 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005941 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005943 }
5944
5945 LOG_FUNC_SECTION {
5946 *Log << TU << ' ';
5947 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5948 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5949 *Log << clang_getRange(bloc, eloc);
5950 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005951
5952 // Any token we don't specifically annotate will have a NULL cursor.
5953 CXCursor C = clang_getNullCursor();
5954 for (unsigned I = 0; I != NumTokens; ++I)
5955 Cursors[I] = C;
5956
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005957 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 if (!CXXUnit)
5959 return;
5960
5961 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5962
5963 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5964 llvm::CrashRecoveryContext CRC;
5965 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5966 GetSafetyThreadStackSize() * 2)) {
5967 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5968 }
5969}
5970
5971} // end: extern "C"
5972
5973//===----------------------------------------------------------------------===//
5974// Operations for querying linkage of a cursor.
5975//===----------------------------------------------------------------------===//
5976
5977extern "C" {
5978CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5979 if (!clang_isDeclaration(cursor.kind))
5980 return CXLinkage_Invalid;
5981
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005982 const Decl *D = cxcursor::getCursorDecl(cursor);
5983 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005984 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005985 case NoLinkage:
5986 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005987 case InternalLinkage: return CXLinkage_Internal;
5988 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5989 case ExternalLinkage: return CXLinkage_External;
5990 };
5991
5992 return CXLinkage_Invalid;
5993}
5994} // end: extern "C"
5995
5996//===----------------------------------------------------------------------===//
5997// Operations for querying language of a cursor.
5998//===----------------------------------------------------------------------===//
5999
6000static CXLanguageKind getDeclLanguage(const Decl *D) {
6001 if (!D)
6002 return CXLanguage_C;
6003
6004 switch (D->getKind()) {
6005 default:
6006 break;
6007 case Decl::ImplicitParam:
6008 case Decl::ObjCAtDefsField:
6009 case Decl::ObjCCategory:
6010 case Decl::ObjCCategoryImpl:
6011 case Decl::ObjCCompatibleAlias:
6012 case Decl::ObjCImplementation:
6013 case Decl::ObjCInterface:
6014 case Decl::ObjCIvar:
6015 case Decl::ObjCMethod:
6016 case Decl::ObjCProperty:
6017 case Decl::ObjCPropertyImpl:
6018 case Decl::ObjCProtocol:
6019 return CXLanguage_ObjC;
6020 case Decl::CXXConstructor:
6021 case Decl::CXXConversion:
6022 case Decl::CXXDestructor:
6023 case Decl::CXXMethod:
6024 case Decl::CXXRecord:
6025 case Decl::ClassTemplate:
6026 case Decl::ClassTemplatePartialSpecialization:
6027 case Decl::ClassTemplateSpecialization:
6028 case Decl::Friend:
6029 case Decl::FriendTemplate:
6030 case Decl::FunctionTemplate:
6031 case Decl::LinkageSpec:
6032 case Decl::Namespace:
6033 case Decl::NamespaceAlias:
6034 case Decl::NonTypeTemplateParm:
6035 case Decl::StaticAssert:
6036 case Decl::TemplateTemplateParm:
6037 case Decl::TemplateTypeParm:
6038 case Decl::UnresolvedUsingTypename:
6039 case Decl::UnresolvedUsingValue:
6040 case Decl::Using:
6041 case Decl::UsingDirective:
6042 case Decl::UsingShadow:
6043 return CXLanguage_CPlusPlus;
6044 }
6045
6046 return CXLanguage_C;
6047}
6048
6049extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006050
6051static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6052 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6053 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006054
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006055 switch (D->getAvailability()) {
6056 case AR_Available:
6057 case AR_NotYetIntroduced:
6058 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006059 return getCursorAvailabilityForDecl(
6060 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006061 return CXAvailability_Available;
6062
6063 case AR_Deprecated:
6064 return CXAvailability_Deprecated;
6065
6066 case AR_Unavailable:
6067 return CXAvailability_NotAvailable;
6068 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006069
6070 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006071}
6072
Guy Benyei11169dd2012-12-18 14:30:41 +00006073enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6074 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006075 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6076 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006077
6078 return CXAvailability_Available;
6079}
6080
6081static CXVersion convertVersion(VersionTuple In) {
6082 CXVersion Out = { -1, -1, -1 };
6083 if (In.empty())
6084 return Out;
6085
6086 Out.Major = In.getMajor();
6087
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006088 Optional<unsigned> Minor = In.getMinor();
6089 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 Out.Minor = *Minor;
6091 else
6092 return Out;
6093
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006094 Optional<unsigned> Subminor = In.getSubminor();
6095 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 Out.Subminor = *Subminor;
6097
6098 return Out;
6099}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006100
6101static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6102 int *always_deprecated,
6103 CXString *deprecated_message,
6104 int *always_unavailable,
6105 CXString *unavailable_message,
6106 CXPlatformAvailability *availability,
6107 int availability_size) {
6108 bool HadAvailAttr = false;
6109 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006110 for (auto A : D->attrs()) {
6111 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006112 HadAvailAttr = true;
6113 if (always_deprecated)
6114 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006115 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006116 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006117 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006118 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006119 continue;
6120 }
6121
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006122 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006123 HadAvailAttr = true;
6124 if (always_unavailable)
6125 *always_unavailable = 1;
6126 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006127 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006128 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6129 }
6130 continue;
6131 }
6132
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006133 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006134 HadAvailAttr = true;
6135 if (N < availability_size) {
6136 availability[N].Platform
6137 = cxstring::createDup(Avail->getPlatform()->getName());
6138 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6139 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6140 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6141 availability[N].Unavailable = Avail->getUnavailable();
6142 availability[N].Message = cxstring::createDup(Avail->getMessage());
6143 }
6144 ++N;
6145 }
6146 }
6147
6148 if (!HadAvailAttr)
6149 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6150 return getCursorPlatformAvailabilityForDecl(
6151 cast<Decl>(EnumConst->getDeclContext()),
6152 always_deprecated,
6153 deprecated_message,
6154 always_unavailable,
6155 unavailable_message,
6156 availability,
6157 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006158
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006159 return N;
6160}
6161
Guy Benyei11169dd2012-12-18 14:30:41 +00006162int clang_getCursorPlatformAvailability(CXCursor cursor,
6163 int *always_deprecated,
6164 CXString *deprecated_message,
6165 int *always_unavailable,
6166 CXString *unavailable_message,
6167 CXPlatformAvailability *availability,
6168 int availability_size) {
6169 if (always_deprecated)
6170 *always_deprecated = 0;
6171 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006172 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 if (always_unavailable)
6174 *always_unavailable = 0;
6175 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006176 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006177
Guy Benyei11169dd2012-12-18 14:30:41 +00006178 if (!clang_isDeclaration(cursor.kind))
6179 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006181 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 if (!D)
6183 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006184
6185 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6186 deprecated_message,
6187 always_unavailable,
6188 unavailable_message,
6189 availability,
6190 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006191}
6192
6193void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6194 clang_disposeString(availability->Platform);
6195 clang_disposeString(availability->Message);
6196}
6197
6198CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6199 if (clang_isDeclaration(cursor.kind))
6200 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6201
6202 return CXLanguage_Invalid;
6203}
6204
6205 /// \brief If the given cursor is the "templated" declaration
6206 /// descibing a class or function template, return the class or
6207 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006208static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006209 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006210 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006211
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006212 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6214 return FunTmpl;
6215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6218 return ClassTmpl;
6219
6220 return D;
6221}
6222
6223CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6224 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006225 if (const Decl *D = getCursorDecl(cursor)) {
6226 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 if (!DC)
6228 return clang_getNullCursor();
6229
6230 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6231 getCursorTU(cursor));
6232 }
6233 }
6234
6235 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006236 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006237 return MakeCXCursor(D, getCursorTU(cursor));
6238 }
6239
6240 return clang_getNullCursor();
6241}
6242
6243CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6244 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006245 if (const Decl *D = getCursorDecl(cursor)) {
6246 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006247 if (!DC)
6248 return clang_getNullCursor();
6249
6250 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6251 getCursorTU(cursor));
6252 }
6253 }
6254
6255 // FIXME: Note that we can't easily compute the lexical context of a
6256 // statement or expression, so we return nothing.
6257 return clang_getNullCursor();
6258}
6259
6260CXFile clang_getIncludedFile(CXCursor cursor) {
6261 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006262 return nullptr;
6263
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006264 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006265 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006266}
6267
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006268unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6269 if (C.kind != CXCursor_ObjCPropertyDecl)
6270 return CXObjCPropertyAttr_noattr;
6271
6272 unsigned Result = CXObjCPropertyAttr_noattr;
6273 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6274 ObjCPropertyDecl::PropertyAttributeKind Attr =
6275 PD->getPropertyAttributesAsWritten();
6276
6277#define SET_CXOBJCPROP_ATTR(A) \
6278 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6279 Result |= CXObjCPropertyAttr_##A
6280 SET_CXOBJCPROP_ATTR(readonly);
6281 SET_CXOBJCPROP_ATTR(getter);
6282 SET_CXOBJCPROP_ATTR(assign);
6283 SET_CXOBJCPROP_ATTR(readwrite);
6284 SET_CXOBJCPROP_ATTR(retain);
6285 SET_CXOBJCPROP_ATTR(copy);
6286 SET_CXOBJCPROP_ATTR(nonatomic);
6287 SET_CXOBJCPROP_ATTR(setter);
6288 SET_CXOBJCPROP_ATTR(atomic);
6289 SET_CXOBJCPROP_ATTR(weak);
6290 SET_CXOBJCPROP_ATTR(strong);
6291 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6292#undef SET_CXOBJCPROP_ATTR
6293
6294 return Result;
6295}
6296
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006297unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6298 if (!clang_isDeclaration(C.kind))
6299 return CXObjCDeclQualifier_None;
6300
6301 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6302 const Decl *D = getCursorDecl(C);
6303 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6304 QT = MD->getObjCDeclQualifier();
6305 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6306 QT = PD->getObjCDeclQualifier();
6307 if (QT == Decl::OBJC_TQ_None)
6308 return CXObjCDeclQualifier_None;
6309
6310 unsigned Result = CXObjCDeclQualifier_None;
6311 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6312 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6313 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6314 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6315 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6316 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6317
6318 return Result;
6319}
6320
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006321unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6322 if (!clang_isDeclaration(C.kind))
6323 return 0;
6324
6325 const Decl *D = getCursorDecl(C);
6326 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6327 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6328 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6329 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6330
6331 return 0;
6332}
6333
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006334unsigned clang_Cursor_isVariadic(CXCursor C) {
6335 if (!clang_isDeclaration(C.kind))
6336 return 0;
6337
6338 const Decl *D = getCursorDecl(C);
6339 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6340 return FD->isVariadic();
6341 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6342 return MD->isVariadic();
6343
6344 return 0;
6345}
6346
Guy Benyei11169dd2012-12-18 14:30:41 +00006347CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6348 if (!clang_isDeclaration(C.kind))
6349 return clang_getNullRange();
6350
6351 const Decl *D = getCursorDecl(C);
6352 ASTContext &Context = getCursorContext(C);
6353 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6354 if (!RC)
6355 return clang_getNullRange();
6356
6357 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6358}
6359
6360CXString clang_Cursor_getRawCommentText(CXCursor C) {
6361 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006362 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006363
6364 const Decl *D = getCursorDecl(C);
6365 ASTContext &Context = getCursorContext(C);
6366 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6367 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6368 StringRef();
6369
6370 // Don't duplicate the string because RawText points directly into source
6371 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006372 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006373}
6374
6375CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6376 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006377 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006378
6379 const Decl *D = getCursorDecl(C);
6380 const ASTContext &Context = getCursorContext(C);
6381 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6382
6383 if (RC) {
6384 StringRef BriefText = RC->getBriefText(Context);
6385
6386 // Don't duplicate the string because RawComment ensures that this memory
6387 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006388 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006389 }
6390
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006391 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006392}
6393
Guy Benyei11169dd2012-12-18 14:30:41 +00006394CXModule clang_Cursor_getModule(CXCursor C) {
6395 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006396 if (const ImportDecl *ImportD =
6397 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006398 return ImportD->getImportedModule();
6399 }
6400
Craig Topper69186e72014-06-08 08:38:04 +00006401 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006402}
6403
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006404CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6405 if (isNotUsableTU(TU)) {
6406 LOG_BAD_TU(TU);
6407 return nullptr;
6408 }
6409 if (!File)
6410 return nullptr;
6411 FileEntry *FE = static_cast<FileEntry *>(File);
6412
6413 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6414 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6415 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6416
6417 if (Module *Mod = Header.getModule()) {
6418 if (Header.getRole() != ModuleMap::ExcludedHeader)
6419 return Mod;
6420 }
6421 return nullptr;
6422}
6423
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006424CXFile clang_Module_getASTFile(CXModule CXMod) {
6425 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006426 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006427 Module *Mod = static_cast<Module*>(CXMod);
6428 return const_cast<FileEntry *>(Mod->getASTFile());
6429}
6430
Guy Benyei11169dd2012-12-18 14:30:41 +00006431CXModule clang_Module_getParent(CXModule CXMod) {
6432 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006433 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 Module *Mod = static_cast<Module*>(CXMod);
6435 return Mod->Parent;
6436}
6437
6438CXString clang_Module_getName(CXModule CXMod) {
6439 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006440 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006441 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006442 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006443}
6444
6445CXString clang_Module_getFullName(CXModule CXMod) {
6446 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006447 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006449 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006450}
6451
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006452int clang_Module_isSystem(CXModule CXMod) {
6453 if (!CXMod)
6454 return 0;
6455 Module *Mod = static_cast<Module*>(CXMod);
6456 return Mod->IsSystem;
6457}
6458
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006459unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6460 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006461 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006462 LOG_BAD_TU(TU);
6463 return 0;
6464 }
6465 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006466 return 0;
6467 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006468 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6469 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6470 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006471}
6472
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006473CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6474 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006475 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006476 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006477 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006478 }
6479 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006480 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006481 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006482 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006483
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006484 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6485 if (Index < TopHeaders.size())
6486 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006487
Craig Topper69186e72014-06-08 08:38:04 +00006488 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006489}
6490
6491} // end: extern "C"
6492
6493//===----------------------------------------------------------------------===//
6494// C++ AST instrospection.
6495//===----------------------------------------------------------------------===//
6496
6497extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006498unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6499 if (!clang_isDeclaration(C.kind))
6500 return 0;
6501
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006502 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006503 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006504 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006505 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6506}
6507
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006508unsigned clang_CXXMethod_isConst(CXCursor C) {
6509 if (!clang_isDeclaration(C.kind))
6510 return 0;
6511
6512 const Decl *D = cxcursor::getCursorDecl(C);
6513 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006514 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006515 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6516}
6517
Guy Benyei11169dd2012-12-18 14:30:41 +00006518unsigned clang_CXXMethod_isStatic(CXCursor C) {
6519 if (!clang_isDeclaration(C.kind))
6520 return 0;
6521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006522 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006523 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006524 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006525 return (Method && Method->isStatic()) ? 1 : 0;
6526}
6527
6528unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6529 if (!clang_isDeclaration(C.kind))
6530 return 0;
6531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006532 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006533 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006534 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 return (Method && Method->isVirtual()) ? 1 : 0;
6536}
6537} // end: extern "C"
6538
6539//===----------------------------------------------------------------------===//
6540// Attribute introspection.
6541//===----------------------------------------------------------------------===//
6542
6543extern "C" {
6544CXType clang_getIBOutletCollectionType(CXCursor C) {
6545 if (C.kind != CXCursor_IBOutletCollectionAttr)
6546 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6547
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006548 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006549 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6550
6551 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6552}
6553} // end: extern "C"
6554
6555//===----------------------------------------------------------------------===//
6556// Inspecting memory usage.
6557//===----------------------------------------------------------------------===//
6558
6559typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6560
6561static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6562 enum CXTUResourceUsageKind k,
6563 unsigned long amount) {
6564 CXTUResourceUsageEntry entry = { k, amount };
6565 entries.push_back(entry);
6566}
6567
6568extern "C" {
6569
6570const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6571 const char *str = "";
6572 switch (kind) {
6573 case CXTUResourceUsage_AST:
6574 str = "ASTContext: expressions, declarations, and types";
6575 break;
6576 case CXTUResourceUsage_Identifiers:
6577 str = "ASTContext: identifiers";
6578 break;
6579 case CXTUResourceUsage_Selectors:
6580 str = "ASTContext: selectors";
6581 break;
6582 case CXTUResourceUsage_GlobalCompletionResults:
6583 str = "Code completion: cached global results";
6584 break;
6585 case CXTUResourceUsage_SourceManagerContentCache:
6586 str = "SourceManager: content cache allocator";
6587 break;
6588 case CXTUResourceUsage_AST_SideTables:
6589 str = "ASTContext: side tables";
6590 break;
6591 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6592 str = "SourceManager: malloc'ed memory buffers";
6593 break;
6594 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6595 str = "SourceManager: mmap'ed memory buffers";
6596 break;
6597 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6598 str = "ExternalASTSource: malloc'ed memory buffers";
6599 break;
6600 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6601 str = "ExternalASTSource: mmap'ed memory buffers";
6602 break;
6603 case CXTUResourceUsage_Preprocessor:
6604 str = "Preprocessor: malloc'ed memory";
6605 break;
6606 case CXTUResourceUsage_PreprocessingRecord:
6607 str = "Preprocessor: PreprocessingRecord";
6608 break;
6609 case CXTUResourceUsage_SourceManager_DataStructures:
6610 str = "SourceManager: data structures and tables";
6611 break;
6612 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6613 str = "Preprocessor: header search tables";
6614 break;
6615 }
6616 return str;
6617}
6618
6619CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006620 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006621 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006622 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 return usage;
6624 }
6625
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006626 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006627 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 ASTContext &astContext = astUnit->getASTContext();
6629
6630 // How much memory is used by AST nodes and types?
6631 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6632 (unsigned long) astContext.getASTAllocatedMemory());
6633
6634 // How much memory is used by identifiers?
6635 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6636 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6637
6638 // How much memory is used for selectors?
6639 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6640 (unsigned long) astContext.Selectors.getTotalMemory());
6641
6642 // How much memory is used by ASTContext's side tables?
6643 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6644 (unsigned long) astContext.getSideTableAllocatedMemory());
6645
6646 // How much memory is used for caching global code completion results?
6647 unsigned long completionBytes = 0;
6648 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006649 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006650 completionBytes = completionAllocator->getTotalMemory();
6651 }
6652 createCXTUResourceUsageEntry(*entries,
6653 CXTUResourceUsage_GlobalCompletionResults,
6654 completionBytes);
6655
6656 // How much memory is being used by SourceManager's content cache?
6657 createCXTUResourceUsageEntry(*entries,
6658 CXTUResourceUsage_SourceManagerContentCache,
6659 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6660
6661 // How much memory is being used by the MemoryBuffer's in SourceManager?
6662 const SourceManager::MemoryBufferSizes &srcBufs =
6663 astUnit->getSourceManager().getMemoryBufferSizes();
6664
6665 createCXTUResourceUsageEntry(*entries,
6666 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6667 (unsigned long) srcBufs.malloc_bytes);
6668 createCXTUResourceUsageEntry(*entries,
6669 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6670 (unsigned long) srcBufs.mmap_bytes);
6671 createCXTUResourceUsageEntry(*entries,
6672 CXTUResourceUsage_SourceManager_DataStructures,
6673 (unsigned long) astContext.getSourceManager()
6674 .getDataStructureSizes());
6675
6676 // How much memory is being used by the ExternalASTSource?
6677 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6678 const ExternalASTSource::MemoryBufferSizes &sizes =
6679 esrc->getMemoryBufferSizes();
6680
6681 createCXTUResourceUsageEntry(*entries,
6682 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6683 (unsigned long) sizes.malloc_bytes);
6684 createCXTUResourceUsageEntry(*entries,
6685 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6686 (unsigned long) sizes.mmap_bytes);
6687 }
6688
6689 // How much memory is being used by the Preprocessor?
6690 Preprocessor &pp = astUnit->getPreprocessor();
6691 createCXTUResourceUsageEntry(*entries,
6692 CXTUResourceUsage_Preprocessor,
6693 pp.getTotalMemory());
6694
6695 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6696 createCXTUResourceUsageEntry(*entries,
6697 CXTUResourceUsage_PreprocessingRecord,
6698 pRec->getTotalMemory());
6699 }
6700
6701 createCXTUResourceUsageEntry(*entries,
6702 CXTUResourceUsage_Preprocessor_HeaderSearch,
6703 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006704
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 CXTUResourceUsage usage = { (void*) entries.get(),
6706 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006707 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006708 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 return usage;
6710}
6711
6712void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6713 if (usage.data)
6714 delete (MemUsageEntries*) usage.data;
6715}
6716
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006717CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6718 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006719 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006720 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006721
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006722 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006723 LOG_BAD_TU(TU);
6724 return skipped;
6725 }
6726
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006727 if (!file)
6728 return skipped;
6729
6730 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6731 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6732 if (!ppRec)
6733 return skipped;
6734
6735 ASTContext &Ctx = astUnit->getASTContext();
6736 SourceManager &sm = Ctx.getSourceManager();
6737 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6738 FileID wantedFileID = sm.translateFile(fileEntry);
6739
6740 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6741 std::vector<SourceRange> wantedRanges;
6742 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6743 i != ei; ++i) {
6744 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6745 wantedRanges.push_back(*i);
6746 }
6747
6748 skipped->count = wantedRanges.size();
6749 skipped->ranges = new CXSourceRange[skipped->count];
6750 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6751 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6752
6753 return skipped;
6754}
6755
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006756void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6757 if (ranges) {
6758 delete[] ranges->ranges;
6759 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006760 }
6761}
6762
Guy Benyei11169dd2012-12-18 14:30:41 +00006763} // end extern "C"
6764
6765void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6766 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6767 for (unsigned I = 0; I != Usage.numEntries; ++I)
6768 fprintf(stderr, " %s: %lu\n",
6769 clang_getTUResourceUsageName(Usage.entries[I].kind),
6770 Usage.entries[I].amount);
6771
6772 clang_disposeCXTUResourceUsage(Usage);
6773}
6774
6775//===----------------------------------------------------------------------===//
6776// Misc. utility functions.
6777//===----------------------------------------------------------------------===//
6778
6779/// Default to using an 8 MB stack size on "safety" threads.
6780static unsigned SafetyStackThreadSize = 8 << 20;
6781
6782namespace clang {
6783
6784bool RunSafely(llvm::CrashRecoveryContext &CRC,
6785 void (*Fn)(void*), void *UserData,
6786 unsigned Size) {
6787 if (!Size)
6788 Size = GetSafetyThreadStackSize();
6789 if (Size)
6790 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6791 return CRC.RunSafely(Fn, UserData);
6792}
6793
6794unsigned GetSafetyThreadStackSize() {
6795 return SafetyStackThreadSize;
6796}
6797
6798void SetSafetyThreadStackSize(unsigned Value) {
6799 SafetyStackThreadSize = Value;
6800}
6801
6802}
6803
6804void clang::setThreadBackgroundPriority() {
6805 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6806 return;
6807
Alp Toker1a86ad22014-07-06 06:24:00 +00006808#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006809 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6810#endif
6811}
6812
6813void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6814 if (!Unit)
6815 return;
6816
6817 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6818 DEnd = Unit->stored_diag_end();
6819 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006820 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006821 CXString Msg = clang_formatDiagnostic(&Diag,
6822 clang_defaultDiagnosticDisplayOptions());
6823 fprintf(stderr, "%s\n", clang_getCString(Msg));
6824 clang_disposeString(Msg);
6825 }
6826#ifdef LLVM_ON_WIN32
6827 // On Windows, force a flush, since there may be multiple copies of
6828 // stderr and stdout in the file system, all with different buffers
6829 // but writing to the same device.
6830 fflush(stderr);
6831#endif
6832}
6833
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6835 SourceLocation MacroDefLoc,
6836 CXTranslationUnit TU){
6837 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006838 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006839 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006841
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006842 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006843 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006844 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006845 if (MD) {
6846 for (MacroDirective::DefInfo
6847 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6848 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6849 return Def.getMacroInfo();
6850 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851 }
6852
Craig Topper69186e72014-06-08 08:38:04 +00006853 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854}
6855
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006856const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6857 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006860 const IdentifierInfo *II = MacroDef->getName();
6861 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006862 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006863
6864 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6865}
6866
6867MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6868 const Token &Tok,
6869 CXTranslationUnit TU) {
6870 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006871 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006872 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006874
6875 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006876 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6878 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006879 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006880
6881 // Check that the token is inside the definition and not its argument list.
6882 SourceManager &SM = Unit->getSourceManager();
6883 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006884 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006885 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006886 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006887
6888 Preprocessor &PP = Unit->getPreprocessor();
6889 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6890 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006892
Alp Toker2d57cea2014-05-17 04:53:25 +00006893 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006894 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006895 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006896
6897 // Check that the identifier is not one of the macro arguments.
6898 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006899 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006900
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006901 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6902 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006903 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006904
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006905 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006906}
6907
6908MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6909 SourceLocation Loc,
6910 CXTranslationUnit TU) {
6911 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006912 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006913
6914 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006915 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006916 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006917 Preprocessor &PP = Unit->getPreprocessor();
6918 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006919 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006920 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6921 Token Tok;
6922 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006923 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006924
6925 return checkForMacroInMacroDefinition(MI, Tok, TU);
6926}
6927
Guy Benyei11169dd2012-12-18 14:30:41 +00006928extern "C" {
6929
6930CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006931 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006932}
6933
6934} // end: extern "C"
6935
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006936Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6937 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006938 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006939 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006940 if (Unit->isMainFileAST())
6941 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006942 return *this;
6943 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006944 } else {
6945 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006946 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006947 return *this;
6948}
6949
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006950Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6951 *this << FE->getName();
6952 return *this;
6953}
6954
6955Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6956 CXString cursorName = clang_getCursorDisplayName(cursor);
6957 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6958 clang_disposeString(cursorName);
6959 return *this;
6960}
6961
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006962Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6963 CXFile File;
6964 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006965 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006966 CXString FileName = clang_getFileName(File);
6967 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6968 clang_disposeString(FileName);
6969 return *this;
6970}
6971
6972Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6973 CXSourceLocation BLoc = clang_getRangeStart(range);
6974 CXSourceLocation ELoc = clang_getRangeEnd(range);
6975
6976 CXFile BFile;
6977 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006978 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006979
6980 CXFile EFile;
6981 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006982 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006983
6984 CXString BFileName = clang_getFileName(BFile);
6985 if (BFile == EFile) {
6986 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6987 BLine, BColumn, ELine, EColumn);
6988 } else {
6989 CXString EFileName = clang_getFileName(EFile);
6990 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6991 BLine, BColumn)
6992 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6993 ELine, EColumn);
6994 clang_disposeString(EFileName);
6995 }
6996 clang_disposeString(BFileName);
6997 return *this;
6998}
6999
7000Logger &cxindex::Logger::operator<<(CXString Str) {
7001 *this << clang_getCString(Str);
7002 return *this;
7003}
7004
7005Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7006 LogOS << Fmt;
7007 return *this;
7008}
7009
Chandler Carruth37ad2582014-06-27 15:14:39 +00007010static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7011
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007012cxindex::Logger::~Logger() {
7013 LogOS.flush();
7014
Chandler Carruth37ad2582014-06-27 15:14:39 +00007015 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007016
7017 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7018
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007019 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007020 OS << "[libclang:" << Name << ':';
7021
Alp Toker1a86ad22014-07-06 06:24:00 +00007022#ifdef USE_DARWIN_THREADS
7023 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007024 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7025 OS << tid << ':';
7026#endif
7027
7028 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7029 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7030 OS << Msg.str() << '\n';
7031
7032 if (Trace) {
7033 llvm::sys::PrintStackTrace(stderr);
7034 OS << "--------------------------------------------------\n";
7035 }
7036}