blob: 06f2d472ce5f9d7d12686674e5e6895bf051b63a [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;
Alp Toker9d85b182014-07-07 01:23:14 +00002730 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002731 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002732 CXTranslationUnit *out_TU;
Alp Toker9d85b182014-07-07 01:23:14 +00002733 mutable CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002734};
2735static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002736 const ParseTranslationUnitInfo *PTUI =
2737 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002738 CXIndex CIdx = PTUI->CIdx;
2739 const char *source_filename = PTUI->source_filename;
2740 const char * const *command_line_args = PTUI->command_line_args;
2741 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002742 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002743 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002744
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002745 // Set up the initial return values.
2746 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002747 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002748 PTUI->result = CXError_Failure;
2749
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002750 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002751 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002752 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002754 }
2755
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2757
2758 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2759 setThreadBackgroundPriority();
2760
2761 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2762 // FIXME: Add a flag for modules.
2763 TranslationUnitKind TUKind
2764 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002765 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 = options & CXTranslationUnit_CacheCompletionResults;
2767 bool IncludeBriefCommentsInCodeCompletion
2768 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2769 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2770 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2771
2772 // Configure the diagnostics.
2773 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002774 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002775
2776 // Recover resources if we crash before exiting this function.
2777 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2778 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002779 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002780
Ahmed Charlesb8984322014-03-07 20:03:18 +00002781 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2782 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002783
2784 // Recover resources if we crash before exiting this function.
2785 llvm::CrashRecoveryContextCleanupRegistrar<
2786 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2787
Alp Toker9d85b182014-07-07 01:23:14 +00002788 for (auto &UF : PTUI->unsaved_files) {
2789 llvm::MemoryBuffer *MB =
2790 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2791 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 }
2793
Ahmed Charlesb8984322014-03-07 20:03:18 +00002794 std::unique_ptr<std::vector<const char *>> Args(
2795 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002796
2797 // Recover resources if we crash before exiting this method.
2798 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2799 ArgsCleanup(Args.get());
2800
2801 // Since the Clang C library is primarily used by batch tools dealing with
2802 // (often very broken) source code, where spell-checking can have a
2803 // significant negative impact on performance (particularly when
2804 // precompiled headers are involved), we disable it by default.
2805 // Only do this if we haven't found a spell-checking-related argument.
2806 bool FoundSpellCheckingArgument = false;
2807 for (int I = 0; I != num_command_line_args; ++I) {
2808 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2809 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2810 FoundSpellCheckingArgument = true;
2811 break;
2812 }
2813 }
2814 if (!FoundSpellCheckingArgument)
2815 Args->push_back("-fno-spell-checking");
2816
2817 Args->insert(Args->end(), command_line_args,
2818 command_line_args + num_command_line_args);
2819
2820 // The 'source_filename' argument is optional. If the caller does not
2821 // specify it then it is assumed that the source file is specified
2822 // in the actual argument list.
2823 // Put the source file after command_line_args otherwise if '-x' flag is
2824 // present it will be unused.
2825 if (source_filename)
2826 Args->push_back(source_filename);
2827
2828 // Do we need the detailed preprocessing record?
2829 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2830 Args->push_back("-Xclang");
2831 Args->push_back("-detailed-preprocessing-record");
2832 }
2833
2834 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002835 std::unique_ptr<ASTUnit> ErrUnit;
2836 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002837 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002838 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2839 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2840 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2841 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2842 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2843 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002844
2845 if (NumErrors != Diags->getClient()->getNumErrors()) {
2846 // Make sure to check that 'Unit' is non-NULL.
2847 if (CXXIdx->getDisplayDiagnostics())
2848 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2849 }
2850
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002851 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2852 PTUI->result = CXError_ASTReadError;
2853 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002854 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002855 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2856 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002857}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858
2859CXTranslationUnit
2860clang_parseTranslationUnit(CXIndex CIdx,
2861 const char *source_filename,
2862 const char *const *command_line_args,
2863 int num_command_line_args,
2864 struct CXUnsavedFile *unsaved_files,
2865 unsigned num_unsaved_files,
2866 unsigned options) {
2867 CXTranslationUnit TU;
2868 enum CXErrorCode Result = clang_parseTranslationUnit2(
2869 CIdx, source_filename, command_line_args, num_command_line_args,
2870 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002871 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002872 assert((TU && Result == CXError_Success) ||
2873 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874 return TU;
2875}
2876
2877enum CXErrorCode clang_parseTranslationUnit2(
2878 CXIndex CIdx,
2879 const char *source_filename,
2880 const char *const *command_line_args,
2881 int num_command_line_args,
2882 struct CXUnsavedFile *unsaved_files,
2883 unsigned num_unsaved_files,
2884 unsigned options,
2885 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002886 LOG_FUNC_SECTION {
2887 *Log << source_filename << ": ";
2888 for (int i = 0; i != num_command_line_args; ++i)
2889 *Log << command_line_args[i] << " ";
2890 }
2891
Alp Toker9d85b182014-07-07 01:23:14 +00002892 if (num_unsaved_files && !unsaved_files)
2893 return CXError_InvalidArguments;
2894
2895 ParseTranslationUnitInfo PTUI = {
2896 CIdx,
2897 source_filename,
2898 command_line_args,
2899 num_command_line_args,
2900 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2901 options,
2902 out_TU,
2903 CXError_Failure};
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 llvm::CrashRecoveryContext CRC;
2905
2906 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2907 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2908 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2909 fprintf(stderr, " 'command_line_args' : [");
2910 for (int i = 0; i != num_command_line_args; ++i) {
2911 if (i)
2912 fprintf(stderr, ", ");
2913 fprintf(stderr, "'%s'", command_line_args[i]);
2914 }
2915 fprintf(stderr, "],\n");
2916 fprintf(stderr, " 'unsaved_files' : [");
2917 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2918 if (i)
2919 fprintf(stderr, ", ");
2920 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2921 unsaved_files[i].Length);
2922 }
2923 fprintf(stderr, "],\n");
2924 fprintf(stderr, " 'options' : %d,\n", options);
2925 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002926
2927 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002928 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002929 if (CXTranslationUnit *TU = PTUI.out_TU)
2930 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002931 }
2932
2933 return PTUI.result;
2934}
2935
2936unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2937 return CXSaveTranslationUnit_None;
2938}
2939
2940namespace {
2941
2942struct SaveTranslationUnitInfo {
2943 CXTranslationUnit TU;
2944 const char *FileName;
2945 unsigned options;
2946 CXSaveError result;
2947};
2948
2949}
2950
2951static void clang_saveTranslationUnit_Impl(void *UserData) {
2952 SaveTranslationUnitInfo *STUI =
2953 static_cast<SaveTranslationUnitInfo*>(UserData);
2954
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002955 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2957 setThreadBackgroundPriority();
2958
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002959 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002960 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2961}
2962
2963int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2964 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002965 LOG_FUNC_SECTION {
2966 *Log << TU << ' ' << FileName;
2967 }
2968
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002969 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002970 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002971 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002972 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002973
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002974 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2976 if (!CXXUnit->hasSema())
2977 return CXSaveError_InvalidTU;
2978
2979 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2980
2981 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2982 getenv("LIBCLANG_NOTHREADS")) {
2983 clang_saveTranslationUnit_Impl(&STUI);
2984
2985 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2986 PrintLibclangResourceUsage(TU);
2987
2988 return STUI.result;
2989 }
2990
2991 // We have an AST that has invalid nodes due to compiler errors.
2992 // Use a crash recovery thread for protection.
2993
2994 llvm::CrashRecoveryContext CRC;
2995
2996 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2997 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2998 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2999 fprintf(stderr, " 'options' : %d,\n", options);
3000 fprintf(stderr, "}\n");
3001
3002 return CXSaveError_Unknown;
3003
3004 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3005 PrintLibclangResourceUsage(TU);
3006 }
3007
3008 return STUI.result;
3009}
3010
3011void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3012 if (CTUnit) {
3013 // If the translation unit has been marked as unsafe to free, just discard
3014 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3016 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 return;
3018
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003019 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003020 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3022 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003023 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003024 delete CTUnit;
3025 }
3026}
3027
3028unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3029 return CXReparse_None;
3030}
3031
3032struct ReparseTranslationUnitInfo {
3033 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003034 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003035 unsigned options;
Alp Toker9d85b182014-07-07 01:23:14 +00003036 mutable int result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003037};
3038
3039static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003040 const ReparseTranslationUnitInfo *RTUI =
3041 static_cast<ReparseTranslationUnitInfo *>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003042 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003043
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 unsigned options = RTUI->options;
3046 (void) options;
3047
3048 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003049 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003050 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051 RTUI->result = CXError_InvalidArguments;
3052 return;
3053 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003054
3055 // Reset the associated diagnostics.
3056 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003057 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003058
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003059 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003060 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3061 setThreadBackgroundPriority();
3062
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003063 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003064 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003065
3066 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3067 new std::vector<ASTUnit::RemappedFile>());
3068
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 // Recover resources if we crash before exiting this function.
3070 llvm::CrashRecoveryContextCleanupRegistrar<
3071 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003072
3073 for (auto &UF : RTUI->unsaved_files) {
3074 llvm::MemoryBuffer *MB =
3075 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3076 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003077 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003078
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003079 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003080 RTUI->result = CXError_Success;
3081 else if (isASTReadError(CXXUnit))
3082 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003083}
3084
3085int clang_reparseTranslationUnit(CXTranslationUnit TU,
3086 unsigned num_unsaved_files,
3087 struct CXUnsavedFile *unsaved_files,
3088 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003089 LOG_FUNC_SECTION {
3090 *Log << TU;
3091 }
3092
Alp Toker9d85b182014-07-07 01:23:14 +00003093 if (num_unsaved_files && !unsaved_files)
3094 return CXError_InvalidArguments;
3095
3096 ReparseTranslationUnitInfo RTUI = {
3097 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
3098 CXError_Failure};
Guy Benyei11169dd2012-12-18 14:30:41 +00003099
3100 if (getenv("LIBCLANG_NOTHREADS")) {
3101 clang_reparseTranslationUnit_Impl(&RTUI);
3102 return RTUI.result;
3103 }
3104
3105 llvm::CrashRecoveryContext CRC;
3106
3107 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3108 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003109 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003110 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3112 PrintLibclangResourceUsage(TU);
3113
3114 return RTUI.result;
3115}
3116
3117
3118CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003119 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003121 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003123
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003124 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003125 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003126}
3127
3128CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003129 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003130 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003131 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003132 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003133
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003134 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3136}
3137
3138} // end: extern "C"
3139
3140//===----------------------------------------------------------------------===//
3141// CXFile Operations.
3142//===----------------------------------------------------------------------===//
3143
3144extern "C" {
3145CXString clang_getFileName(CXFile SFile) {
3146 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003147 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003148
3149 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003150 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003151}
3152
3153time_t clang_getFileTime(CXFile SFile) {
3154 if (!SFile)
3155 return 0;
3156
3157 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3158 return FEnt->getModificationTime();
3159}
3160
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003161CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003162 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003163 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003164 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003165 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003166
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003167 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003168
3169 FileManager &FMgr = CXXUnit->getFileManager();
3170 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3171}
3172
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003173unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3174 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003175 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003176 LOG_BAD_TU(TU);
3177 return 0;
3178 }
3179
3180 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 return 0;
3182
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003183 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 FileEntry *FEnt = static_cast<FileEntry *>(file);
3185 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3186 .isFileMultipleIncludeGuarded(FEnt);
3187}
3188
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003189int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3190 if (!file || !outID)
3191 return 1;
3192
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003193 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003194 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3195 outID->data[0] = ID.getDevice();
3196 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003197 outID->data[2] = FEnt->getModificationTime();
3198 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003199}
3200
Guy Benyei11169dd2012-12-18 14:30:41 +00003201} // end: extern "C"
3202
3203//===----------------------------------------------------------------------===//
3204// CXCursor Operations.
3205//===----------------------------------------------------------------------===//
3206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003207static const Decl *getDeclFromExpr(const Stmt *E) {
3208 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return getDeclFromExpr(CE->getSubExpr());
3210
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003211 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003213 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003215 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003217 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 if (PRE->isExplicitProperty())
3219 return PRE->getExplicitProperty();
3220 // It could be messaging both getter and setter as in:
3221 // ++myobj.myprop;
3222 // in which case prefer to associate the setter since it is less obvious
3223 // from inspecting the source that the setter is going to get called.
3224 if (PRE->isMessagingSetter())
3225 return PRE->getImplicitPropertySetter();
3226 return PRE->getImplicitPropertyGetter();
3227 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003228 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003230 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 if (Expr *Src = OVE->getSourceExpr())
3232 return getDeclFromExpr(Src);
3233
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003234 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003236 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 if (!CE->isElidable())
3238 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003239 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 return OME->getMethodDecl();
3241
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003242 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003244 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3246 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003247 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3249 isa<ParmVarDecl>(SizeOfPack->getPack()))
3250 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003251
3252 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003253}
3254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003255static SourceLocation getLocationFromExpr(const Expr *E) {
3256 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 return getLocationFromExpr(CE->getSubExpr());
3258
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003259 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003261 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003263 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003265 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003267 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003269 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 return PropRef->getLocation();
3271
3272 return E->getLocStart();
3273}
3274
3275extern "C" {
3276
3277unsigned clang_visitChildren(CXCursor parent,
3278 CXCursorVisitor visitor,
3279 CXClientData client_data) {
3280 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3281 /*VisitPreprocessorLast=*/false);
3282 return CursorVis.VisitChildren(parent);
3283}
3284
3285#ifndef __has_feature
3286#define __has_feature(x) 0
3287#endif
3288#if __has_feature(blocks)
3289typedef enum CXChildVisitResult
3290 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3291
3292static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3293 CXClientData client_data) {
3294 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3295 return block(cursor, parent);
3296}
3297#else
3298// If we are compiled with a compiler that doesn't have native blocks support,
3299// define and call the block manually, so the
3300typedef struct _CXChildVisitResult
3301{
3302 void *isa;
3303 int flags;
3304 int reserved;
3305 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3306 CXCursor);
3307} *CXCursorVisitorBlock;
3308
3309static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3310 CXClientData client_data) {
3311 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3312 return block->invoke(block, cursor, parent);
3313}
3314#endif
3315
3316
3317unsigned clang_visitChildrenWithBlock(CXCursor parent,
3318 CXCursorVisitorBlock block) {
3319 return clang_visitChildren(parent, visitWithBlock, block);
3320}
3321
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003322static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003326 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003328 if (const ObjCPropertyImplDecl *PropImpl =
3329 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003331 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003332
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003333 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003337 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003340 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3345 // and returns different names. NamedDecl returns the class name and
3346 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003347 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348
3349 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003350 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003351
3352 SmallString<1024> S;
3353 llvm::raw_svector_ostream os(S);
3354 ND->printName(os);
3355
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357}
3358
3359CXString clang_getCursorSpelling(CXCursor C) {
3360 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003361 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003362
3363 if (clang_isReference(C.kind)) {
3364 switch (C.kind) {
3365 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003366 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003367 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 }
3369 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003370 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003371 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 }
3373 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003374 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003376 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 }
3378 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003379 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 }
3382 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003383 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 assert(Type && "Missing type decl");
3385
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 getAsString());
3388 }
3389 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003390 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 assert(Template && "Missing template decl");
3392
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003393 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 }
3395
3396 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003397 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 assert(NS && "Missing namespace decl");
3399
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003400 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 }
3402
3403 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003404 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 assert(Field && "Missing member decl");
3406
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003407 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409
3410 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003411 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 assert(Label && "Missing label");
3413
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003414 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 }
3416
3417 case CXCursor_OverloadedDeclRef: {
3418 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3420 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003421 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003422 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003424 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003425 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 OverloadedTemplateStorage *Ovl
3427 = Storage.get<OverloadedTemplateStorage*>();
3428 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003429 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003430 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
3433 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003434 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 assert(Var && "Missing variable decl");
3436
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003437 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 }
3439
3440 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003441 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 }
3443 }
3444
3445 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003446 const Expr *E = getCursorExpr(C);
3447
3448 if (C.kind == CXCursor_ObjCStringLiteral ||
3449 C.kind == CXCursor_StringLiteral) {
3450 const StringLiteral *SLit;
3451 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3452 SLit = OSL->getString();
3453 } else {
3454 SLit = cast<StringLiteral>(E);
3455 }
3456 SmallString<256> Buf;
3457 llvm::raw_svector_ostream OS(Buf);
3458 SLit->outputString(OS);
3459 return cxstring::createDup(OS.str());
3460 }
3461
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 if (D)
3464 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003465 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 }
3467
3468 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003469 const Stmt *S = getCursorStmt(C);
3470 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003471 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003473 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475
3476 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003477 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 ->getNameStart());
3479
3480 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003481 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 ->getNameStart());
3483
3484 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003485 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003486
3487 if (clang_isDeclaration(C.kind))
3488 return getDeclSpelling(getCursorDecl(C));
3489
3490 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003491 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 }
3494
3495 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003496 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003497 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 }
3499
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003500 if (C.kind == CXCursor_PackedAttr) {
3501 return cxstring::createRef("packed");
3502 }
3503
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003504 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003505}
3506
3507CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3508 unsigned pieceIndex,
3509 unsigned options) {
3510 if (clang_Cursor_isNull(C))
3511 return clang_getNullRange();
3512
3513 ASTContext &Ctx = getCursorContext(C);
3514
3515 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003516 const Stmt *S = getCursorStmt(C);
3517 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 if (pieceIndex > 0)
3519 return clang_getNullRange();
3520 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3521 }
3522
3523 return clang_getNullRange();
3524 }
3525
3526 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003527 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3529 if (pieceIndex >= ME->getNumSelectorLocs())
3530 return clang_getNullRange();
3531 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3532 }
3533 }
3534
3535 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3536 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3539 if (pieceIndex >= MD->getNumSelectorLocs())
3540 return clang_getNullRange();
3541 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3542 }
3543 }
3544
3545 if (C.kind == CXCursor_ObjCCategoryDecl ||
3546 C.kind == CXCursor_ObjCCategoryImplDecl) {
3547 if (pieceIndex > 0)
3548 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003549 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3551 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003552 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3554 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3555 }
3556
3557 if (C.kind == CXCursor_ModuleImportDecl) {
3558 if (pieceIndex > 0)
3559 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const ImportDecl *ImportD =
3561 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3563 if (!Locs.empty())
3564 return cxloc::translateSourceRange(Ctx,
3565 SourceRange(Locs.front(), Locs.back()));
3566 }
3567 return clang_getNullRange();
3568 }
3569
3570 // FIXME: A CXCursor_InclusionDirective should give the location of the
3571 // filename, but we don't keep track of this.
3572
3573 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3574 // but we don't keep track of this.
3575
3576 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3577 // but we don't keep track of this.
3578
3579 // Default handling, give the location of the cursor.
3580
3581 if (pieceIndex > 0)
3582 return clang_getNullRange();
3583
3584 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3585 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3586 return cxloc::translateSourceRange(Ctx, Loc);
3587}
3588
3589CXString clang_getCursorDisplayName(CXCursor C) {
3590 if (!clang_isDeclaration(C.kind))
3591 return clang_getCursorSpelling(C);
3592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003595 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003596
3597 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 D = FunTmpl->getTemplatedDecl();
3600
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 SmallString<64> Str;
3603 llvm::raw_svector_ostream OS(Str);
3604 OS << *Function;
3605 if (Function->getPrimaryTemplate())
3606 OS << "<>";
3607 OS << "(";
3608 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3609 if (I)
3610 OS << ", ";
3611 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3612 }
3613
3614 if (Function->isVariadic()) {
3615 if (Function->getNumParams())
3616 OS << ", ";
3617 OS << "...";
3618 }
3619 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003620 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 }
3622
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003623 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 SmallString<64> Str;
3625 llvm::raw_svector_ostream OS(Str);
3626 OS << *ClassTemplate;
3627 OS << "<";
3628 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3629 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3630 if (I)
3631 OS << ", ";
3632
3633 NamedDecl *Param = Params->getParam(I);
3634 if (Param->getIdentifier()) {
3635 OS << Param->getIdentifier()->getName();
3636 continue;
3637 }
3638
3639 // There is no parameter name, which makes this tricky. Try to come up
3640 // with something useful that isn't too long.
3641 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3642 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3643 else if (NonTypeTemplateParmDecl *NTTP
3644 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3645 OS << NTTP->getType().getAsString(Policy);
3646 else
3647 OS << "template<...> class";
3648 }
3649
3650 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003651 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 }
3653
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003654 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3656 // If the type was explicitly written, use that.
3657 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003658 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003659
Benjamin Kramer9170e912013-02-22 15:46:01 +00003660 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 llvm::raw_svector_ostream OS(Str);
3662 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003663 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 ClassSpec->getTemplateArgs().data(),
3665 ClassSpec->getTemplateArgs().size(),
3666 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003667 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 }
3669
3670 return clang_getCursorSpelling(C);
3671}
3672
3673CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3674 switch (Kind) {
3675 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003803 case CXCursor_ObjCSelfExpr:
3804 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003893 case CXCursor_SEHLeaveStmt:
3894 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003923 case CXCursor_PackedAttr:
3924 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003925 case CXCursor_PureAttr:
3926 return cxstring::createRef("attribute(pure)");
3927 case CXCursor_ConstAttr:
3928 return cxstring::createRef("attribute(const)");
3929 case CXCursor_NoDuplicateAttr:
3930 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003931 case CXCursor_CUDAConstantAttr:
3932 return cxstring::createRef("attribute(constant)");
3933 case CXCursor_CUDADeviceAttr:
3934 return cxstring::createRef("attribute(device)");
3935 case CXCursor_CUDAGlobalAttr:
3936 return cxstring::createRef("attribute(global)");
3937 case CXCursor_CUDAHostAttr:
3938 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003987 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003988 return cxstring::createRef("OMPParallelDirective");
3989 case CXCursor_OMPSimdDirective:
3990 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003991 case CXCursor_OMPForDirective:
3992 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003993 case CXCursor_OMPSectionsDirective:
3994 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003995 case CXCursor_OMPSectionDirective:
3996 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00003997 case CXCursor_OMPSingleDirective:
3998 return cxstring::createRef("OMPSingleDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 }
4000
4001 llvm_unreachable("Unhandled CXCursorKind");
4002}
4003
4004struct GetCursorData {
4005 SourceLocation TokenBeginLoc;
4006 bool PointsAtMacroArgExpansion;
4007 bool VisitedObjCPropertyImplDecl;
4008 SourceLocation VisitedDeclaratorDeclStartLoc;
4009 CXCursor &BestCursor;
4010
4011 GetCursorData(SourceManager &SM,
4012 SourceLocation tokenBegin, CXCursor &outputCursor)
4013 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4014 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4015 VisitedObjCPropertyImplDecl = false;
4016 }
4017};
4018
4019static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4020 CXCursor parent,
4021 CXClientData client_data) {
4022 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4023 CXCursor *BestCursor = &Data->BestCursor;
4024
4025 // If we point inside a macro argument we should provide info of what the
4026 // token is so use the actual cursor, don't replace it with a macro expansion
4027 // cursor.
4028 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4029 return CXChildVisit_Recurse;
4030
4031 if (clang_isDeclaration(cursor.kind)) {
4032 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004033 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4035 if (MD->isImplicit())
4036 return CXChildVisit_Break;
4037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004038 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4040 // Check that when we have multiple @class references in the same line,
4041 // that later ones do not override the previous ones.
4042 // If we have:
4043 // @class Foo, Bar;
4044 // source ranges for both start at '@', so 'Bar' will end up overriding
4045 // 'Foo' even though the cursor location was at 'Foo'.
4046 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4047 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4050 if (PrevID != ID &&
4051 !PrevID->isThisDeclarationADefinition() &&
4052 !ID->isThisDeclarationADefinition())
4053 return CXChildVisit_Break;
4054 }
4055
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004056 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4058 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4059 // Check that when we have multiple declarators in the same line,
4060 // that later ones do not override the previous ones.
4061 // If we have:
4062 // int Foo, Bar;
4063 // source ranges for both start at 'int', so 'Bar' will end up overriding
4064 // 'Foo' even though the cursor location was at 'Foo'.
4065 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4066 return CXChildVisit_Break;
4067 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4068
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004069 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4071 (void)PropImp;
4072 // Check that when we have multiple @synthesize in the same line,
4073 // that later ones do not override the previous ones.
4074 // If we have:
4075 // @synthesize Foo, Bar;
4076 // source ranges for both start at '@', so 'Bar' will end up overriding
4077 // 'Foo' even though the cursor location was at 'Foo'.
4078 if (Data->VisitedObjCPropertyImplDecl)
4079 return CXChildVisit_Break;
4080 Data->VisitedObjCPropertyImplDecl = true;
4081 }
4082 }
4083
4084 if (clang_isExpression(cursor.kind) &&
4085 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004086 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 // Avoid having the cursor of an expression replace the declaration cursor
4088 // when the expression source range overlaps the declaration range.
4089 // This can happen for C++ constructor expressions whose range generally
4090 // include the variable declaration, e.g.:
4091 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4092 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4093 D->getLocation() == Data->TokenBeginLoc)
4094 return CXChildVisit_Break;
4095 }
4096 }
4097
4098 // If our current best cursor is the construction of a temporary object,
4099 // don't replace that cursor with a type reference, because we want
4100 // clang_getCursor() to point at the constructor.
4101 if (clang_isExpression(BestCursor->kind) &&
4102 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4103 cursor.kind == CXCursor_TypeRef) {
4104 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4105 // as having the actual point on the type reference.
4106 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4107 return CXChildVisit_Recurse;
4108 }
4109
4110 *BestCursor = cursor;
4111 return CXChildVisit_Recurse;
4112}
4113
4114CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004115 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004116 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004118 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004119
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004120 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4122
4123 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4124 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4125
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004126 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 CXFile SearchFile;
4128 unsigned SearchLine, SearchColumn;
4129 CXFile ResultFile;
4130 unsigned ResultLine, ResultColumn;
4131 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4132 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4133 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004134
4135 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4136 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004137 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004138 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 SearchFileName = clang_getFileName(SearchFile);
4140 ResultFileName = clang_getFileName(ResultFile);
4141 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4142 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004143 *Log << llvm::format("(%s:%d:%d) = %s",
4144 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4145 clang_getCString(KindSpelling))
4146 << llvm::format("(%s:%d:%d):%s%s",
4147 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4148 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 clang_disposeString(SearchFileName);
4150 clang_disposeString(ResultFileName);
4151 clang_disposeString(KindSpelling);
4152 clang_disposeString(USR);
4153
4154 CXCursor Definition = clang_getCursorDefinition(Result);
4155 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4156 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4157 CXString DefinitionKindSpelling
4158 = clang_getCursorKindSpelling(Definition.kind);
4159 CXFile DefinitionFile;
4160 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004161 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004162 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004164 *Log << llvm::format(" -> %s(%s:%d:%d)",
4165 clang_getCString(DefinitionKindSpelling),
4166 clang_getCString(DefinitionFileName),
4167 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 clang_disposeString(DefinitionFileName);
4169 clang_disposeString(DefinitionKindSpelling);
4170 }
4171 }
4172
4173 return Result;
4174}
4175
4176CXCursor clang_getNullCursor(void) {
4177 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4178}
4179
4180unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004181 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4182 // can't set consistently. For example, when visiting a DeclStmt we will set
4183 // it but we don't set it on the result of clang_getCursorDefinition for
4184 // a reference of the same declaration.
4185 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4186 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4187 // to provide that kind of info.
4188 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004189 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004190 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004191 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004192
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 return X == Y;
4194}
4195
4196unsigned clang_hashCursor(CXCursor C) {
4197 unsigned Index = 0;
4198 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4199 Index = 1;
4200
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004201 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 std::make_pair(C.kind, C.data[Index]));
4203}
4204
4205unsigned clang_isInvalid(enum CXCursorKind K) {
4206 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4207}
4208
4209unsigned clang_isDeclaration(enum CXCursorKind K) {
4210 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4211 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4212}
4213
4214unsigned clang_isReference(enum CXCursorKind K) {
4215 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4216}
4217
4218unsigned clang_isExpression(enum CXCursorKind K) {
4219 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4220}
4221
4222unsigned clang_isStatement(enum CXCursorKind K) {
4223 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4224}
4225
4226unsigned clang_isAttribute(enum CXCursorKind K) {
4227 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4228}
4229
4230unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4231 return K == CXCursor_TranslationUnit;
4232}
4233
4234unsigned clang_isPreprocessing(enum CXCursorKind K) {
4235 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4236}
4237
4238unsigned clang_isUnexposed(enum CXCursorKind K) {
4239 switch (K) {
4240 case CXCursor_UnexposedDecl:
4241 case CXCursor_UnexposedExpr:
4242 case CXCursor_UnexposedStmt:
4243 case CXCursor_UnexposedAttr:
4244 return true;
4245 default:
4246 return false;
4247 }
4248}
4249
4250CXCursorKind clang_getCursorKind(CXCursor C) {
4251 return C.kind;
4252}
4253
4254CXSourceLocation clang_getCursorLocation(CXCursor C) {
4255 if (clang_isReference(C.kind)) {
4256 switch (C.kind) {
4257 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004258 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 = getCursorObjCSuperClassRef(C);
4260 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4261 }
4262
4263 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004264 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 = getCursorObjCProtocolRef(C);
4266 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4267 }
4268
4269 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004270 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 = getCursorObjCClassRef(C);
4272 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4273 }
4274
4275 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004276 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4278 }
4279
4280 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004281 std::pair<const TemplateDecl *, SourceLocation> P =
4282 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4284 }
4285
4286 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004287 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4289 }
4290
4291 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004292 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4294 }
4295
4296 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004297 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4299 }
4300
4301 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004302 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 if (!BaseSpec)
4304 return clang_getNullLocation();
4305
4306 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4307 return cxloc::translateSourceLocation(getCursorContext(C),
4308 TSInfo->getTypeLoc().getBeginLoc());
4309
4310 return cxloc::translateSourceLocation(getCursorContext(C),
4311 BaseSpec->getLocStart());
4312 }
4313
4314 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004315 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4317 }
4318
4319 case CXCursor_OverloadedDeclRef:
4320 return cxloc::translateSourceLocation(getCursorContext(C),
4321 getCursorOverloadedDeclRef(C).second);
4322
4323 default:
4324 // FIXME: Need a way to enumerate all non-reference cases.
4325 llvm_unreachable("Missed a reference kind");
4326 }
4327 }
4328
4329 if (clang_isExpression(C.kind))
4330 return cxloc::translateSourceLocation(getCursorContext(C),
4331 getLocationFromExpr(getCursorExpr(C)));
4332
4333 if (clang_isStatement(C.kind))
4334 return cxloc::translateSourceLocation(getCursorContext(C),
4335 getCursorStmt(C)->getLocStart());
4336
4337 if (C.kind == CXCursor_PreprocessingDirective) {
4338 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4339 return cxloc::translateSourceLocation(getCursorContext(C), L);
4340 }
4341
4342 if (C.kind == CXCursor_MacroExpansion) {
4343 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004344 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 return cxloc::translateSourceLocation(getCursorContext(C), L);
4346 }
4347
4348 if (C.kind == CXCursor_MacroDefinition) {
4349 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4350 return cxloc::translateSourceLocation(getCursorContext(C), L);
4351 }
4352
4353 if (C.kind == CXCursor_InclusionDirective) {
4354 SourceLocation L
4355 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4356 return cxloc::translateSourceLocation(getCursorContext(C), L);
4357 }
4358
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004359 if (clang_isAttribute(C.kind)) {
4360 SourceLocation L
4361 = cxcursor::getCursorAttr(C)->getLocation();
4362 return cxloc::translateSourceLocation(getCursorContext(C), L);
4363 }
4364
Guy Benyei11169dd2012-12-18 14:30:41 +00004365 if (!clang_isDeclaration(C.kind))
4366 return clang_getNullLocation();
4367
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004368 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 if (!D)
4370 return clang_getNullLocation();
4371
4372 SourceLocation Loc = D->getLocation();
4373 // FIXME: Multiple variables declared in a single declaration
4374 // currently lack the information needed to correctly determine their
4375 // ranges when accounting for the type-specifier. We use context
4376 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4377 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004378 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 if (!cxcursor::isFirstInDeclGroup(C))
4380 Loc = VD->getLocation();
4381 }
4382
4383 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004384 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 Loc = MD->getSelectorStartLoc();
4386
4387 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4388}
4389
4390} // end extern "C"
4391
4392CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4393 assert(TU);
4394
4395 // Guard against an invalid SourceLocation, or we may assert in one
4396 // of the following calls.
4397 if (SLoc.isInvalid())
4398 return clang_getNullCursor();
4399
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004400 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004401
4402 // Translate the given source location to make it point at the beginning of
4403 // the token under the cursor.
4404 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4405 CXXUnit->getASTContext().getLangOpts());
4406
4407 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4408 if (SLoc.isValid()) {
4409 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4410 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4411 /*VisitPreprocessorLast=*/true,
4412 /*VisitIncludedEntities=*/false,
4413 SourceLocation(SLoc));
4414 CursorVis.visitFileRegion();
4415 }
4416
4417 return Result;
4418}
4419
4420static SourceRange getRawCursorExtent(CXCursor C) {
4421 if (clang_isReference(C.kind)) {
4422 switch (C.kind) {
4423 case CXCursor_ObjCSuperClassRef:
4424 return getCursorObjCSuperClassRef(C).second;
4425
4426 case CXCursor_ObjCProtocolRef:
4427 return getCursorObjCProtocolRef(C).second;
4428
4429 case CXCursor_ObjCClassRef:
4430 return getCursorObjCClassRef(C).second;
4431
4432 case CXCursor_TypeRef:
4433 return getCursorTypeRef(C).second;
4434
4435 case CXCursor_TemplateRef:
4436 return getCursorTemplateRef(C).second;
4437
4438 case CXCursor_NamespaceRef:
4439 return getCursorNamespaceRef(C).second;
4440
4441 case CXCursor_MemberRef:
4442 return getCursorMemberRef(C).second;
4443
4444 case CXCursor_CXXBaseSpecifier:
4445 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4446
4447 case CXCursor_LabelRef:
4448 return getCursorLabelRef(C).second;
4449
4450 case CXCursor_OverloadedDeclRef:
4451 return getCursorOverloadedDeclRef(C).second;
4452
4453 case CXCursor_VariableRef:
4454 return getCursorVariableRef(C).second;
4455
4456 default:
4457 // FIXME: Need a way to enumerate all non-reference cases.
4458 llvm_unreachable("Missed a reference kind");
4459 }
4460 }
4461
4462 if (clang_isExpression(C.kind))
4463 return getCursorExpr(C)->getSourceRange();
4464
4465 if (clang_isStatement(C.kind))
4466 return getCursorStmt(C)->getSourceRange();
4467
4468 if (clang_isAttribute(C.kind))
4469 return getCursorAttr(C)->getRange();
4470
4471 if (C.kind == CXCursor_PreprocessingDirective)
4472 return cxcursor::getCursorPreprocessingDirective(C);
4473
4474 if (C.kind == CXCursor_MacroExpansion) {
4475 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004476 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 return TU->mapRangeFromPreamble(Range);
4478 }
4479
4480 if (C.kind == CXCursor_MacroDefinition) {
4481 ASTUnit *TU = getCursorASTUnit(C);
4482 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4483 return TU->mapRangeFromPreamble(Range);
4484 }
4485
4486 if (C.kind == CXCursor_InclusionDirective) {
4487 ASTUnit *TU = getCursorASTUnit(C);
4488 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4489 return TU->mapRangeFromPreamble(Range);
4490 }
4491
4492 if (C.kind == CXCursor_TranslationUnit) {
4493 ASTUnit *TU = getCursorASTUnit(C);
4494 FileID MainID = TU->getSourceManager().getMainFileID();
4495 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4496 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4497 return SourceRange(Start, End);
4498 }
4499
4500 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004501 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 if (!D)
4503 return SourceRange();
4504
4505 SourceRange R = D->getSourceRange();
4506 // FIXME: Multiple variables declared in a single declaration
4507 // currently lack the information needed to correctly determine their
4508 // ranges when accounting for the type-specifier. We use context
4509 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4510 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004511 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 if (!cxcursor::isFirstInDeclGroup(C))
4513 R.setBegin(VD->getLocation());
4514 }
4515 return R;
4516 }
4517 return SourceRange();
4518}
4519
4520/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4521/// the decl-specifier-seq for declarations.
4522static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4523 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004524 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 if (!D)
4526 return SourceRange();
4527
4528 SourceRange R = D->getSourceRange();
4529
4530 // Adjust the start of the location for declarations preceded by
4531 // declaration specifiers.
4532 SourceLocation StartLoc;
4533 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4534 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4535 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004536 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4538 StartLoc = TI->getTypeLoc().getLocStart();
4539 }
4540
4541 if (StartLoc.isValid() && R.getBegin().isValid() &&
4542 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4543 R.setBegin(StartLoc);
4544
4545 // FIXME: Multiple variables declared in a single declaration
4546 // currently lack the information needed to correctly determine their
4547 // ranges when accounting for the type-specifier. We use context
4548 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4549 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004550 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 if (!cxcursor::isFirstInDeclGroup(C))
4552 R.setBegin(VD->getLocation());
4553 }
4554
4555 return R;
4556 }
4557
4558 return getRawCursorExtent(C);
4559}
4560
4561extern "C" {
4562
4563CXSourceRange clang_getCursorExtent(CXCursor C) {
4564 SourceRange R = getRawCursorExtent(C);
4565 if (R.isInvalid())
4566 return clang_getNullRange();
4567
4568 return cxloc::translateSourceRange(getCursorContext(C), R);
4569}
4570
4571CXCursor clang_getCursorReferenced(CXCursor C) {
4572 if (clang_isInvalid(C.kind))
4573 return clang_getNullCursor();
4574
4575 CXTranslationUnit tu = getCursorTU(C);
4576 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004577 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 if (!D)
4579 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004580 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004582 if (const ObjCPropertyImplDecl *PropImpl =
4583 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4585 return MakeCXCursor(Property, tu);
4586
4587 return C;
4588 }
4589
4590 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004591 const Expr *E = getCursorExpr(C);
4592 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 if (D) {
4594 CXCursor declCursor = MakeCXCursor(D, tu);
4595 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4596 declCursor);
4597 return declCursor;
4598 }
4599
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004600 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 return MakeCursorOverloadedDeclRef(Ovl, tu);
4602
4603 return clang_getNullCursor();
4604 }
4605
4606 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004607 const Stmt *S = getCursorStmt(C);
4608 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 if (LabelDecl *label = Goto->getLabel())
4610 if (LabelStmt *labelS = label->getStmt())
4611 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4612
4613 return clang_getNullCursor();
4614 }
4615
4616 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004617 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 return MakeMacroDefinitionCursor(Def, tu);
4619 }
4620
4621 if (!clang_isReference(C.kind))
4622 return clang_getNullCursor();
4623
4624 switch (C.kind) {
4625 case CXCursor_ObjCSuperClassRef:
4626 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4627
4628 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004629 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4630 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 return MakeCXCursor(Def, tu);
4632
4633 return MakeCXCursor(Prot, tu);
4634 }
4635
4636 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004637 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4638 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 return MakeCXCursor(Def, tu);
4640
4641 return MakeCXCursor(Class, tu);
4642 }
4643
4644 case CXCursor_TypeRef:
4645 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4646
4647 case CXCursor_TemplateRef:
4648 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4649
4650 case CXCursor_NamespaceRef:
4651 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4652
4653 case CXCursor_MemberRef:
4654 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4655
4656 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004657 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4659 tu ));
4660 }
4661
4662 case CXCursor_LabelRef:
4663 // FIXME: We end up faking the "parent" declaration here because we
4664 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004665 return MakeCXCursor(getCursorLabelRef(C).first,
4666 cxtu::getASTUnit(tu)->getASTContext()
4667 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 tu);
4669
4670 case CXCursor_OverloadedDeclRef:
4671 return C;
4672
4673 case CXCursor_VariableRef:
4674 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4675
4676 default:
4677 // We would prefer to enumerate all non-reference cursor kinds here.
4678 llvm_unreachable("Unhandled reference cursor kind");
4679 }
4680}
4681
4682CXCursor clang_getCursorDefinition(CXCursor C) {
4683 if (clang_isInvalid(C.kind))
4684 return clang_getNullCursor();
4685
4686 CXTranslationUnit TU = getCursorTU(C);
4687
4688 bool WasReference = false;
4689 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4690 C = clang_getCursorReferenced(C);
4691 WasReference = true;
4692 }
4693
4694 if (C.kind == CXCursor_MacroExpansion)
4695 return clang_getCursorReferenced(C);
4696
4697 if (!clang_isDeclaration(C.kind))
4698 return clang_getNullCursor();
4699
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004700 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 if (!D)
4702 return clang_getNullCursor();
4703
4704 switch (D->getKind()) {
4705 // Declaration kinds that don't really separate the notions of
4706 // declaration and definition.
4707 case Decl::Namespace:
4708 case Decl::Typedef:
4709 case Decl::TypeAlias:
4710 case Decl::TypeAliasTemplate:
4711 case Decl::TemplateTypeParm:
4712 case Decl::EnumConstant:
4713 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004714 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case Decl::IndirectField:
4716 case Decl::ObjCIvar:
4717 case Decl::ObjCAtDefsField:
4718 case Decl::ImplicitParam:
4719 case Decl::ParmVar:
4720 case Decl::NonTypeTemplateParm:
4721 case Decl::TemplateTemplateParm:
4722 case Decl::ObjCCategoryImpl:
4723 case Decl::ObjCImplementation:
4724 case Decl::AccessSpec:
4725 case Decl::LinkageSpec:
4726 case Decl::ObjCPropertyImpl:
4727 case Decl::FileScopeAsm:
4728 case Decl::StaticAssert:
4729 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004730 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case Decl::Label: // FIXME: Is this right??
4732 case Decl::ClassScopeFunctionSpecialization:
4733 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004734 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 return C;
4736
4737 // Declaration kinds that don't make any sense here, but are
4738 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004739 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 case Decl::TranslationUnit:
4741 break;
4742
4743 // Declaration kinds for which the definition is not resolvable.
4744 case Decl::UnresolvedUsingTypename:
4745 case Decl::UnresolvedUsingValue:
4746 break;
4747
4748 case Decl::UsingDirective:
4749 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4750 TU);
4751
4752 case Decl::NamespaceAlias:
4753 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4754
4755 case Decl::Enum:
4756 case Decl::Record:
4757 case Decl::CXXRecord:
4758 case Decl::ClassTemplateSpecialization:
4759 case Decl::ClassTemplatePartialSpecialization:
4760 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4761 return MakeCXCursor(Def, TU);
4762 return clang_getNullCursor();
4763
4764 case Decl::Function:
4765 case Decl::CXXMethod:
4766 case Decl::CXXConstructor:
4767 case Decl::CXXDestructor:
4768 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004769 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004771 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return clang_getNullCursor();
4773 }
4774
Larisse Voufo39a1e502013-08-06 01:03:05 +00004775 case Decl::Var:
4776 case Decl::VarTemplateSpecialization:
4777 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004779 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 return MakeCXCursor(Def, TU);
4781 return clang_getNullCursor();
4782 }
4783
4784 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004785 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4787 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4788 return clang_getNullCursor();
4789 }
4790
4791 case Decl::ClassTemplate: {
4792 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4793 ->getDefinition())
4794 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4795 TU);
4796 return clang_getNullCursor();
4797 }
4798
Larisse Voufo39a1e502013-08-06 01:03:05 +00004799 case Decl::VarTemplate: {
4800 if (VarDecl *Def =
4801 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4802 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4803 return clang_getNullCursor();
4804 }
4805
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 case Decl::Using:
4807 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4808 D->getLocation(), TU);
4809
4810 case Decl::UsingShadow:
4811 return clang_getCursorDefinition(
4812 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4813 TU));
4814
4815 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 if (Method->isThisDeclarationADefinition())
4818 return C;
4819
4820 // Dig out the method definition in the associated
4821 // @implementation, if we have it.
4822 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004823 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4825 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4826 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4827 Method->isInstanceMethod()))
4828 if (Def->isThisDeclarationADefinition())
4829 return MakeCXCursor(Def, TU);
4830
4831 return clang_getNullCursor();
4832 }
4833
4834 case Decl::ObjCCategory:
4835 if (ObjCCategoryImplDecl *Impl
4836 = cast<ObjCCategoryDecl>(D)->getImplementation())
4837 return MakeCXCursor(Impl, TU);
4838 return clang_getNullCursor();
4839
4840 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004841 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 return MakeCXCursor(Def, TU);
4843 return clang_getNullCursor();
4844
4845 case Decl::ObjCInterface: {
4846 // There are two notions of a "definition" for an Objective-C
4847 // class: the interface and its implementation. When we resolved a
4848 // reference to an Objective-C class, produce the @interface as
4849 // the definition; when we were provided with the interface,
4850 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004853 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 return MakeCXCursor(Def, TU);
4855 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4856 return MakeCXCursor(Impl, TU);
4857 return clang_getNullCursor();
4858 }
4859
4860 case Decl::ObjCProperty:
4861 // FIXME: We don't really know where to find the
4862 // ObjCPropertyImplDecls that implement this property.
4863 return clang_getNullCursor();
4864
4865 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 return MakeCXCursor(Def, TU);
4870
4871 return clang_getNullCursor();
4872
4873 case Decl::Friend:
4874 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4875 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4876 return clang_getNullCursor();
4877
4878 case Decl::FriendTemplate:
4879 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4880 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4881 return clang_getNullCursor();
4882 }
4883
4884 return clang_getNullCursor();
4885}
4886
4887unsigned clang_isCursorDefinition(CXCursor C) {
4888 if (!clang_isDeclaration(C.kind))
4889 return 0;
4890
4891 return clang_getCursorDefinition(C) == C;
4892}
4893
4894CXCursor clang_getCanonicalCursor(CXCursor C) {
4895 if (!clang_isDeclaration(C.kind))
4896 return C;
4897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004898 if (const Decl *D = getCursorDecl(C)) {
4899 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4901 return MakeCXCursor(CatD, getCursorTU(C));
4902
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004903 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4904 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 return MakeCXCursor(IFD, getCursorTU(C));
4906
4907 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4908 }
4909
4910 return C;
4911}
4912
4913int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4914 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4915}
4916
4917unsigned clang_getNumOverloadedDecls(CXCursor C) {
4918 if (C.kind != CXCursor_OverloadedDeclRef)
4919 return 0;
4920
4921 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004922 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 return E->getNumDecls();
4924
4925 if (OverloadedTemplateStorage *S
4926 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4927 return S->size();
4928
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004929 const Decl *D = Storage.get<const Decl *>();
4930 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 return Using->shadow_size();
4932
4933 return 0;
4934}
4935
4936CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4937 if (cursor.kind != CXCursor_OverloadedDeclRef)
4938 return clang_getNullCursor();
4939
4940 if (index >= clang_getNumOverloadedDecls(cursor))
4941 return clang_getNullCursor();
4942
4943 CXTranslationUnit TU = getCursorTU(cursor);
4944 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004945 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 return MakeCXCursor(E->decls_begin()[index], TU);
4947
4948 if (OverloadedTemplateStorage *S
4949 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4950 return MakeCXCursor(S->begin()[index], TU);
4951
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 const Decl *D = Storage.get<const Decl *>();
4953 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004954 // FIXME: This is, unfortunately, linear time.
4955 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4956 std::advance(Pos, index);
4957 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4958 }
4959
4960 return clang_getNullCursor();
4961}
4962
4963void clang_getDefinitionSpellingAndExtent(CXCursor C,
4964 const char **startBuf,
4965 const char **endBuf,
4966 unsigned *startLine,
4967 unsigned *startColumn,
4968 unsigned *endLine,
4969 unsigned *endColumn) {
4970 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004971 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4973
4974 SourceManager &SM = FD->getASTContext().getSourceManager();
4975 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4976 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4977 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4978 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4979 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4980 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4981}
4982
4983
4984CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4985 unsigned PieceIndex) {
4986 RefNamePieces Pieces;
4987
4988 switch (C.kind) {
4989 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004990 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4992 E->getQualifierLoc().getSourceRange());
4993 break;
4994
4995 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004996 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4998 E->getQualifierLoc().getSourceRange(),
4999 E->getOptionalExplicitTemplateArgs());
5000 break;
5001
5002 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005003 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005005 const Expr *Callee = OCE->getCallee();
5006 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 Callee = ICE->getSubExpr();
5008
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005009 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5011 DRE->getQualifierLoc().getSourceRange());
5012 }
5013 break;
5014
5015 default:
5016 break;
5017 }
5018
5019 if (Pieces.empty()) {
5020 if (PieceIndex == 0)
5021 return clang_getCursorExtent(C);
5022 } else if (PieceIndex < Pieces.size()) {
5023 SourceRange R = Pieces[PieceIndex];
5024 if (R.isValid())
5025 return cxloc::translateSourceRange(getCursorContext(C), R);
5026 }
5027
5028 return clang_getNullRange();
5029}
5030
5031void clang_enableStackTraces(void) {
5032 llvm::sys::PrintStackTraceOnErrorSignal();
5033}
5034
5035void clang_executeOnThread(void (*fn)(void*), void *user_data,
5036 unsigned stack_size) {
5037 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5038}
5039
5040} // end: extern "C"
5041
5042//===----------------------------------------------------------------------===//
5043// Token-based Operations.
5044//===----------------------------------------------------------------------===//
5045
5046/* CXToken layout:
5047 * int_data[0]: a CXTokenKind
5048 * int_data[1]: starting token location
5049 * int_data[2]: token length
5050 * int_data[3]: reserved
5051 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5052 * otherwise unused.
5053 */
5054extern "C" {
5055
5056CXTokenKind clang_getTokenKind(CXToken CXTok) {
5057 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5058}
5059
5060CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5061 switch (clang_getTokenKind(CXTok)) {
5062 case CXToken_Identifier:
5063 case CXToken_Keyword:
5064 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005065 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 ->getNameStart());
5067
5068 case CXToken_Literal: {
5069 // We have stashed the starting pointer in the ptr_data field. Use it.
5070 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005071 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 }
5073
5074 case CXToken_Punctuation:
5075 case CXToken_Comment:
5076 break;
5077 }
5078
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005079 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005080 LOG_BAD_TU(TU);
5081 return cxstring::createEmpty();
5082 }
5083
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 // We have to find the starting buffer pointer the hard way, by
5085 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005086 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005088 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005089
5090 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5091 std::pair<FileID, unsigned> LocInfo
5092 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5093 bool Invalid = false;
5094 StringRef Buffer
5095 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5096 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005097 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005098
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005099 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005100}
5101
5102CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005103 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005104 LOG_BAD_TU(TU);
5105 return clang_getNullLocation();
5106 }
5107
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005108 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 if (!CXXUnit)
5110 return clang_getNullLocation();
5111
5112 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5113 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5114}
5115
5116CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005117 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005118 LOG_BAD_TU(TU);
5119 return clang_getNullRange();
5120 }
5121
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005122 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 if (!CXXUnit)
5124 return clang_getNullRange();
5125
5126 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5127 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5128}
5129
5130static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5131 SmallVectorImpl<CXToken> &CXTokens) {
5132 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5133 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005134 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005136 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005137
5138 // Cannot tokenize across files.
5139 if (BeginLocInfo.first != EndLocInfo.first)
5140 return;
5141
5142 // Create a lexer
5143 bool Invalid = false;
5144 StringRef Buffer
5145 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5146 if (Invalid)
5147 return;
5148
5149 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5150 CXXUnit->getASTContext().getLangOpts(),
5151 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5152 Lex.SetCommentRetentionState(true);
5153
5154 // Lex tokens until we hit the end of the range.
5155 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5156 Token Tok;
5157 bool previousWasAt = false;
5158 do {
5159 // Lex the next token
5160 Lex.LexFromRawLexer(Tok);
5161 if (Tok.is(tok::eof))
5162 break;
5163
5164 // Initialize the CXToken.
5165 CXToken CXTok;
5166
5167 // - Common fields
5168 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5169 CXTok.int_data[2] = Tok.getLength();
5170 CXTok.int_data[3] = 0;
5171
5172 // - Kind-specific fields
5173 if (Tok.isLiteral()) {
5174 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005175 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 } else if (Tok.is(tok::raw_identifier)) {
5177 // Lookup the identifier to determine whether we have a keyword.
5178 IdentifierInfo *II
5179 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5180
5181 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5182 CXTok.int_data[0] = CXToken_Keyword;
5183 }
5184 else {
5185 CXTok.int_data[0] = Tok.is(tok::identifier)
5186 ? CXToken_Identifier
5187 : CXToken_Keyword;
5188 }
5189 CXTok.ptr_data = II;
5190 } else if (Tok.is(tok::comment)) {
5191 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005192 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 } else {
5194 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005195 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 }
5197 CXTokens.push_back(CXTok);
5198 previousWasAt = Tok.is(tok::at);
5199 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5200}
5201
5202void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5203 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005204 LOG_FUNC_SECTION {
5205 *Log << TU << ' ' << Range;
5206 }
5207
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005209 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 if (NumTokens)
5211 *NumTokens = 0;
5212
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005213 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005214 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005215 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005216 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005217
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005218 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 if (!CXXUnit || !Tokens || !NumTokens)
5220 return;
5221
5222 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5223
5224 SourceRange R = cxloc::translateCXSourceRange(Range);
5225 if (R.isInvalid())
5226 return;
5227
5228 SmallVector<CXToken, 32> CXTokens;
5229 getTokens(CXXUnit, R, CXTokens);
5230
5231 if (CXTokens.empty())
5232 return;
5233
5234 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5235 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5236 *NumTokens = CXTokens.size();
5237}
5238
5239void clang_disposeTokens(CXTranslationUnit TU,
5240 CXToken *Tokens, unsigned NumTokens) {
5241 free(Tokens);
5242}
5243
5244} // end: extern "C"
5245
5246//===----------------------------------------------------------------------===//
5247// Token annotation APIs.
5248//===----------------------------------------------------------------------===//
5249
Guy Benyei11169dd2012-12-18 14:30:41 +00005250static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5251 CXCursor parent,
5252 CXClientData client_data);
5253static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5254 CXClientData client_data);
5255
5256namespace {
5257class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 CXToken *Tokens;
5259 CXCursor *Cursors;
5260 unsigned NumTokens;
5261 unsigned TokIdx;
5262 unsigned PreprocessingTokIdx;
5263 CursorVisitor AnnotateVis;
5264 SourceManager &SrcMgr;
5265 bool HasContextSensitiveKeywords;
5266
5267 struct PostChildrenInfo {
5268 CXCursor Cursor;
5269 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005270 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 unsigned BeforeChildrenTokenIdx;
5272 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005273 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005274
5275 CXToken &getTok(unsigned Idx) {
5276 assert(Idx < NumTokens);
5277 return Tokens[Idx];
5278 }
5279 const CXToken &getTok(unsigned Idx) const {
5280 assert(Idx < NumTokens);
5281 return Tokens[Idx];
5282 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 bool MoreTokens() const { return TokIdx < NumTokens; }
5284 unsigned NextToken() const { return TokIdx; }
5285 void AdvanceToken() { ++TokIdx; }
5286 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005287 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 }
5289 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005290 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 }
5292 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005293 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 }
5295
5296 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005297 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 SourceRange);
5299
5300public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005301 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005302 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005303 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005305 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 AnnotateTokensVisitor, this,
5307 /*VisitPreprocessorLast=*/true,
5308 /*VisitIncludedEntities=*/false,
5309 RegionOfInterest,
5310 /*VisitDeclsOnly=*/false,
5311 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005312 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 HasContextSensitiveKeywords(false) { }
5314
5315 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5316 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5317 bool postVisitChildren(CXCursor cursor);
5318 void AnnotateTokens();
5319
5320 /// \brief Determine whether the annotator saw any cursors that have
5321 /// context-sensitive keywords.
5322 bool hasContextSensitiveKeywords() const {
5323 return HasContextSensitiveKeywords;
5324 }
5325
5326 ~AnnotateTokensWorker() {
5327 assert(PostChildrenInfos.empty());
5328 }
5329};
5330}
5331
5332void AnnotateTokensWorker::AnnotateTokens() {
5333 // Walk the AST within the region of interest, annotating tokens
5334 // along the way.
5335 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005336}
Guy Benyei11169dd2012-12-18 14:30:41 +00005337
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005338static inline void updateCursorAnnotation(CXCursor &Cursor,
5339 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005340 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005342 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005343}
5344
5345/// \brief It annotates and advances tokens with a cursor until the comparison
5346//// between the cursor location and the source range is the same as
5347/// \arg compResult.
5348///
5349/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5350/// Pass RangeOverlap to annotate tokens inside a range.
5351void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5352 RangeComparisonResult compResult,
5353 SourceRange range) {
5354 while (MoreTokens()) {
5355 const unsigned I = NextToken();
5356 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005357 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5358 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005359
5360 SourceLocation TokLoc = GetTokenLoc(I);
5361 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005362 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 AdvanceToken();
5364 continue;
5365 }
5366 break;
5367 }
5368}
5369
5370/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005371/// \returns true if it advanced beyond all macro tokens, false otherwise.
5372bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 CXCursor updateC,
5374 RangeComparisonResult compResult,
5375 SourceRange range) {
5376 assert(MoreTokens());
5377 assert(isFunctionMacroToken(NextToken()) &&
5378 "Should be called only for macro arg tokens");
5379
5380 // This works differently than annotateAndAdvanceTokens; because expanded
5381 // macro arguments can have arbitrary translation-unit source order, we do not
5382 // advance the token index one by one until a token fails the range test.
5383 // We only advance once past all of the macro arg tokens if all of them
5384 // pass the range test. If one of them fails we keep the token index pointing
5385 // at the start of the macro arg tokens so that the failing token will be
5386 // annotated by a subsequent annotation try.
5387
5388 bool atLeastOneCompFail = false;
5389
5390 unsigned I = NextToken();
5391 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5392 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5393 if (TokLoc.isFileID())
5394 continue; // not macro arg token, it's parens or comma.
5395 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5396 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5397 Cursors[I] = updateC;
5398 } else
5399 atLeastOneCompFail = true;
5400 }
5401
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005402 if (atLeastOneCompFail)
5403 return false;
5404
5405 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5406 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005407}
5408
5409enum CXChildVisitResult
5410AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005411 SourceRange cursorRange = getRawCursorExtent(cursor);
5412 if (cursorRange.isInvalid())
5413 return CXChildVisit_Recurse;
5414
5415 if (!HasContextSensitiveKeywords) {
5416 // Objective-C properties can have context-sensitive keywords.
5417 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005418 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5420 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5421 }
5422 // Objective-C methods can have context-sensitive keywords.
5423 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5424 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5427 if (Method->getObjCDeclQualifier())
5428 HasContextSensitiveKeywords = true;
5429 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005430 for (const auto *P : Method->params()) {
5431 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 HasContextSensitiveKeywords = true;
5433 break;
5434 }
5435 }
5436 }
5437 }
5438 }
5439 // C++ methods can have context-sensitive keywords.
5440 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005441 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5443 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5444 HasContextSensitiveKeywords = true;
5445 }
5446 }
5447 // C++ classes can have context-sensitive keywords.
5448 else if (cursor.kind == CXCursor_StructDecl ||
5449 cursor.kind == CXCursor_ClassDecl ||
5450 cursor.kind == CXCursor_ClassTemplate ||
5451 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005452 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 if (D->hasAttr<FinalAttr>())
5454 HasContextSensitiveKeywords = true;
5455 }
5456 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005457
5458 // Don't override a property annotation with its getter/setter method.
5459 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5460 parent.kind == CXCursor_ObjCPropertyDecl)
5461 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005462
5463 if (clang_isPreprocessing(cursor.kind)) {
5464 // Items in the preprocessing record are kept separate from items in
5465 // declarations, so we keep a separate token index.
5466 unsigned SavedTokIdx = TokIdx;
5467 TokIdx = PreprocessingTokIdx;
5468
5469 // Skip tokens up until we catch up to the beginning of the preprocessing
5470 // entry.
5471 while (MoreTokens()) {
5472 const unsigned I = NextToken();
5473 SourceLocation TokLoc = GetTokenLoc(I);
5474 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5475 case RangeBefore:
5476 AdvanceToken();
5477 continue;
5478 case RangeAfter:
5479 case RangeOverlap:
5480 break;
5481 }
5482 break;
5483 }
5484
5485 // Look at all of the tokens within this range.
5486 while (MoreTokens()) {
5487 const unsigned I = NextToken();
5488 SourceLocation TokLoc = GetTokenLoc(I);
5489 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5490 case RangeBefore:
5491 llvm_unreachable("Infeasible");
5492 case RangeAfter:
5493 break;
5494 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005495 // For macro expansions, just note where the beginning of the macro
5496 // expansion occurs.
5497 if (cursor.kind == CXCursor_MacroExpansion) {
5498 if (TokLoc == cursorRange.getBegin())
5499 Cursors[I] = cursor;
5500 AdvanceToken();
5501 break;
5502 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005503 // We may have already annotated macro names inside macro definitions.
5504 if (Cursors[I].kind != CXCursor_MacroExpansion)
5505 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 continue;
5508 }
5509 break;
5510 }
5511
5512 // Save the preprocessing token index; restore the non-preprocessing
5513 // token index.
5514 PreprocessingTokIdx = TokIdx;
5515 TokIdx = SavedTokIdx;
5516 return CXChildVisit_Recurse;
5517 }
5518
5519 if (cursorRange.isInvalid())
5520 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005521
5522 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 const enum CXCursorKind K = clang_getCursorKind(parent);
5525 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005526 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5527 // Attributes are annotated out-of-order, skip tokens until we reach it.
5528 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 ? clang_getNullCursor() : parent;
5530
5531 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5532
5533 // Avoid having the cursor of an expression "overwrite" the annotation of the
5534 // variable declaration that it belongs to.
5535 // This can happen for C++ constructor expressions whose range generally
5536 // include the variable declaration, e.g.:
5537 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005538 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005539 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005540 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 const unsigned I = NextToken();
5542 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5543 E->getLocStart() == D->getLocation() &&
5544 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005545 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 AdvanceToken();
5547 }
5548 }
5549 }
5550
5551 // Before recursing into the children keep some state that we are going
5552 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5553 // extra work after the child nodes are visited.
5554 // Note that we don't call VisitChildren here to avoid traversing statements
5555 // code-recursively which can blow the stack.
5556
5557 PostChildrenInfo Info;
5558 Info.Cursor = cursor;
5559 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005560 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 Info.BeforeChildrenTokenIdx = NextToken();
5562 PostChildrenInfos.push_back(Info);
5563
5564 return CXChildVisit_Recurse;
5565}
5566
5567bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5568 if (PostChildrenInfos.empty())
5569 return false;
5570 const PostChildrenInfo &Info = PostChildrenInfos.back();
5571 if (!clang_equalCursors(Info.Cursor, cursor))
5572 return false;
5573
5574 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5575 const unsigned AfterChildren = NextToken();
5576 SourceRange cursorRange = Info.CursorRange;
5577
5578 // Scan the tokens that are at the end of the cursor, but are not captured
5579 // but the child cursors.
5580 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5581
5582 // Scan the tokens that are at the beginning of the cursor, but are not
5583 // capture by the child cursors.
5584 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5585 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5586 break;
5587
5588 Cursors[I] = cursor;
5589 }
5590
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005591 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5592 // encountered the attribute cursor.
5593 if (clang_isAttribute(cursor.kind))
5594 TokIdx = Info.BeforeReachingCursorIdx;
5595
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 PostChildrenInfos.pop_back();
5597 return false;
5598}
5599
5600static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5601 CXCursor parent,
5602 CXClientData client_data) {
5603 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5604}
5605
5606static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5607 CXClientData client_data) {
5608 return static_cast<AnnotateTokensWorker*>(client_data)->
5609 postVisitChildren(cursor);
5610}
5611
5612namespace {
5613
5614/// \brief Uses the macro expansions in the preprocessing record to find
5615/// and mark tokens that are macro arguments. This info is used by the
5616/// AnnotateTokensWorker.
5617class MarkMacroArgTokensVisitor {
5618 SourceManager &SM;
5619 CXToken *Tokens;
5620 unsigned NumTokens;
5621 unsigned CurIdx;
5622
5623public:
5624 MarkMacroArgTokensVisitor(SourceManager &SM,
5625 CXToken *tokens, unsigned numTokens)
5626 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5627
5628 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5629 if (cursor.kind != CXCursor_MacroExpansion)
5630 return CXChildVisit_Continue;
5631
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005632 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 if (macroRange.getBegin() == macroRange.getEnd())
5634 return CXChildVisit_Continue; // it's not a function macro.
5635
5636 for (; CurIdx < NumTokens; ++CurIdx) {
5637 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5638 macroRange.getBegin()))
5639 break;
5640 }
5641
5642 if (CurIdx == NumTokens)
5643 return CXChildVisit_Break;
5644
5645 for (; CurIdx < NumTokens; ++CurIdx) {
5646 SourceLocation tokLoc = getTokenLoc(CurIdx);
5647 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5648 break;
5649
5650 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5651 }
5652
5653 if (CurIdx == NumTokens)
5654 return CXChildVisit_Break;
5655
5656 return CXChildVisit_Continue;
5657 }
5658
5659private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005660 CXToken &getTok(unsigned Idx) {
5661 assert(Idx < NumTokens);
5662 return Tokens[Idx];
5663 }
5664 const CXToken &getTok(unsigned Idx) const {
5665 assert(Idx < NumTokens);
5666 return Tokens[Idx];
5667 }
5668
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005670 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 }
5672
5673 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5674 // The third field is reserved and currently not used. Use it here
5675 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005676 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 }
5678};
5679
5680} // end anonymous namespace
5681
5682static CXChildVisitResult
5683MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5684 CXClientData client_data) {
5685 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5686 parent);
5687}
5688
5689namespace {
5690 struct clang_annotateTokens_Data {
5691 CXTranslationUnit TU;
5692 ASTUnit *CXXUnit;
5693 CXToken *Tokens;
5694 unsigned NumTokens;
5695 CXCursor *Cursors;
5696 };
5697}
5698
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699/// \brief Used by \c annotatePreprocessorTokens.
5700/// \returns true if lexing was finished, false otherwise.
5701static bool lexNext(Lexer &Lex, Token &Tok,
5702 unsigned &NextIdx, unsigned NumTokens) {
5703 if (NextIdx >= NumTokens)
5704 return true;
5705
5706 ++NextIdx;
5707 Lex.LexFromRawLexer(Tok);
5708 if (Tok.is(tok::eof))
5709 return true;
5710
5711 return false;
5712}
5713
Guy Benyei11169dd2012-12-18 14:30:41 +00005714static void annotatePreprocessorTokens(CXTranslationUnit TU,
5715 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005716 CXCursor *Cursors,
5717 CXToken *Tokens,
5718 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005719 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005720
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005721 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5723 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005724 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005726 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005727
5728 if (BeginLocInfo.first != EndLocInfo.first)
5729 return;
5730
5731 StringRef Buffer;
5732 bool Invalid = false;
5733 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5734 if (Buffer.empty() || Invalid)
5735 return;
5736
5737 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5738 CXXUnit->getASTContext().getLangOpts(),
5739 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5740 Buffer.end());
5741 Lex.SetCommentRetentionState(true);
5742
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005743 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 // Lex tokens in raw mode until we hit the end of the range, to avoid
5745 // entering #includes or expanding macros.
5746 while (true) {
5747 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005748 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5749 break;
5750 unsigned TokIdx = NextIdx-1;
5751 assert(Tok.getLocation() ==
5752 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005753
5754 reprocess:
5755 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005756 // We have found a preprocessing directive. Annotate the tokens
5757 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 //
5759 // FIXME: Some simple tests here could identify macro definitions and
5760 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005761
5762 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005763 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5764 break;
5765
Craig Topper69186e72014-06-08 08:38:04 +00005766 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005767 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005768 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5769 break;
5770
5771 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005772 IdentifierInfo &II =
5773 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005774 SourceLocation MappedTokLoc =
5775 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5776 MI = getMacroInfo(II, MappedTokLoc, TU);
5777 }
5778 }
5779
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005780 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005782 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5783 finished = true;
5784 break;
5785 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005786 // If we are in a macro definition, check if the token was ever a
5787 // macro name and annotate it if that's the case.
5788 if (MI) {
5789 SourceLocation SaveLoc = Tok.getLocation();
5790 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5791 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5792 Tok.setLocation(SaveLoc);
5793 if (MacroDef)
5794 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5795 Tok.getLocation(), TU);
5796 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005797 } while (!Tok.isAtStartOfLine());
5798
5799 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5800 assert(TokIdx <= LastIdx);
5801 SourceLocation EndLoc =
5802 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5803 CXCursor Cursor =
5804 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5805
5806 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005807 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005808
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005809 if (finished)
5810 break;
5811 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 }
5814}
5815
5816// This gets run a separate thread to avoid stack blowout.
5817static void clang_annotateTokensImpl(void *UserData) {
5818 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5819 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5820 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5821 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5822 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5823
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005824 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005825 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5826 setThreadBackgroundPriority();
5827
5828 // Determine the region of interest, which contains all of the tokens.
5829 SourceRange RegionOfInterest;
5830 RegionOfInterest.setBegin(
5831 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5832 RegionOfInterest.setEnd(
5833 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5834 Tokens[NumTokens-1])));
5835
Guy Benyei11169dd2012-12-18 14:30:41 +00005836 // Relex the tokens within the source range to look for preprocessing
5837 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005838 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005839
5840 // If begin location points inside a macro argument, set it to the expansion
5841 // location so we can have the full context when annotating semantically.
5842 {
5843 SourceManager &SM = CXXUnit->getSourceManager();
5844 SourceLocation Loc =
5845 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5846 if (Loc.isMacroID())
5847 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5848 }
5849
Guy Benyei11169dd2012-12-18 14:30:41 +00005850 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5851 // Search and mark tokens that are macro argument expansions.
5852 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5853 Tokens, NumTokens);
5854 CursorVisitor MacroArgMarker(TU,
5855 MarkMacroArgTokensVisitorDelegate, &Visitor,
5856 /*VisitPreprocessorLast=*/true,
5857 /*VisitIncludedEntities=*/false,
5858 RegionOfInterest);
5859 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5860 }
5861
5862 // Annotate all of the source locations in the region of interest that map to
5863 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005864 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005865
5866 // FIXME: We use a ridiculous stack size here because the data-recursion
5867 // algorithm uses a large stack frame than the non-data recursive version,
5868 // and AnnotationTokensWorker currently transforms the data-recursion
5869 // algorithm back into a traditional recursion by explicitly calling
5870 // VisitChildren(). We will need to remove this explicit recursive call.
5871 W.AnnotateTokens();
5872
5873 // If we ran into any entities that involve context-sensitive keywords,
5874 // take another pass through the tokens to mark them as such.
5875 if (W.hasContextSensitiveKeywords()) {
5876 for (unsigned I = 0; I != NumTokens; ++I) {
5877 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5878 continue;
5879
5880 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5881 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005882 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5884 if (Property->getPropertyAttributesAsWritten() != 0 &&
5885 llvm::StringSwitch<bool>(II->getName())
5886 .Case("readonly", true)
5887 .Case("assign", true)
5888 .Case("unsafe_unretained", true)
5889 .Case("readwrite", true)
5890 .Case("retain", true)
5891 .Case("copy", true)
5892 .Case("nonatomic", true)
5893 .Case("atomic", true)
5894 .Case("getter", true)
5895 .Case("setter", true)
5896 .Case("strong", true)
5897 .Case("weak", true)
5898 .Default(false))
5899 Tokens[I].int_data[0] = CXToken_Keyword;
5900 }
5901 continue;
5902 }
5903
5904 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5905 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5906 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5907 if (llvm::StringSwitch<bool>(II->getName())
5908 .Case("in", true)
5909 .Case("out", true)
5910 .Case("inout", true)
5911 .Case("oneway", true)
5912 .Case("bycopy", true)
5913 .Case("byref", true)
5914 .Default(false))
5915 Tokens[I].int_data[0] = CXToken_Keyword;
5916 continue;
5917 }
5918
5919 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5920 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5921 Tokens[I].int_data[0] = CXToken_Keyword;
5922 continue;
5923 }
5924 }
5925 }
5926}
5927
5928extern "C" {
5929
5930void clang_annotateTokens(CXTranslationUnit TU,
5931 CXToken *Tokens, unsigned NumTokens,
5932 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005933 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005934 LOG_BAD_TU(TU);
5935 return;
5936 }
5937 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005938 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005940 }
5941
5942 LOG_FUNC_SECTION {
5943 *Log << TU << ' ';
5944 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5945 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5946 *Log << clang_getRange(bloc, eloc);
5947 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005948
5949 // Any token we don't specifically annotate will have a NULL cursor.
5950 CXCursor C = clang_getNullCursor();
5951 for (unsigned I = 0; I != NumTokens; ++I)
5952 Cursors[I] = C;
5953
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005954 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 if (!CXXUnit)
5956 return;
5957
5958 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5959
5960 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5961 llvm::CrashRecoveryContext CRC;
5962 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5963 GetSafetyThreadStackSize() * 2)) {
5964 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5965 }
5966}
5967
5968} // end: extern "C"
5969
5970//===----------------------------------------------------------------------===//
5971// Operations for querying linkage of a cursor.
5972//===----------------------------------------------------------------------===//
5973
5974extern "C" {
5975CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5976 if (!clang_isDeclaration(cursor.kind))
5977 return CXLinkage_Invalid;
5978
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005979 const Decl *D = cxcursor::getCursorDecl(cursor);
5980 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005981 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005982 case NoLinkage:
5983 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005984 case InternalLinkage: return CXLinkage_Internal;
5985 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5986 case ExternalLinkage: return CXLinkage_External;
5987 };
5988
5989 return CXLinkage_Invalid;
5990}
5991} // end: extern "C"
5992
5993//===----------------------------------------------------------------------===//
5994// Operations for querying language of a cursor.
5995//===----------------------------------------------------------------------===//
5996
5997static CXLanguageKind getDeclLanguage(const Decl *D) {
5998 if (!D)
5999 return CXLanguage_C;
6000
6001 switch (D->getKind()) {
6002 default:
6003 break;
6004 case Decl::ImplicitParam:
6005 case Decl::ObjCAtDefsField:
6006 case Decl::ObjCCategory:
6007 case Decl::ObjCCategoryImpl:
6008 case Decl::ObjCCompatibleAlias:
6009 case Decl::ObjCImplementation:
6010 case Decl::ObjCInterface:
6011 case Decl::ObjCIvar:
6012 case Decl::ObjCMethod:
6013 case Decl::ObjCProperty:
6014 case Decl::ObjCPropertyImpl:
6015 case Decl::ObjCProtocol:
6016 return CXLanguage_ObjC;
6017 case Decl::CXXConstructor:
6018 case Decl::CXXConversion:
6019 case Decl::CXXDestructor:
6020 case Decl::CXXMethod:
6021 case Decl::CXXRecord:
6022 case Decl::ClassTemplate:
6023 case Decl::ClassTemplatePartialSpecialization:
6024 case Decl::ClassTemplateSpecialization:
6025 case Decl::Friend:
6026 case Decl::FriendTemplate:
6027 case Decl::FunctionTemplate:
6028 case Decl::LinkageSpec:
6029 case Decl::Namespace:
6030 case Decl::NamespaceAlias:
6031 case Decl::NonTypeTemplateParm:
6032 case Decl::StaticAssert:
6033 case Decl::TemplateTemplateParm:
6034 case Decl::TemplateTypeParm:
6035 case Decl::UnresolvedUsingTypename:
6036 case Decl::UnresolvedUsingValue:
6037 case Decl::Using:
6038 case Decl::UsingDirective:
6039 case Decl::UsingShadow:
6040 return CXLanguage_CPlusPlus;
6041 }
6042
6043 return CXLanguage_C;
6044}
6045
6046extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006047
6048static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6049 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6050 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006051
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006052 switch (D->getAvailability()) {
6053 case AR_Available:
6054 case AR_NotYetIntroduced:
6055 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006056 return getCursorAvailabilityForDecl(
6057 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006058 return CXAvailability_Available;
6059
6060 case AR_Deprecated:
6061 return CXAvailability_Deprecated;
6062
6063 case AR_Unavailable:
6064 return CXAvailability_NotAvailable;
6065 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006066
6067 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006068}
6069
Guy Benyei11169dd2012-12-18 14:30:41 +00006070enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6071 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006072 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6073 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006074
6075 return CXAvailability_Available;
6076}
6077
6078static CXVersion convertVersion(VersionTuple In) {
6079 CXVersion Out = { -1, -1, -1 };
6080 if (In.empty())
6081 return Out;
6082
6083 Out.Major = In.getMajor();
6084
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006085 Optional<unsigned> Minor = In.getMinor();
6086 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 Out.Minor = *Minor;
6088 else
6089 return Out;
6090
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006091 Optional<unsigned> Subminor = In.getSubminor();
6092 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 Out.Subminor = *Subminor;
6094
6095 return Out;
6096}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097
6098static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6099 int *always_deprecated,
6100 CXString *deprecated_message,
6101 int *always_unavailable,
6102 CXString *unavailable_message,
6103 CXPlatformAvailability *availability,
6104 int availability_size) {
6105 bool HadAvailAttr = false;
6106 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006107 for (auto A : D->attrs()) {
6108 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006109 HadAvailAttr = true;
6110 if (always_deprecated)
6111 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006112 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006113 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006114 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006115 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006116 continue;
6117 }
6118
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006119 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006120 HadAvailAttr = true;
6121 if (always_unavailable)
6122 *always_unavailable = 1;
6123 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006124 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006125 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6126 }
6127 continue;
6128 }
6129
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006130 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006131 HadAvailAttr = true;
6132 if (N < availability_size) {
6133 availability[N].Platform
6134 = cxstring::createDup(Avail->getPlatform()->getName());
6135 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6136 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6137 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6138 availability[N].Unavailable = Avail->getUnavailable();
6139 availability[N].Message = cxstring::createDup(Avail->getMessage());
6140 }
6141 ++N;
6142 }
6143 }
6144
6145 if (!HadAvailAttr)
6146 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6147 return getCursorPlatformAvailabilityForDecl(
6148 cast<Decl>(EnumConst->getDeclContext()),
6149 always_deprecated,
6150 deprecated_message,
6151 always_unavailable,
6152 unavailable_message,
6153 availability,
6154 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006155
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006156 return N;
6157}
6158
Guy Benyei11169dd2012-12-18 14:30:41 +00006159int clang_getCursorPlatformAvailability(CXCursor cursor,
6160 int *always_deprecated,
6161 CXString *deprecated_message,
6162 int *always_unavailable,
6163 CXString *unavailable_message,
6164 CXPlatformAvailability *availability,
6165 int availability_size) {
6166 if (always_deprecated)
6167 *always_deprecated = 0;
6168 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006169 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 if (always_unavailable)
6171 *always_unavailable = 0;
6172 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006173 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006174
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 if (!clang_isDeclaration(cursor.kind))
6176 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006177
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006178 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 if (!D)
6180 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006181
6182 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6183 deprecated_message,
6184 always_unavailable,
6185 unavailable_message,
6186 availability,
6187 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006188}
6189
6190void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6191 clang_disposeString(availability->Platform);
6192 clang_disposeString(availability->Message);
6193}
6194
6195CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6196 if (clang_isDeclaration(cursor.kind))
6197 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6198
6199 return CXLanguage_Invalid;
6200}
6201
6202 /// \brief If the given cursor is the "templated" declaration
6203 /// descibing a class or function template, return the class or
6204 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006205static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006207 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006208
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006209 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6211 return FunTmpl;
6212
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006213 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6215 return ClassTmpl;
6216
6217 return D;
6218}
6219
6220CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6221 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006222 if (const Decl *D = getCursorDecl(cursor)) {
6223 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 if (!DC)
6225 return clang_getNullCursor();
6226
6227 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6228 getCursorTU(cursor));
6229 }
6230 }
6231
6232 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006233 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006234 return MakeCXCursor(D, getCursorTU(cursor));
6235 }
6236
6237 return clang_getNullCursor();
6238}
6239
6240CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6241 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006242 if (const Decl *D = getCursorDecl(cursor)) {
6243 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006244 if (!DC)
6245 return clang_getNullCursor();
6246
6247 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6248 getCursorTU(cursor));
6249 }
6250 }
6251
6252 // FIXME: Note that we can't easily compute the lexical context of a
6253 // statement or expression, so we return nothing.
6254 return clang_getNullCursor();
6255}
6256
6257CXFile clang_getIncludedFile(CXCursor cursor) {
6258 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006259 return nullptr;
6260
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006261 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006262 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006263}
6264
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006265unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6266 if (C.kind != CXCursor_ObjCPropertyDecl)
6267 return CXObjCPropertyAttr_noattr;
6268
6269 unsigned Result = CXObjCPropertyAttr_noattr;
6270 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6271 ObjCPropertyDecl::PropertyAttributeKind Attr =
6272 PD->getPropertyAttributesAsWritten();
6273
6274#define SET_CXOBJCPROP_ATTR(A) \
6275 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6276 Result |= CXObjCPropertyAttr_##A
6277 SET_CXOBJCPROP_ATTR(readonly);
6278 SET_CXOBJCPROP_ATTR(getter);
6279 SET_CXOBJCPROP_ATTR(assign);
6280 SET_CXOBJCPROP_ATTR(readwrite);
6281 SET_CXOBJCPROP_ATTR(retain);
6282 SET_CXOBJCPROP_ATTR(copy);
6283 SET_CXOBJCPROP_ATTR(nonatomic);
6284 SET_CXOBJCPROP_ATTR(setter);
6285 SET_CXOBJCPROP_ATTR(atomic);
6286 SET_CXOBJCPROP_ATTR(weak);
6287 SET_CXOBJCPROP_ATTR(strong);
6288 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6289#undef SET_CXOBJCPROP_ATTR
6290
6291 return Result;
6292}
6293
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006294unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6295 if (!clang_isDeclaration(C.kind))
6296 return CXObjCDeclQualifier_None;
6297
6298 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6299 const Decl *D = getCursorDecl(C);
6300 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6301 QT = MD->getObjCDeclQualifier();
6302 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6303 QT = PD->getObjCDeclQualifier();
6304 if (QT == Decl::OBJC_TQ_None)
6305 return CXObjCDeclQualifier_None;
6306
6307 unsigned Result = CXObjCDeclQualifier_None;
6308 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6309 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6310 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6311 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6312 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6313 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6314
6315 return Result;
6316}
6317
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006318unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6319 if (!clang_isDeclaration(C.kind))
6320 return 0;
6321
6322 const Decl *D = getCursorDecl(C);
6323 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6324 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6325 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6326 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6327
6328 return 0;
6329}
6330
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006331unsigned clang_Cursor_isVariadic(CXCursor C) {
6332 if (!clang_isDeclaration(C.kind))
6333 return 0;
6334
6335 const Decl *D = getCursorDecl(C);
6336 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6337 return FD->isVariadic();
6338 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6339 return MD->isVariadic();
6340
6341 return 0;
6342}
6343
Guy Benyei11169dd2012-12-18 14:30:41 +00006344CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6345 if (!clang_isDeclaration(C.kind))
6346 return clang_getNullRange();
6347
6348 const Decl *D = getCursorDecl(C);
6349 ASTContext &Context = getCursorContext(C);
6350 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6351 if (!RC)
6352 return clang_getNullRange();
6353
6354 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6355}
6356
6357CXString clang_Cursor_getRawCommentText(CXCursor C) {
6358 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006359 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006360
6361 const Decl *D = getCursorDecl(C);
6362 ASTContext &Context = getCursorContext(C);
6363 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6364 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6365 StringRef();
6366
6367 // Don't duplicate the string because RawText points directly into source
6368 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006369 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006370}
6371
6372CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6373 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006374 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375
6376 const Decl *D = getCursorDecl(C);
6377 const ASTContext &Context = getCursorContext(C);
6378 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6379
6380 if (RC) {
6381 StringRef BriefText = RC->getBriefText(Context);
6382
6383 // Don't duplicate the string because RawComment ensures that this memory
6384 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006385 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006386 }
6387
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006388 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006389}
6390
Guy Benyei11169dd2012-12-18 14:30:41 +00006391CXModule clang_Cursor_getModule(CXCursor C) {
6392 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006393 if (const ImportDecl *ImportD =
6394 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 return ImportD->getImportedModule();
6396 }
6397
Craig Topper69186e72014-06-08 08:38:04 +00006398 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006399}
6400
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006401CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6402 if (isNotUsableTU(TU)) {
6403 LOG_BAD_TU(TU);
6404 return nullptr;
6405 }
6406 if (!File)
6407 return nullptr;
6408 FileEntry *FE = static_cast<FileEntry *>(File);
6409
6410 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6411 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6412 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6413
6414 if (Module *Mod = Header.getModule()) {
6415 if (Header.getRole() != ModuleMap::ExcludedHeader)
6416 return Mod;
6417 }
6418 return nullptr;
6419}
6420
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006421CXFile clang_Module_getASTFile(CXModule CXMod) {
6422 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006423 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006424 Module *Mod = static_cast<Module*>(CXMod);
6425 return const_cast<FileEntry *>(Mod->getASTFile());
6426}
6427
Guy Benyei11169dd2012-12-18 14:30:41 +00006428CXModule clang_Module_getParent(CXModule CXMod) {
6429 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006430 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 Module *Mod = static_cast<Module*>(CXMod);
6432 return Mod->Parent;
6433}
6434
6435CXString clang_Module_getName(CXModule CXMod) {
6436 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006437 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006439 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006440}
6441
6442CXString clang_Module_getFullName(CXModule CXMod) {
6443 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006444 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006445 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006446 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006447}
6448
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006449int clang_Module_isSystem(CXModule CXMod) {
6450 if (!CXMod)
6451 return 0;
6452 Module *Mod = static_cast<Module*>(CXMod);
6453 return Mod->IsSystem;
6454}
6455
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006456unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6457 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006458 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006459 LOG_BAD_TU(TU);
6460 return 0;
6461 }
6462 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006463 return 0;
6464 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006465 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6466 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6467 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006468}
6469
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006470CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6471 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006472 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006473 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006474 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006475 }
6476 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006477 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006479 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006480
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006481 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6482 if (Index < TopHeaders.size())
6483 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006484
Craig Topper69186e72014-06-08 08:38:04 +00006485 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006486}
6487
6488} // end: extern "C"
6489
6490//===----------------------------------------------------------------------===//
6491// C++ AST instrospection.
6492//===----------------------------------------------------------------------===//
6493
6494extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006495unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6496 if (!clang_isDeclaration(C.kind))
6497 return 0;
6498
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006499 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006500 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006501 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006502 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6503}
6504
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006505unsigned clang_CXXMethod_isConst(CXCursor C) {
6506 if (!clang_isDeclaration(C.kind))
6507 return 0;
6508
6509 const Decl *D = cxcursor::getCursorDecl(C);
6510 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006511 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006512 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6513}
6514
Guy Benyei11169dd2012-12-18 14:30:41 +00006515unsigned clang_CXXMethod_isStatic(CXCursor C) {
6516 if (!clang_isDeclaration(C.kind))
6517 return 0;
6518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006519 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006520 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006521 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 return (Method && Method->isStatic()) ? 1 : 0;
6523}
6524
6525unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6526 if (!clang_isDeclaration(C.kind))
6527 return 0;
6528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006529 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006530 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006531 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006532 return (Method && Method->isVirtual()) ? 1 : 0;
6533}
6534} // end: extern "C"
6535
6536//===----------------------------------------------------------------------===//
6537// Attribute introspection.
6538//===----------------------------------------------------------------------===//
6539
6540extern "C" {
6541CXType clang_getIBOutletCollectionType(CXCursor C) {
6542 if (C.kind != CXCursor_IBOutletCollectionAttr)
6543 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6544
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006545 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6547
6548 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6549}
6550} // end: extern "C"
6551
6552//===----------------------------------------------------------------------===//
6553// Inspecting memory usage.
6554//===----------------------------------------------------------------------===//
6555
6556typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6557
6558static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6559 enum CXTUResourceUsageKind k,
6560 unsigned long amount) {
6561 CXTUResourceUsageEntry entry = { k, amount };
6562 entries.push_back(entry);
6563}
6564
6565extern "C" {
6566
6567const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6568 const char *str = "";
6569 switch (kind) {
6570 case CXTUResourceUsage_AST:
6571 str = "ASTContext: expressions, declarations, and types";
6572 break;
6573 case CXTUResourceUsage_Identifiers:
6574 str = "ASTContext: identifiers";
6575 break;
6576 case CXTUResourceUsage_Selectors:
6577 str = "ASTContext: selectors";
6578 break;
6579 case CXTUResourceUsage_GlobalCompletionResults:
6580 str = "Code completion: cached global results";
6581 break;
6582 case CXTUResourceUsage_SourceManagerContentCache:
6583 str = "SourceManager: content cache allocator";
6584 break;
6585 case CXTUResourceUsage_AST_SideTables:
6586 str = "ASTContext: side tables";
6587 break;
6588 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6589 str = "SourceManager: malloc'ed memory buffers";
6590 break;
6591 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6592 str = "SourceManager: mmap'ed memory buffers";
6593 break;
6594 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6595 str = "ExternalASTSource: malloc'ed memory buffers";
6596 break;
6597 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6598 str = "ExternalASTSource: mmap'ed memory buffers";
6599 break;
6600 case CXTUResourceUsage_Preprocessor:
6601 str = "Preprocessor: malloc'ed memory";
6602 break;
6603 case CXTUResourceUsage_PreprocessingRecord:
6604 str = "Preprocessor: PreprocessingRecord";
6605 break;
6606 case CXTUResourceUsage_SourceManager_DataStructures:
6607 str = "SourceManager: data structures and tables";
6608 break;
6609 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6610 str = "Preprocessor: header search tables";
6611 break;
6612 }
6613 return str;
6614}
6615
6616CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006617 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006618 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006619 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 return usage;
6621 }
6622
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006623 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006624 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 ASTContext &astContext = astUnit->getASTContext();
6626
6627 // How much memory is used by AST nodes and types?
6628 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6629 (unsigned long) astContext.getASTAllocatedMemory());
6630
6631 // How much memory is used by identifiers?
6632 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6633 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6634
6635 // How much memory is used for selectors?
6636 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6637 (unsigned long) astContext.Selectors.getTotalMemory());
6638
6639 // How much memory is used by ASTContext's side tables?
6640 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6641 (unsigned long) astContext.getSideTableAllocatedMemory());
6642
6643 // How much memory is used for caching global code completion results?
6644 unsigned long completionBytes = 0;
6645 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006646 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 completionBytes = completionAllocator->getTotalMemory();
6648 }
6649 createCXTUResourceUsageEntry(*entries,
6650 CXTUResourceUsage_GlobalCompletionResults,
6651 completionBytes);
6652
6653 // How much memory is being used by SourceManager's content cache?
6654 createCXTUResourceUsageEntry(*entries,
6655 CXTUResourceUsage_SourceManagerContentCache,
6656 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6657
6658 // How much memory is being used by the MemoryBuffer's in SourceManager?
6659 const SourceManager::MemoryBufferSizes &srcBufs =
6660 astUnit->getSourceManager().getMemoryBufferSizes();
6661
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6664 (unsigned long) srcBufs.malloc_bytes);
6665 createCXTUResourceUsageEntry(*entries,
6666 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6667 (unsigned long) srcBufs.mmap_bytes);
6668 createCXTUResourceUsageEntry(*entries,
6669 CXTUResourceUsage_SourceManager_DataStructures,
6670 (unsigned long) astContext.getSourceManager()
6671 .getDataStructureSizes());
6672
6673 // How much memory is being used by the ExternalASTSource?
6674 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6675 const ExternalASTSource::MemoryBufferSizes &sizes =
6676 esrc->getMemoryBufferSizes();
6677
6678 createCXTUResourceUsageEntry(*entries,
6679 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6680 (unsigned long) sizes.malloc_bytes);
6681 createCXTUResourceUsageEntry(*entries,
6682 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6683 (unsigned long) sizes.mmap_bytes);
6684 }
6685
6686 // How much memory is being used by the Preprocessor?
6687 Preprocessor &pp = astUnit->getPreprocessor();
6688 createCXTUResourceUsageEntry(*entries,
6689 CXTUResourceUsage_Preprocessor,
6690 pp.getTotalMemory());
6691
6692 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6693 createCXTUResourceUsageEntry(*entries,
6694 CXTUResourceUsage_PreprocessingRecord,
6695 pRec->getTotalMemory());
6696 }
6697
6698 createCXTUResourceUsageEntry(*entries,
6699 CXTUResourceUsage_Preprocessor_HeaderSearch,
6700 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006701
Guy Benyei11169dd2012-12-18 14:30:41 +00006702 CXTUResourceUsage usage = { (void*) entries.get(),
6703 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006704 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006705 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006706 return usage;
6707}
6708
6709void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6710 if (usage.data)
6711 delete (MemUsageEntries*) usage.data;
6712}
6713
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006714CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6715 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006716 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006717 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006718
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006719 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006720 LOG_BAD_TU(TU);
6721 return skipped;
6722 }
6723
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006724 if (!file)
6725 return skipped;
6726
6727 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6728 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6729 if (!ppRec)
6730 return skipped;
6731
6732 ASTContext &Ctx = astUnit->getASTContext();
6733 SourceManager &sm = Ctx.getSourceManager();
6734 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6735 FileID wantedFileID = sm.translateFile(fileEntry);
6736
6737 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6738 std::vector<SourceRange> wantedRanges;
6739 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6740 i != ei; ++i) {
6741 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6742 wantedRanges.push_back(*i);
6743 }
6744
6745 skipped->count = wantedRanges.size();
6746 skipped->ranges = new CXSourceRange[skipped->count];
6747 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6748 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6749
6750 return skipped;
6751}
6752
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006753void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6754 if (ranges) {
6755 delete[] ranges->ranges;
6756 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006757 }
6758}
6759
Guy Benyei11169dd2012-12-18 14:30:41 +00006760} // end extern "C"
6761
6762void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6763 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6764 for (unsigned I = 0; I != Usage.numEntries; ++I)
6765 fprintf(stderr, " %s: %lu\n",
6766 clang_getTUResourceUsageName(Usage.entries[I].kind),
6767 Usage.entries[I].amount);
6768
6769 clang_disposeCXTUResourceUsage(Usage);
6770}
6771
6772//===----------------------------------------------------------------------===//
6773// Misc. utility functions.
6774//===----------------------------------------------------------------------===//
6775
6776/// Default to using an 8 MB stack size on "safety" threads.
6777static unsigned SafetyStackThreadSize = 8 << 20;
6778
6779namespace clang {
6780
6781bool RunSafely(llvm::CrashRecoveryContext &CRC,
6782 void (*Fn)(void*), void *UserData,
6783 unsigned Size) {
6784 if (!Size)
6785 Size = GetSafetyThreadStackSize();
6786 if (Size)
6787 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6788 return CRC.RunSafely(Fn, UserData);
6789}
6790
6791unsigned GetSafetyThreadStackSize() {
6792 return SafetyStackThreadSize;
6793}
6794
6795void SetSafetyThreadStackSize(unsigned Value) {
6796 SafetyStackThreadSize = Value;
6797}
6798
6799}
6800
6801void clang::setThreadBackgroundPriority() {
6802 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6803 return;
6804
Alp Toker1a86ad22014-07-06 06:24:00 +00006805#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6807#endif
6808}
6809
6810void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6811 if (!Unit)
6812 return;
6813
6814 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6815 DEnd = Unit->stored_diag_end();
6816 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006817 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 CXString Msg = clang_formatDiagnostic(&Diag,
6819 clang_defaultDiagnosticDisplayOptions());
6820 fprintf(stderr, "%s\n", clang_getCString(Msg));
6821 clang_disposeString(Msg);
6822 }
6823#ifdef LLVM_ON_WIN32
6824 // On Windows, force a flush, since there may be multiple copies of
6825 // stderr and stdout in the file system, all with different buffers
6826 // but writing to the same device.
6827 fflush(stderr);
6828#endif
6829}
6830
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006831MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6832 SourceLocation MacroDefLoc,
6833 CXTranslationUnit TU){
6834 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006836 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006837 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006838
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006839 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006840 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006841 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006842 if (MD) {
6843 for (MacroDirective::DefInfo
6844 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6845 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6846 return Def.getMacroInfo();
6847 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006848 }
6849
Craig Topper69186e72014-06-08 08:38:04 +00006850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851}
6852
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006853const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6854 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006855 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006856 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006857 const IdentifierInfo *II = MacroDef->getName();
6858 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006860
6861 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6862}
6863
6864MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6865 const Token &Tok,
6866 CXTranslationUnit TU) {
6867 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006869 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006870 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006871
6872 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006874 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6875 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006876 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877
6878 // Check that the token is inside the definition and not its argument list.
6879 SourceManager &SM = Unit->getSourceManager();
6880 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006881 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884
6885 Preprocessor &PP = Unit->getPreprocessor();
6886 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6887 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006888 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006889
Alp Toker2d57cea2014-05-17 04:53:25 +00006890 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006891 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006892 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006893
6894 // Check that the identifier is not one of the macro arguments.
6895 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006896 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006897
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006898 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6899 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006900 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006901
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006902 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006903}
6904
6905MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6906 SourceLocation Loc,
6907 CXTranslationUnit TU) {
6908 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006909 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006910
6911 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006912 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006913 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006914 Preprocessor &PP = Unit->getPreprocessor();
6915 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006916 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006917 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6918 Token Tok;
6919 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006920 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006921
6922 return checkForMacroInMacroDefinition(MI, Tok, TU);
6923}
6924
Guy Benyei11169dd2012-12-18 14:30:41 +00006925extern "C" {
6926
6927CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006928 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006929}
6930
6931} // end: extern "C"
6932
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006933Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6934 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006935 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006936 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006937 if (Unit->isMainFileAST())
6938 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006939 return *this;
6940 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006941 } else {
6942 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006943 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006944 return *this;
6945}
6946
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006947Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6948 *this << FE->getName();
6949 return *this;
6950}
6951
6952Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6953 CXString cursorName = clang_getCursorDisplayName(cursor);
6954 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6955 clang_disposeString(cursorName);
6956 return *this;
6957}
6958
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006959Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6960 CXFile File;
6961 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006962 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006963 CXString FileName = clang_getFileName(File);
6964 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6965 clang_disposeString(FileName);
6966 return *this;
6967}
6968
6969Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6970 CXSourceLocation BLoc = clang_getRangeStart(range);
6971 CXSourceLocation ELoc = clang_getRangeEnd(range);
6972
6973 CXFile BFile;
6974 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006975 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006976
6977 CXFile EFile;
6978 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006979 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006980
6981 CXString BFileName = clang_getFileName(BFile);
6982 if (BFile == EFile) {
6983 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6984 BLine, BColumn, ELine, EColumn);
6985 } else {
6986 CXString EFileName = clang_getFileName(EFile);
6987 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6988 BLine, BColumn)
6989 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6990 ELine, EColumn);
6991 clang_disposeString(EFileName);
6992 }
6993 clang_disposeString(BFileName);
6994 return *this;
6995}
6996
6997Logger &cxindex::Logger::operator<<(CXString Str) {
6998 *this << clang_getCString(Str);
6999 return *this;
7000}
7001
7002Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7003 LogOS << Fmt;
7004 return *this;
7005}
7006
Chandler Carruth37ad2582014-06-27 15:14:39 +00007007static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7008
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007009cxindex::Logger::~Logger() {
7010 LogOS.flush();
7011
Chandler Carruth37ad2582014-06-27 15:14:39 +00007012 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007013
7014 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7015
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007016 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007017 OS << "[libclang:" << Name << ':';
7018
Alp Toker1a86ad22014-07-06 06:24:00 +00007019#ifdef USE_DARWIN_THREADS
7020 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007021 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7022 OS << tid << ':';
7023#endif
7024
7025 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7026 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7027 OS << Msg.str() << '\n';
7028
7029 if (Trace) {
7030 llvm::sys::PrintStackTrace(stderr);
7031 OS << "--------------------------------------------------\n";
7032 }
7033}