blob: 2b7c8f50bbc4763bd80895bb67989d96de3f7176 [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"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Program.h"
49#include "llvm/Support/SaveAndRestore.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/Support/Threading.h"
52#include "llvm/Support/Timer.h"
53#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000054
Alp Toker1d257e12014-06-04 03:28:55 +000055#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000056#include <pthread.h>
57#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000058
59using namespace clang;
60using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000061using namespace clang::cxtu;
62using namespace clang::cxindex;
63
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000064CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
65 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000066 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000067 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000068 CXTranslationUnit D = new CXTranslationUnitImpl();
69 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000070 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000071 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000072 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000074 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000075 return D;
76}
77
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000078bool cxtu::isASTReadError(ASTUnit *AU) {
79 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
80 DEnd = AU->stored_diag_end();
81 D != DEnd; ++D) {
82 if (D->getLevel() >= DiagnosticsEngine::Error &&
83 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
84 diag::DiagCat_AST_Deserialization_Issue)
85 return true;
86 }
87 return false;
88}
89
Guy Benyei11169dd2012-12-18 14:30:41 +000090cxtu::CXTUOwner::~CXTUOwner() {
91 if (TU)
92 clang_disposeTranslationUnit(TU);
93}
94
95/// \brief Compare two source ranges to determine their relative position in
96/// the translation unit.
97static RangeComparisonResult RangeCompare(SourceManager &SM,
98 SourceRange R1,
99 SourceRange R2) {
100 assert(R1.isValid() && "First range is invalid?");
101 assert(R2.isValid() && "Second range is invalid?");
102 if (R1.getEnd() != R2.getBegin() &&
103 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
104 return RangeBefore;
105 if (R2.getEnd() != R1.getBegin() &&
106 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
107 return RangeAfter;
108 return RangeOverlap;
109}
110
111/// \brief Determine if a source location falls within, before, or after a
112/// a given source range.
113static RangeComparisonResult LocationCompare(SourceManager &SM,
114 SourceLocation L, SourceRange R) {
115 assert(R.isValid() && "First range is invalid?");
116 assert(L.isValid() && "Second range is invalid?");
117 if (L == R.getBegin() || L == R.getEnd())
118 return RangeOverlap;
119 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
120 return RangeBefore;
121 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
122 return RangeAfter;
123 return RangeOverlap;
124}
125
126/// \brief Translate a Clang source range into a CIndex source range.
127///
128/// Clang internally represents ranges where the end location points to the
129/// start of the token at the end. However, for external clients it is more
130/// useful to have a CXSourceRange be a proper half-open interval. This routine
131/// does the appropriate translation.
132CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
133 const LangOptions &LangOpts,
134 const CharSourceRange &R) {
135 // We want the last character in this location, so we will adjust the
136 // location accordingly.
137 SourceLocation EndLoc = R.getEnd();
138 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
139 EndLoc = SM.getExpansionRange(EndLoc).second;
140 if (R.isTokenRange() && !EndLoc.isInvalid()) {
141 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
142 SM, LangOpts);
143 EndLoc = EndLoc.getLocWithOffset(Length);
144 }
145
Bill Wendlingeade3622013-01-23 08:25:41 +0000146 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000147 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000148 R.getBegin().getRawEncoding(),
149 EndLoc.getRawEncoding()
150 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 return Result;
152}
153
154//===----------------------------------------------------------------------===//
155// Cursor visitor.
156//===----------------------------------------------------------------------===//
157
158static SourceRange getRawCursorExtent(CXCursor C);
159static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
160
161
162RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
163 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
164}
165
166/// \brief Visit the given cursor and, if requested by the visitor,
167/// its children.
168///
169/// \param Cursor the cursor to visit.
170///
171/// \param CheckedRegionOfInterest if true, then the caller already checked
172/// that this cursor is within the region of interest.
173///
174/// \returns true if the visitation should be aborted, false if it
175/// should continue.
176bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
177 if (clang_isInvalid(Cursor.kind))
178 return false;
179
180 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000181 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000182 if (!D) {
183 assert(0 && "Invalid declaration cursor");
184 return true; // abort.
185 }
186
187 // Ignore implicit declarations, unless it's an objc method because
188 // currently we should report implicit methods for properties when indexing.
189 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
190 return false;
191 }
192
193 // If we have a range of interest, and this cursor doesn't intersect with it,
194 // we're done.
195 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
196 SourceRange Range = getRawCursorExtent(Cursor);
197 if (Range.isInvalid() || CompareRegionOfInterest(Range))
198 return false;
199 }
200
201 switch (Visitor(Cursor, Parent, ClientData)) {
202 case CXChildVisit_Break:
203 return true;
204
205 case CXChildVisit_Continue:
206 return false;
207
208 case CXChildVisit_Recurse: {
209 bool ret = VisitChildren(Cursor);
210 if (PostChildrenVisitor)
211 if (PostChildrenVisitor(Cursor, ClientData))
212 return true;
213 return ret;
214 }
215 }
216
217 llvm_unreachable("Invalid CXChildVisitResult!");
218}
219
220static bool visitPreprocessedEntitiesInRange(SourceRange R,
221 PreprocessingRecord &PPRec,
222 CursorVisitor &Visitor) {
223 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
224 FileID FID;
225
226 if (!Visitor.shouldVisitIncludedEntities()) {
227 // If the begin/end of the range lie in the same FileID, do the optimization
228 // where we skip preprocessed entities that do not come from the same FileID.
229 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
230 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
231 FID = FileID();
232 }
233
234 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
235 Entities = PPRec.getPreprocessedEntitiesInRange(R);
236 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
237 PPRec, FID);
238}
239
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000240bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000241 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000242 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000243
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000244 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 SourceManager &SM = Unit->getSourceManager();
246
247 std::pair<FileID, unsigned>
248 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
249 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
250
251 if (End.first != Begin.first) {
252 // If the end does not reside in the same file, try to recover by
253 // picking the end of the file of begin location.
254 End.first = Begin.first;
255 End.second = SM.getFileIDSize(Begin.first);
256 }
257
258 assert(Begin.first == End.first);
259 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000260 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000261
262 FileID File = Begin.first;
263 unsigned Offset = Begin.second;
264 unsigned Length = End.second - Begin.second;
265
266 if (!VisitDeclsOnly && !VisitPreprocessorLast)
267 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000270 if (visitDeclsFromFileRegion(File, Offset, Length))
271 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000272
273 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return visitPreprocessedEntitiesInRegion();
275
276 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000277}
278
279static bool isInLexicalContext(Decl *D, DeclContext *DC) {
280 if (!DC)
281 return false;
282
283 for (DeclContext *DeclDC = D->getLexicalDeclContext();
284 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
285 if (DeclDC == DC)
286 return true;
287 }
288 return false;
289}
290
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000291bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000292 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000293 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000294 SourceManager &SM = Unit->getSourceManager();
295 SourceRange Range = RegionOfInterest;
296
297 SmallVector<Decl *, 16> Decls;
298 Unit->findFileRegionDecls(File, Offset, Length, Decls);
299
300 // If we didn't find any file level decls for the file, try looking at the
301 // file that it was included from.
302 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
303 bool Invalid = false;
304 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
305 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000306 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000307
308 SourceLocation Outer;
309 if (SLEntry.isFile())
310 Outer = SLEntry.getFile().getIncludeLoc();
311 else
312 Outer = SLEntry.getExpansion().getExpansionLocStart();
313 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000316 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000317 Length = 0;
318 Unit->findFileRegionDecls(File, Offset, Length, Decls);
319 }
320
321 assert(!Decls.empty());
322
323 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000324 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000325 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
326 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000327 Decl *D = *DIt;
328 if (D->getSourceRange().isInvalid())
329 continue;
330
331 if (isInLexicalContext(D, CurDC))
332 continue;
333
334 CurDC = dyn_cast<DeclContext>(D);
335
336 if (TagDecl *TD = dyn_cast<TagDecl>(D))
337 if (!TD->isFreeStanding())
338 continue;
339
340 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
341 if (CompRes == RangeBefore)
342 continue;
343 if (CompRes == RangeAfter)
344 break;
345
346 assert(CompRes == RangeOverlap);
347 VisitedAtLeastOnce = true;
348
349 if (isa<ObjCContainerDecl>(D)) {
350 FileDI_current = &DIt;
351 FileDE_current = DE;
352 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000353 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000354 }
355
356 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000357 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000358 }
359
360 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000361 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362
363 // No Decls overlapped with the range. Move up the lexical context until there
364 // is a context that contains the range or we reach the translation unit
365 // level.
366 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
367 : (*(DIt-1))->getLexicalDeclContext();
368
369 while (DC && !DC->isTranslationUnit()) {
370 Decl *D = cast<Decl>(DC);
371 SourceRange CurDeclRange = D->getSourceRange();
372 if (CurDeclRange.isInvalid())
373 break;
374
375 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000376 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
377 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000378 }
379
380 DC = D->getLexicalDeclContext();
381 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382
383 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000384}
385
386bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
387 if (!AU->getPreprocessor().getPreprocessingRecord())
388 return false;
389
390 PreprocessingRecord &PPRec
391 = *AU->getPreprocessor().getPreprocessingRecord();
392 SourceManager &SM = AU->getSourceManager();
393
394 if (RegionOfInterest.isValid()) {
395 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
396 SourceLocation B = MappedRange.getBegin();
397 SourceLocation E = MappedRange.getEnd();
398
399 if (AU->isInPreambleFileID(B)) {
400 if (SM.isLoadedSourceLocation(E))
401 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
402 PPRec, *this);
403
404 // Beginning of range lies in the preamble but it also extends beyond
405 // it into the main file. Split the range into 2 parts, one covering
406 // the preamble and another covering the main file. This allows subsequent
407 // calls to visitPreprocessedEntitiesInRange to accept a source range that
408 // lies in the same FileID, allowing it to skip preprocessed entities that
409 // do not come from the same FileID.
410 bool breaked =
411 visitPreprocessedEntitiesInRange(
412 SourceRange(B, AU->getEndOfPreambleFileID()),
413 PPRec, *this);
414 if (breaked) return true;
415 return visitPreprocessedEntitiesInRange(
416 SourceRange(AU->getStartOfMainFileID(), E),
417 PPRec, *this);
418 }
419
420 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
421 }
422
423 bool OnlyLocalDecls
424 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
425
426 if (OnlyLocalDecls)
427 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
428 PPRec);
429
430 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
431}
432
433template<typename InputIterator>
434bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
435 InputIterator Last,
436 PreprocessingRecord &PPRec,
437 FileID FID) {
438 for (; First != Last; ++First) {
439 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
440 continue;
441
442 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000443 if (!PPE)
444 continue;
445
Guy Benyei11169dd2012-12-18 14:30:41 +0000446 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
447 if (Visit(MakeMacroExpansionCursor(ME, TU)))
448 return true;
449
450 continue;
451 }
452
453 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
454 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
455 return true;
456
457 continue;
458 }
459
460 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
461 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
462 return true;
463
464 continue;
465 }
466 }
467
468 return false;
469}
470
471/// \brief Visit the children of the given cursor.
472///
473/// \returns true if the visitation should be aborted, false if it
474/// should continue.
475bool CursorVisitor::VisitChildren(CXCursor Cursor) {
476 if (clang_isReference(Cursor.kind) &&
477 Cursor.kind != CXCursor_CXXBaseSpecifier) {
478 // By definition, references have no children.
479 return false;
480 }
481
482 // Set the Parent field to Cursor, then back to its old value once we're
483 // done.
484 SetParentRAII SetParent(Parent, StmtParent, Cursor);
485
486 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000487 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 if (!D)
489 return false;
490
491 return VisitAttributes(D) || Visit(D);
492 }
493
494 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000495 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 return Visit(S);
497
498 return false;
499 }
500
501 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000502 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000503 return Visit(E);
504
505 return false;
506 }
507
508 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000509 CXTranslationUnit TU = getCursorTU(Cursor);
510 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000511
512 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
513 for (unsigned I = 0; I != 2; ++I) {
514 if (VisitOrder[I]) {
515 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
516 RegionOfInterest.isInvalid()) {
517 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
518 TLEnd = CXXUnit->top_level_end();
519 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000520 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000521 return true;
522 }
523 } else if (VisitDeclContext(
524 CXXUnit->getASTContext().getTranslationUnitDecl()))
525 return true;
526 continue;
527 }
528
529 // Walk the preprocessing record.
530 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
531 visitPreprocessedEntitiesInRegion();
532 }
533
534 return false;
535 }
536
537 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000538 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000539 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
540 return Visit(BaseTSInfo->getTypeLoc());
541 }
542 }
543 }
544
545 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000546 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000548 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000549 return Visit(cxcursor::MakeCursorObjCClassRef(
550 ObjT->getInterface(),
551 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 }
553
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000554 // If pointing inside a macro definition, check if the token is an identifier
555 // that was ever defined as a macro. In such a case, create a "pseudo" macro
556 // expansion cursor for that token.
557 SourceLocation BeginLoc = RegionOfInterest.getBegin();
558 if (Cursor.kind == CXCursor_MacroDefinition &&
559 BeginLoc == RegionOfInterest.getEnd()) {
560 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000561 const MacroInfo *MI =
562 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 if (MacroDefinition *MacroDef =
564 checkForMacroInMacroDefinition(MI, Loc, TU))
565 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
566 }
567
Guy Benyei11169dd2012-12-18 14:30:41 +0000568 // Nothing to visit at the moment.
569 return false;
570}
571
572bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
573 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
574 if (Visit(TSInfo->getTypeLoc()))
575 return true;
576
577 if (Stmt *Body = B->getBody())
578 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
579
580 return false;
581}
582
Ted Kremenek03325582013-02-21 01:29:01 +0000583Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000584 if (RegionOfInterest.isValid()) {
585 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
586 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000587 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000588
589 switch (CompareRegionOfInterest(Range)) {
590 case RangeBefore:
591 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 case RangeAfter:
595 // This declaration comes after the region of interest; we're done.
596 return false;
597
598 case RangeOverlap:
599 // This declaration overlaps the region of interest; visit it.
600 break;
601 }
602 }
603 return true;
604}
605
606bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
607 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
608
609 // FIXME: Eventually remove. This part of a hack to support proper
610 // iteration over all Decls contained lexically within an ObjC container.
611 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
612 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
613
614 for ( ; I != E; ++I) {
615 Decl *D = *I;
616 if (D->getLexicalDeclContext() != DC)
617 continue;
618 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
619
620 // Ignore synthesized ivars here, otherwise if we have something like:
621 // @synthesize prop = _prop;
622 // and '_prop' is not declared, we will encounter a '_prop' ivar before
623 // encountering the 'prop' synthesize declaration and we will think that
624 // we passed the region-of-interest.
625 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
626 if (ivarD->getSynthesize())
627 continue;
628 }
629
630 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
631 // declarations is a mismatch with the compiler semantics.
632 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
633 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
634 if (!ID->isThisDeclarationADefinition())
635 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
636
637 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
638 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
639 if (!PD->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
641 }
642
Ted Kremenek03325582013-02-21 01:29:01 +0000643 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000644 if (!V.hasValue())
645 continue;
646 if (!V.getValue())
647 return false;
648 if (Visit(Cursor, true))
649 return true;
650 }
651 return false;
652}
653
654bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
655 llvm_unreachable("Translation units are visited directly by Visit()");
656}
657
658bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
659 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
660 return Visit(TSInfo->getTypeLoc());
661
662 return false;
663}
664
665bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
666 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
667 return Visit(TSInfo->getTypeLoc());
668
669 return false;
670}
671
672bool CursorVisitor::VisitTagDecl(TagDecl *D) {
673 return VisitDeclContext(D);
674}
675
676bool CursorVisitor::VisitClassTemplateSpecializationDecl(
677 ClassTemplateSpecializationDecl *D) {
678 bool ShouldVisitBody = false;
679 switch (D->getSpecializationKind()) {
680 case TSK_Undeclared:
681 case TSK_ImplicitInstantiation:
682 // Nothing to visit
683 return false;
684
685 case TSK_ExplicitInstantiationDeclaration:
686 case TSK_ExplicitInstantiationDefinition:
687 break;
688
689 case TSK_ExplicitSpecialization:
690 ShouldVisitBody = true;
691 break;
692 }
693
694 // Visit the template arguments used in the specialization.
695 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
696 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000697 if (TemplateSpecializationTypeLoc TSTLoc =
698 TL.getAs<TemplateSpecializationTypeLoc>()) {
699 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
700 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000701 return true;
702 }
703 }
704
705 if (ShouldVisitBody && VisitCXXRecordDecl(D))
706 return true;
707
708 return false;
709}
710
711bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
712 ClassTemplatePartialSpecializationDecl *D) {
713 // FIXME: Visit the "outer" template parameter lists on the TagDecl
714 // before visiting these template parameters.
715 if (VisitTemplateParameters(D->getTemplateParameters()))
716 return true;
717
718 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000719 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
720 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
721 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000722 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
723 return true;
724
725 return VisitCXXRecordDecl(D);
726}
727
728bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
729 // Visit the default argument.
730 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
731 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
732 if (Visit(DefArg->getTypeLoc()))
733 return true;
734
735 return false;
736}
737
738bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
739 if (Expr *Init = D->getInitExpr())
740 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
741 return false;
742}
743
744bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000745 unsigned NumParamList = DD->getNumTemplateParameterLists();
746 for (unsigned i = 0; i < NumParamList; i++) {
747 TemplateParameterList* Params = DD->getTemplateParameterList(i);
748 if (VisitTemplateParameters(Params))
749 return true;
750 }
751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
753 if (Visit(TSInfo->getTypeLoc()))
754 return true;
755
756 // Visit the nested-name-specifier, if present.
757 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
758 if (VisitNestedNameSpecifierLoc(QualifierLoc))
759 return true;
760
761 return false;
762}
763
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000764/// \brief Compare two base or member initializers based on their source order.
765static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
766 CXXCtorInitializer *const *Y) {
767 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
768}
769
Guy Benyei11169dd2012-12-18 14:30:41 +0000770bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000771 unsigned NumParamList = ND->getNumTemplateParameterLists();
772 for (unsigned i = 0; i < NumParamList; i++) {
773 TemplateParameterList* Params = ND->getTemplateParameterList(i);
774 if (VisitTemplateParameters(Params))
775 return true;
776 }
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
779 // Visit the function declaration's syntactic components in the order
780 // written. This requires a bit of work.
781 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000782 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000783
784 // If we have a function declared directly (without the use of a typedef),
785 // visit just the return type. Otherwise, just visit the function's type
786 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000787 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 (!FTL && Visit(TL)))
789 return true;
790
791 // Visit the nested-name-specifier, if present.
792 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
793 if (VisitNestedNameSpecifierLoc(QualifierLoc))
794 return true;
795
796 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000797 if (!isa<CXXDestructorDecl>(ND))
798 if (VisitDeclarationNameInfo(ND->getNameInfo()))
799 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000800
801 // FIXME: Visit explicitly-specified template arguments!
802
803 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000804 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000805 return true;
806
Bill Wendling44426052012-12-20 19:22:21 +0000807 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000808 }
809
810 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
811 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
812 // Find the initializers that were written in the source.
813 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000814 for (auto *I : Constructor->inits()) {
815 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 continue;
817
Aaron Ballman0ad78302014-03-13 17:34:31 +0000818 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000819 }
820
821 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000822 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
823 &CompareCXXCtorInitializers);
824
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 // Visit the initializers in source order
826 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
827 CXXCtorInitializer *Init = WrittenInits[I];
828 if (Init->isAnyMemberInitializer()) {
829 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
830 Init->getMemberLocation(), TU)))
831 return true;
832 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
833 if (Visit(TInfo->getTypeLoc()))
834 return true;
835 }
836
837 // Visit the initializer value.
838 if (Expr *Initializer = Init->getInit())
839 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
840 return true;
841 }
842 }
843
844 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
845 return true;
846 }
847
848 return false;
849}
850
851bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
852 if (VisitDeclaratorDecl(D))
853 return true;
854
855 if (Expr *BitWidth = D->getBitWidth())
856 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
857
858 return false;
859}
860
861bool CursorVisitor::VisitVarDecl(VarDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *Init = D->getInit())
866 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
876 if (Expr *DefArg = D->getDefaultArgument())
877 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
878
879 return false;
880}
881
882bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
883 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
884 // before visiting these template parameters.
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 return VisitFunctionDecl(D->getTemplatedDecl());
889}
890
891bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the TagDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitCXXRecordDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
905 VisitTemplateArgumentLoc(D->getDefaultArgument()))
906 return true;
907
908 return false;
909}
910
911bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000912 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000913 if (Visit(TSInfo->getTypeLoc()))
914 return true;
915
Aaron Ballman43b68be2014-03-07 17:50:17 +0000916 for (const auto *P : ND->params()) {
917 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 return true;
919 }
920
921 if (ND->isThisDeclarationADefinition() &&
922 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
923 return true;
924
925 return false;
926}
927
928template <typename DeclIt>
929static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
930 SourceManager &SM, SourceLocation EndLoc,
931 SmallVectorImpl<Decl *> &Decls) {
932 DeclIt next = *DI_current;
933 while (++next != DE_current) {
934 Decl *D_next = *next;
935 if (!D_next)
936 break;
937 SourceLocation L = D_next->getLocStart();
938 if (!L.isValid())
939 break;
940 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
941 *DI_current = next;
942 Decls.push_back(D_next);
943 continue;
944 }
945 break;
946 }
947}
948
Guy Benyei11169dd2012-12-18 14:30:41 +0000949bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
950 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
951 // an @implementation can lexically contain Decls that are not properly
952 // nested in the AST. When we identify such cases, we need to retrofit
953 // this nesting here.
954 if (!DI_current && !FileDI_current)
955 return VisitDeclContext(D);
956
957 // Scan the Decls that immediately come after the container
958 // in the current DeclContext. If any fall within the
959 // container's lexical region, stash them into a vector
960 // for later processing.
961 SmallVector<Decl *, 24> DeclsInContainer;
962 SourceLocation EndLoc = D->getSourceRange().getEnd();
963 SourceManager &SM = AU->getSourceManager();
964 if (EndLoc.isValid()) {
965 if (DI_current) {
966 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
967 DeclsInContainer);
968 } else {
969 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
970 DeclsInContainer);
971 }
972 }
973
974 // The common case.
975 if (DeclsInContainer.empty())
976 return VisitDeclContext(D);
977
978 // Get all the Decls in the DeclContext, and sort them with the
979 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000980 for (auto *SubDecl : D->decls()) {
981 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
982 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000983 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000984 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000985 }
986
987 // Now sort the Decls so that they appear in lexical order.
988 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000989 [&SM](Decl *A, Decl *B) {
990 SourceLocation L_A = A->getLocStart();
991 SourceLocation L_B = B->getLocStart();
992 assert(L_A.isValid() && L_B.isValid());
993 return SM.isBeforeInTranslationUnit(L_A, L_B);
994 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000995
996 // Now visit the decls.
997 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
998 E = DeclsInContainer.end(); I != E; ++I) {
999 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001000 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!V.hasValue())
1002 continue;
1003 if (!V.getValue())
1004 return false;
1005 if (Visit(Cursor, true))
1006 return true;
1007 }
1008 return false;
1009}
1010
1011bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1012 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1013 TU)))
1014 return true;
1015
1016 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1017 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1018 E = ND->protocol_end(); I != E; ++I, ++PL)
1019 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1020 return true;
1021
1022 return VisitObjCContainerDecl(ND);
1023}
1024
1025bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1026 if (!PID->isThisDeclarationADefinition())
1027 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1028
1029 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1030 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1031 E = PID->protocol_end(); I != E; ++I, ++PL)
1032 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1033 return true;
1034
1035 return VisitObjCContainerDecl(PID);
1036}
1037
1038bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1039 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1040 return true;
1041
1042 // FIXME: This implements a workaround with @property declarations also being
1043 // installed in the DeclContext for the @interface. Eventually this code
1044 // should be removed.
1045 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1046 if (!CDecl || !CDecl->IsClassExtension())
1047 return false;
1048
1049 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1050 if (!ID)
1051 return false;
1052
1053 IdentifierInfo *PropertyId = PD->getIdentifier();
1054 ObjCPropertyDecl *prevDecl =
1055 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1056
1057 if (!prevDecl)
1058 return false;
1059
1060 // Visit synthesized methods since they will be skipped when visiting
1061 // the @interface.
1062 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1063 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1064 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1065 return true;
1066
1067 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1076 if (!D->isThisDeclarationADefinition()) {
1077 // Forward declaration is treated like a reference.
1078 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1079 }
1080
1081 // Issue callbacks for super class.
1082 if (D->getSuperClass() &&
1083 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1084 D->getSuperClassLoc(),
1085 TU)))
1086 return true;
1087
1088 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1089 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1090 E = D->protocol_end(); I != E; ++I, ++PL)
1091 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1092 return true;
1093
1094 return VisitObjCContainerDecl(D);
1095}
1096
1097bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1098 return VisitObjCContainerDecl(D);
1099}
1100
1101bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1102 // 'ID' could be null when dealing with invalid code.
1103 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1104 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1105 return true;
1106
1107 return VisitObjCImplDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1111#if 0
1112 // Issue callbacks for super class.
1113 // FIXME: No source location information!
1114 if (D->getSuperClass() &&
1115 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1116 D->getSuperClassLoc(),
1117 TU)))
1118 return true;
1119#endif
1120
1121 return VisitObjCImplDecl(D);
1122}
1123
1124bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1125 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1126 if (PD->isIvarNameSpecified())
1127 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1128
1129 return false;
1130}
1131
1132bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1133 return VisitDeclContext(D);
1134}
1135
1136bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1137 // Visit nested-name-specifier.
1138 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1139 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1140 return true;
1141
1142 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1143 D->getTargetNameLoc(), TU));
1144}
1145
1146bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1147 // Visit nested-name-specifier.
1148 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1149 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1150 return true;
1151 }
1152
1153 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1154 return true;
1155
1156 return VisitDeclarationNameInfo(D->getNameInfo());
1157}
1158
1159bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1160 // Visit nested-name-specifier.
1161 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1162 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1163 return true;
1164
1165 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1166 D->getIdentLocation(), TU));
1167}
1168
1169bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174 }
1175
1176 return VisitDeclarationNameInfo(D->getNameInfo());
1177}
1178
1179bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1180 UnresolvedUsingTypenameDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return false;
1187}
1188
1189bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1190 switch (Name.getName().getNameKind()) {
1191 case clang::DeclarationName::Identifier:
1192 case clang::DeclarationName::CXXLiteralOperatorName:
1193 case clang::DeclarationName::CXXOperatorName:
1194 case clang::DeclarationName::CXXUsingDirective:
1195 return false;
1196
1197 case clang::DeclarationName::CXXConstructorName:
1198 case clang::DeclarationName::CXXDestructorName:
1199 case clang::DeclarationName::CXXConversionFunctionName:
1200 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1201 return Visit(TSInfo->getTypeLoc());
1202 return false;
1203
1204 case clang::DeclarationName::ObjCZeroArgSelector:
1205 case clang::DeclarationName::ObjCOneArgSelector:
1206 case clang::DeclarationName::ObjCMultiArgSelector:
1207 // FIXME: Per-identifier location info?
1208 return false;
1209 }
1210
1211 llvm_unreachable("Invalid DeclarationName::Kind!");
1212}
1213
1214bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1215 SourceRange Range) {
1216 // FIXME: This whole routine is a hack to work around the lack of proper
1217 // source information in nested-name-specifiers (PR5791). Since we do have
1218 // a beginning source location, we can visit the first component of the
1219 // nested-name-specifier, if it's a single-token component.
1220 if (!NNS)
1221 return false;
1222
1223 // Get the first component in the nested-name-specifier.
1224 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1225 NNS = Prefix;
1226
1227 switch (NNS->getKind()) {
1228 case NestedNameSpecifier::Namespace:
1229 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1230 TU));
1231
1232 case NestedNameSpecifier::NamespaceAlias:
1233 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1234 Range.getBegin(), TU));
1235
1236 case NestedNameSpecifier::TypeSpec: {
1237 // If the type has a form where we know that the beginning of the source
1238 // range matches up with a reference cursor. Visit the appropriate reference
1239 // cursor.
1240 const Type *T = NNS->getAsType();
1241 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1242 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1243 if (const TagType *Tag = dyn_cast<TagType>(T))
1244 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1245 if (const TemplateSpecializationType *TST
1246 = dyn_cast<TemplateSpecializationType>(T))
1247 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1248 break;
1249 }
1250
1251 case NestedNameSpecifier::TypeSpecWithTemplate:
1252 case NestedNameSpecifier::Global:
1253 case NestedNameSpecifier::Identifier:
1254 break;
1255 }
1256
1257 return false;
1258}
1259
1260bool
1261CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1262 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1263 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1264 Qualifiers.push_back(Qualifier);
1265
1266 while (!Qualifiers.empty()) {
1267 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1268 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1269 switch (NNS->getKind()) {
1270 case NestedNameSpecifier::Namespace:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1272 Q.getLocalBeginLoc(),
1273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Q.getLocalBeginLoc(),
1281 TU)))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::TypeSpec:
1287 case NestedNameSpecifier::TypeSpecWithTemplate:
1288 if (Visit(Q.getTypeLoc()))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::Global:
1294 case NestedNameSpecifier::Identifier:
1295 break;
1296 }
1297 }
1298
1299 return false;
1300}
1301
1302bool CursorVisitor::VisitTemplateParameters(
1303 const TemplateParameterList *Params) {
1304 if (!Params)
1305 return false;
1306
1307 for (TemplateParameterList::const_iterator P = Params->begin(),
1308 PEnd = Params->end();
1309 P != PEnd; ++P) {
1310 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1311 return true;
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1318 switch (Name.getKind()) {
1319 case TemplateName::Template:
1320 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1321
1322 case TemplateName::OverloadedTemplate:
1323 // Visit the overloaded template set.
1324 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1325 return true;
1326
1327 return false;
1328
1329 case TemplateName::DependentTemplate:
1330 // FIXME: Visit nested-name-specifier.
1331 return false;
1332
1333 case TemplateName::QualifiedTemplate:
1334 // FIXME: Visit nested-name-specifier.
1335 return Visit(MakeCursorTemplateRef(
1336 Name.getAsQualifiedTemplateName()->getDecl(),
1337 Loc, TU));
1338
1339 case TemplateName::SubstTemplateTemplateParm:
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParmPack:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1347 Loc, TU));
1348 }
1349
1350 llvm_unreachable("Invalid TemplateName::Kind!");
1351}
1352
1353bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1354 switch (TAL.getArgument().getKind()) {
1355 case TemplateArgument::Null:
1356 case TemplateArgument::Integral:
1357 case TemplateArgument::Pack:
1358 return false;
1359
1360 case TemplateArgument::Type:
1361 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1362 return Visit(TSInfo->getTypeLoc());
1363 return false;
1364
1365 case TemplateArgument::Declaration:
1366 if (Expr *E = TAL.getSourceDeclExpression())
1367 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1368 return false;
1369
1370 case TemplateArgument::NullPtr:
1371 if (Expr *E = TAL.getSourceNullPtrExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::Expression:
1376 if (Expr *E = TAL.getSourceExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Template:
1381 case TemplateArgument::TemplateExpansion:
1382 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1383 return true;
1384
1385 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1386 TAL.getTemplateNameLoc());
1387 }
1388
1389 llvm_unreachable("Invalid TemplateArgument::Kind!");
1390}
1391
1392bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1393 return VisitDeclContext(D);
1394}
1395
1396bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1397 return Visit(TL.getUnqualifiedLoc());
1398}
1399
1400bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1401 ASTContext &Context = AU->getASTContext();
1402
1403 // Some builtin types (such as Objective-C's "id", "sel", and
1404 // "Class") have associated declarations. Create cursors for those.
1405 QualType VisitType;
1406 switch (TL.getTypePtr()->getKind()) {
1407
1408 case BuiltinType::Void:
1409 case BuiltinType::NullPtr:
1410 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001411 case BuiltinType::OCLImage1d:
1412 case BuiltinType::OCLImage1dArray:
1413 case BuiltinType::OCLImage1dBuffer:
1414 case BuiltinType::OCLImage2d:
1415 case BuiltinType::OCLImage2dArray:
1416 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001417 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001418 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001419#define BUILTIN_TYPE(Id, SingletonId)
1420#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#include "clang/AST/BuiltinTypes.def"
1425 break;
1426
1427 case BuiltinType::ObjCId:
1428 VisitType = Context.getObjCIdType();
1429 break;
1430
1431 case BuiltinType::ObjCClass:
1432 VisitType = Context.getObjCClassType();
1433 break;
1434
1435 case BuiltinType::ObjCSel:
1436 VisitType = Context.getObjCSelType();
1437 break;
1438 }
1439
1440 if (!VisitType.isNull()) {
1441 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1442 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1443 TU));
1444 }
1445
1446 return false;
1447}
1448
1449bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1450 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1458 if (TL.isDefinition())
1459 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1460
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1469 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1470 return true;
1471
1472 return false;
1473}
1474
1475bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1476 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1477 return true;
1478
1479 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1480 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1481 TU)))
1482 return true;
1483 }
1484
1485 return false;
1486}
1487
1488bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1493 return Visit(TL.getInnerLoc());
1494}
1495
1496bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1501 return Visit(TL.getPointeeLoc());
1502}
1503
1504bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1505 return Visit(TL.getPointeeLoc());
1506}
1507
1508bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1509 return Visit(TL.getPointeeLoc());
1510}
1511
1512bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1513 return Visit(TL.getPointeeLoc());
1514}
1515
1516bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1517 return Visit(TL.getModifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1521 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001522 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001523 return true;
1524
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001525 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1526 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001527 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1528 return true;
1529
1530 return false;
1531}
1532
1533bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1534 if (Visit(TL.getElementLoc()))
1535 return true;
1536
1537 if (Expr *Size = TL.getSizeExpr())
1538 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1539
1540 return false;
1541}
1542
Reid Kleckner8a365022013-06-24 17:51:48 +00001543bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1544 return Visit(TL.getOriginalLoc());
1545}
1546
Reid Kleckner0503a872013-12-05 01:23:43 +00001547bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1548 return Visit(TL.getOriginalLoc());
1549}
1550
Guy Benyei11169dd2012-12-18 14:30:41 +00001551bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1552 TemplateSpecializationTypeLoc TL) {
1553 // Visit the template name.
1554 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1555 TL.getTemplateNameLoc()))
1556 return true;
1557
1558 // Visit the template arguments.
1559 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1560 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1561 return true;
1562
1563 return false;
1564}
1565
1566bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1567 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1568}
1569
1570bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1571 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1572 return Visit(TSInfo->getTypeLoc());
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1585 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1592 DependentTemplateSpecializationTypeLoc TL) {
1593 // Visit the nested-name-specifier, if there is one.
1594 if (TL.getQualifierLoc() &&
1595 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 // Visit the template arguments.
1599 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1600 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1601 return true;
1602
1603 return false;
1604}
1605
1606bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1607 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1608 return true;
1609
1610 return Visit(TL.getNamedTypeLoc());
1611}
1612
1613bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1614 return Visit(TL.getPatternLoc());
1615}
1616
1617bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1618 if (Expr *E = TL.getUnderlyingExpr())
1619 return Visit(MakeCXCursor(E, StmtParent, TU));
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1625 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1626}
1627
1628bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1629 return Visit(TL.getValueLoc());
1630}
1631
1632#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1633bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1634 return Visit##PARENT##Loc(TL); \
1635}
1636
1637DEFAULT_TYPELOC_IMPL(Complex, Type)
1638DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1643DEFAULT_TYPELOC_IMPL(Vector, Type)
1644DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1645DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1646DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(Record, TagType)
1648DEFAULT_TYPELOC_IMPL(Enum, TagType)
1649DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1651DEFAULT_TYPELOC_IMPL(Auto, Type)
1652
1653bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1654 // Visit the nested-name-specifier, if present.
1655 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1656 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1657 return true;
1658
1659 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001660 for (const auto &I : D->bases()) {
1661 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001662 return true;
1663 }
1664 }
1665
1666 return VisitTagDecl(D);
1667}
1668
1669bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001670 for (const auto *I : D->attrs())
1671 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001706 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001801 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 VisitorWorkList &WL;
1803 CXCursor Parent;
1804public:
1805 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1806 : WL(wl), Parent(parent) {}
1807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1809 void VisitBlockExpr(const BlockExpr *B);
1810 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1811 void VisitCompoundStmt(const CompoundStmt *S);
1812 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1813 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1814 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1815 void VisitCXXNewExpr(const CXXNewExpr *E);
1816 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1817 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1818 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1819 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1820 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1821 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1822 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1823 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1824 void VisitDeclRefExpr(const DeclRefExpr *D);
1825 void VisitDeclStmt(const DeclStmt *S);
1826 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1827 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1828 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1829 void VisitForStmt(const ForStmt *FS);
1830 void VisitGotoStmt(const GotoStmt *GS);
1831 void VisitIfStmt(const IfStmt *If);
1832 void VisitInitListExpr(const InitListExpr *IE);
1833 void VisitMemberExpr(const MemberExpr *M);
1834 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1835 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1836 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1837 void VisitOverloadExpr(const OverloadExpr *E);
1838 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1839 void VisitStmt(const Stmt *S);
1840 void VisitSwitchStmt(const SwitchStmt *S);
1841 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001853 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001854 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001855 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001856 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857
Guy Benyei11169dd2012-12-18 14:30:41 +00001858private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1861 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1863 void AddStmt(const Stmt *S);
1864 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001867 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001868};
1869} // end anonyous namespace
1870
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 // 'S' should always be non-null, since it comes from the
1873 // statement we are visiting.
1874 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1875}
1876
1877void
1878EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1879 if (Qualifier)
1880 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1881}
1882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 if (S)
1885 WL.push_back(StmtVisit(S, Parent));
1886}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 if (D)
1889 WL.push_back(DeclVisit(D, Parent, isFirst));
1890}
1891void EnqueueVisitor::
1892 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1893 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001895}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 if (D)
1898 WL.push_back(MemberRefVisit(D, L, Parent));
1899}
1900void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1901 if (TI)
1902 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1903 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 AddStmt(*Child);
1908 }
1909 if (size == WL.size())
1910 return;
1911 // Now reverse the entries we just added. This will match the DFS
1912 // ordering performed by the worklist.
1913 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1914 std::reverse(I, E);
1915}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001916namespace {
1917class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1918 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001919 /// \brief Process clauses with list of variables.
1920 template <typename T>
1921 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001922public:
1923 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1924#define OPENMP_CLAUSE(Name, Class) \
1925 void Visit##Class(const Class *C);
1926#include "clang/Basic/OpenMPKinds.def"
1927};
1928
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001929void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1930 Visitor->AddStmt(C->getCondition());
1931}
1932
Alexey Bataev568a8332014-03-06 06:15:19 +00001933void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1934 Visitor->AddStmt(C->getNumThreads());
1935}
1936
Alexey Bataev62c87d22014-03-21 04:51:18 +00001937void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1938 Visitor->AddStmt(C->getSafelen());
1939}
1940
Alexander Musman8bd31e62014-05-27 15:12:19 +00001941void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1942 Visitor->AddStmt(C->getNumForLoops());
1943}
1944
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001946
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001947void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1948
Alexey Bataev56dafe82014-06-20 07:16:17 +00001949void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1950 Visitor->AddStmt(C->getChunkSize());
1951}
1952
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001953void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1954
Alexey Bataev236070f2014-06-20 11:19:47 +00001955void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1956
Alexey Bataev756c1962013-09-24 03:17:45 +00001957template<typename T>
1958void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001959 for (const auto *I : Node->varlists())
1960 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001961}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001962
1963void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001964 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001966void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1967 const OMPFirstprivateClause *C) {
1968 VisitOMPClauseList(C);
1969}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001970void OMPClauseEnqueue::VisitOMPLastprivateClause(
1971 const OMPLastprivateClause *C) {
1972 VisitOMPClauseList(C);
1973}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001974void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001975 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001976}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001977void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1978 VisitOMPClauseList(C);
1979}
Alexander Musman8dba6642014-04-22 13:09:42 +00001980void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1981 VisitOMPClauseList(C);
1982 Visitor->AddStmt(C->getStep());
1983}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001984void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1985 VisitOMPClauseList(C);
1986 Visitor->AddStmt(C->getAlignment());
1987}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001988void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1989 VisitOMPClauseList(C);
1990}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001991}
Alexey Bataev756c1962013-09-24 03:17:45 +00001992
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001993void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1994 unsigned size = WL.size();
1995 OMPClauseEnqueue Visitor(this);
1996 Visitor.Visit(S);
1997 if (size == WL.size())
1998 return;
1999 // Now reverse the entries we just added. This will match the DFS
2000 // ordering performed by the worklist.
2001 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2002 std::reverse(I, E);
2003}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2006}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002007void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 AddDecl(B->getBlockDecl());
2009}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 EnqueueChildren(E);
2012 AddTypeLoc(E->getTypeSourceInfo());
2013}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2015 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 E = S->body_rend(); I != E; ++I) {
2017 AddStmt(*I);
2018 }
2019}
2020void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002022 AddStmt(S->getSubStmt());
2023 AddDeclarationNameInfo(S);
2024 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2025 AddNestedNameSpecifierLoc(QualifierLoc);
2026}
2027
2028void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002029VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002030 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2031 AddDeclarationNameInfo(E);
2032 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2033 AddNestedNameSpecifierLoc(QualifierLoc);
2034 if (!E->isImplicitAccess())
2035 AddStmt(E->getBase());
2036}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002037void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002038 // Enqueue the initializer , if any.
2039 AddStmt(E->getInitializer());
2040 // Enqueue the array size, if any.
2041 AddStmt(E->getArraySize());
2042 // Enqueue the allocated type.
2043 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2044 // Enqueue the placement arguments.
2045 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2046 AddStmt(E->getPlacementArg(I-1));
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2050 AddStmt(CE->getArg(I-1));
2051 AddStmt(CE->getCallee());
2052 AddStmt(CE->getArg(0));
2053}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2055 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 // Visit the name of the type being destroyed.
2057 AddTypeLoc(E->getDestroyedTypeInfo());
2058 // Visit the scope type that looks disturbingly like the nested-name-specifier
2059 // but isn't.
2060 AddTypeLoc(E->getScopeTypeInfo());
2061 // Visit the nested-name-specifier.
2062 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2063 AddNestedNameSpecifierLoc(QualifierLoc);
2064 // Visit base expression.
2065 AddStmt(E->getBase());
2066}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2068 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002069 AddTypeLoc(E->getTypeSourceInfo());
2070}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2072 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 EnqueueChildren(E);
2074 AddTypeLoc(E->getTypeSourceInfo());
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 EnqueueChildren(E);
2078 if (E->isTypeOperand())
2079 AddTypeLoc(E->getTypeOperandSourceInfo());
2080}
2081
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2083 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 EnqueueChildren(E);
2085 AddTypeLoc(E->getTypeSourceInfo());
2086}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 EnqueueChildren(E);
2089 if (E->isTypeOperand())
2090 AddTypeLoc(E->getTypeOperandSourceInfo());
2091}
2092
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 EnqueueChildren(S);
2095 AddDecl(S->getExceptionDecl());
2096}
2097
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 if (DR->hasExplicitTemplateArgs()) {
2100 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2101 }
2102 WL.push_back(DeclRefExprParts(DR, Parent));
2103}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2105 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002106 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2107 AddDeclarationNameInfo(E);
2108 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 unsigned size = WL.size();
2112 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002113 for (const auto *D : S->decls()) {
2114 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 isFirst = false;
2116 }
2117 if (size == WL.size())
2118 return;
2119 // Now reverse the entries we just added. This will match the DFS
2120 // ordering performed by the worklist.
2121 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2122 std::reverse(I, E);
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 D = E->designators_rbegin(), DEnd = E->designators_rend();
2128 D != DEnd; ++D) {
2129 if (D->isFieldDesignator()) {
2130 if (FieldDecl *Field = D->getField())
2131 AddMemberRef(Field, D->getFieldLoc());
2132 continue;
2133 }
2134 if (D->isArrayDesignator()) {
2135 AddStmt(E->getArrayIndex(*D));
2136 continue;
2137 }
2138 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2139 AddStmt(E->getArrayRangeEnd(*D));
2140 AddStmt(E->getArrayRangeStart(*D));
2141 }
2142}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 EnqueueChildren(E);
2145 AddTypeLoc(E->getTypeInfoAsWritten());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 AddStmt(FS->getBody());
2149 AddStmt(FS->getInc());
2150 AddStmt(FS->getCond());
2151 AddDecl(FS->getConditionVariable());
2152 AddStmt(FS->getInit());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2156}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 AddStmt(If->getElse());
2159 AddStmt(If->getThen());
2160 AddStmt(If->getCond());
2161 AddDecl(If->getConditionVariable());
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 // We care about the syntactic form of the initializer list, only.
2165 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2166 IE = Syntactic;
2167 EnqueueChildren(IE);
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 WL.push_back(MemberExprParts(M, Parent));
2171
2172 // If the base of the member access expression is an implicit 'this', don't
2173 // visit it.
2174 // FIXME: If we ever want to show these implicit accesses, this will be
2175 // unfortunate. However, clang_getCursor() relies on this behavior.
2176 if (!M->isImplicitAccess())
2177 AddStmt(M->getBase());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddTypeLoc(E->getEncodedTypeSourceInfo());
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 EnqueueChildren(M);
2184 AddTypeLoc(M->getClassReceiverTypeInfo());
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 // Visit the components of the offsetof expression.
2188 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2189 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2190 const OffsetOfNode &Node = E->getComponent(I-1);
2191 switch (Node.getKind()) {
2192 case OffsetOfNode::Array:
2193 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2194 break;
2195 case OffsetOfNode::Field:
2196 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2197 break;
2198 case OffsetOfNode::Identifier:
2199 case OffsetOfNode::Base:
2200 continue;
2201 }
2202 }
2203 // Visit the type into which we're computing the offset.
2204 AddTypeLoc(E->getTypeSourceInfo());
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2208 WL.push_back(OverloadExprParts(E, Parent));
2209}
2210void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 EnqueueChildren(E);
2213 if (E->isArgumentType())
2214 AddTypeLoc(E->getArgumentTypeInfo());
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 EnqueueChildren(S);
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 AddStmt(S->getBody());
2221 AddStmt(S->getCond());
2222 AddDecl(S->getConditionVariable());
2223}
2224
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 AddStmt(W->getBody());
2227 AddStmt(W->getCond());
2228 AddDecl(W->getConditionVariable());
2229}
2230
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 for (unsigned I = E->getNumArgs(); I > 0; --I)
2233 AddTypeLoc(E->getArg(I-1));
2234}
2235
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 AddTypeLoc(E->getQueriedTypeSourceInfo());
2238}
2239
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 EnqueueChildren(E);
2242}
2243
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 VisitOverloadExpr(U);
2246 if (!U->isImplicitAccess())
2247 AddStmt(U->getBase());
2248}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 AddStmt(E->getSubExpr());
2251 AddTypeLoc(E->getWrittenTypeInfo());
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 WL.push_back(SizeOfPackExprParts(E, Parent));
2255}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 // If the opaque value has a source expression, just transparently
2258 // visit that. This is useful for (e.g.) pseudo-object expressions.
2259 if (Expr *SourceExpr = E->getSourceExpr())
2260 return Visit(SourceExpr);
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 AddStmt(E->getBody());
2264 WL.push_back(LambdaExprParts(E, Parent));
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 // Treat the expression like its syntactic form.
2268 Visit(E->getSyntacticForm());
2269}
2270
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002271void EnqueueVisitor::VisitOMPExecutableDirective(
2272 const OMPExecutableDirective *D) {
2273 EnqueueChildren(D);
2274 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2275 E = D->clauses().end();
2276 I != E; ++I)
2277 EnqueueChildren(*I);
2278}
2279
2280void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2281 VisitOMPExecutableDirective(D);
2282}
2283
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002284void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2285 VisitOMPExecutableDirective(D);
2286}
2287
Alexey Bataevf29276e2014-06-18 04:14:57 +00002288void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2289 VisitOMPExecutableDirective(D);
2290}
2291
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002292void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2293 VisitOMPExecutableDirective(D);
2294}
2295
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002296void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2297 VisitOMPExecutableDirective(D);
2298}
2299
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2302}
2303
2304bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2305 if (RegionOfInterest.isValid()) {
2306 SourceRange Range = getRawCursorExtent(C);
2307 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2308 return false;
2309 }
2310 return true;
2311}
2312
2313bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2314 while (!WL.empty()) {
2315 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002316 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002317
2318 // Set the Parent field, then back to its old value once we're done.
2319 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2320
2321 switch (LI.getKind()) {
2322 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 if (!D)
2325 continue;
2326
2327 // For now, perform default visitation for Decls.
2328 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2329 cast<DeclVisit>(&LI)->isFirst())))
2330 return true;
2331
2332 continue;
2333 }
2334 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2335 const ASTTemplateArgumentListInfo *ArgList =
2336 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2337 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2338 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2339 Arg != ArgEnd; ++Arg) {
2340 if (VisitTemplateArgumentLoc(*Arg))
2341 return true;
2342 }
2343 continue;
2344 }
2345 case VisitorJob::TypeLocVisitKind: {
2346 // Perform default visitation for TypeLocs.
2347 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2348 return true;
2349 continue;
2350 }
2351 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 if (LabelStmt *stmt = LS->getStmt()) {
2354 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2355 TU))) {
2356 return true;
2357 }
2358 }
2359 continue;
2360 }
2361
2362 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2363 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2364 if (VisitNestedNameSpecifierLoc(V->get()))
2365 return true;
2366 continue;
2367 }
2368
2369 case VisitorJob::DeclarationNameInfoVisitKind: {
2370 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2371 ->get()))
2372 return true;
2373 continue;
2374 }
2375 case VisitorJob::MemberRefVisitKind: {
2376 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2377 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2378 return true;
2379 continue;
2380 }
2381 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 if (!S)
2384 continue;
2385
2386 // Update the current cursor.
2387 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2388 if (!IsInRegionOfInterest(Cursor))
2389 continue;
2390 switch (Visitor(Cursor, Parent, ClientData)) {
2391 case CXChildVisit_Break: return true;
2392 case CXChildVisit_Continue: break;
2393 case CXChildVisit_Recurse:
2394 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002395 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 EnqueueWorkList(WL, S);
2397 break;
2398 }
2399 continue;
2400 }
2401 case VisitorJob::MemberExprPartsKind: {
2402 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002404
2405 // Visit the nested-name-specifier
2406 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2407 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2408 return true;
2409
2410 // Visit the declaration name.
2411 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2412 return true;
2413
2414 // Visit the explicitly-specified template arguments, if any.
2415 if (M->hasExplicitTemplateArgs()) {
2416 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2417 *ArgEnd = Arg + M->getNumTemplateArgs();
2418 Arg != ArgEnd; ++Arg) {
2419 if (VisitTemplateArgumentLoc(*Arg))
2420 return true;
2421 }
2422 }
2423 continue;
2424 }
2425 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 // Visit nested-name-specifier, if present.
2428 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2429 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2430 return true;
2431 // Visit declaration name.
2432 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2433 return true;
2434 continue;
2435 }
2436 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 // Visit the nested-name-specifier.
2439 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2440 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2441 return true;
2442 // Visit the declaration name.
2443 if (VisitDeclarationNameInfo(O->getNameInfo()))
2444 return true;
2445 // Visit the overloaded declaration reference.
2446 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2447 return true;
2448 continue;
2449 }
2450 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 NamedDecl *Pack = E->getPack();
2453 if (isa<TemplateTypeParmDecl>(Pack)) {
2454 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2455 E->getPackLoc(), TU)))
2456 return true;
2457
2458 continue;
2459 }
2460
2461 if (isa<TemplateTemplateParmDecl>(Pack)) {
2462 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2463 E->getPackLoc(), TU)))
2464 return true;
2465
2466 continue;
2467 }
2468
2469 // Non-type template parameter packs and function parameter packs are
2470 // treated like DeclRefExpr cursors.
2471 continue;
2472 }
2473
2474 case VisitorJob::LambdaExprPartsKind: {
2475 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2478 CEnd = E->explicit_capture_end();
2479 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002480 // FIXME: Lambda init-captures.
2481 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002483
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2485 C->getLocation(),
2486 TU)))
2487 return true;
2488 }
2489
2490 // Visit parameters and return type, if present.
2491 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2492 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2493 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2494 // Visit the whole type.
2495 if (Visit(TL))
2496 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002497 } else if (FunctionProtoTypeLoc Proto =
2498 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002499 if (E->hasExplicitParameters()) {
2500 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002501 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2502 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 return true;
2504 } else {
2505 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002506 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 return true;
2508 }
2509 }
2510 }
2511 break;
2512 }
2513
2514 case VisitorJob::PostChildrenVisitKind:
2515 if (PostChildrenVisitor(Parent, ClientData))
2516 return true;
2517 break;
2518 }
2519 }
2520 return false;
2521}
2522
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002524 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 if (!WorkListFreeList.empty()) {
2526 WL = WorkListFreeList.back();
2527 WL->clear();
2528 WorkListFreeList.pop_back();
2529 }
2530 else {
2531 WL = new VisitorWorkList();
2532 WorkListCache.push_back(WL);
2533 }
2534 EnqueueWorkList(*WL, S);
2535 bool result = RunVisitorWorkList(*WL);
2536 WorkListFreeList.push_back(WL);
2537 return result;
2538}
2539
2540namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002541typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002542RefNamePieces
2543buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2544 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2545 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2547 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2548 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2549
2550 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2551
2552 RefNamePieces Pieces;
2553
2554 if (WantQualifier && QLoc.isValid())
2555 Pieces.push_back(QLoc);
2556
2557 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2558 Pieces.push_back(NI.getLoc());
2559
2560 if (WantTemplateArgs && TemplateArgs)
2561 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2562 TemplateArgs->RAngleLoc));
2563
2564 if (Kind == DeclarationName::CXXOperatorName) {
2565 Pieces.push_back(SourceLocation::getFromRawEncoding(
2566 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2567 Pieces.push_back(SourceLocation::getFromRawEncoding(
2568 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2569 }
2570
2571 if (WantSinglePiece) {
2572 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2573 Pieces.clear();
2574 Pieces.push_back(R);
2575 }
2576
2577 return Pieces;
2578}
2579}
2580
2581//===----------------------------------------------------------------------===//
2582// Misc. API hooks.
2583//===----------------------------------------------------------------------===//
2584
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002585static llvm::sys::Mutex EnableMultithreadingMutex;
2586static bool EnabledMultithreading;
Guy Benyei11169dd2012-12-18 14:30:41 +00002587
Chad Rosier05c71aa2013-03-27 18:28:23 +00002588static void fatal_error_handler(void *user_data, const std::string& reason,
2589 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 // Write the result out to stderr avoiding errs() because raw_ostreams can
2591 // call report_fatal_error.
2592 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2593 ::abort();
2594}
2595
2596extern "C" {
2597CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2598 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 // We use crash recovery to make some of our APIs more reliable, implicitly
2600 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002601 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2602 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002603
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002604 // Enable support for multithreading in LLVM.
2605 {
2606 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2607 if (!EnabledMultithreading) {
2608 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2609 llvm::llvm_start_multithreaded();
2610 EnabledMultithreading = true;
2611 }
2612 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002613
2614 CIndexer *CIdxr = new CIndexer();
2615 if (excludeDeclarationsFromPCH)
2616 CIdxr->setOnlyLocalDecls();
2617 if (displayDiagnostics)
2618 CIdxr->setDisplayDiagnostics();
2619
2620 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2621 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2622 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2623 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2624 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2625 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2626
2627 return CIdxr;
2628}
2629
2630void clang_disposeIndex(CXIndex CIdx) {
2631 if (CIdx)
2632 delete static_cast<CIndexer *>(CIdx);
2633}
2634
2635void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2636 if (CIdx)
2637 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2638}
2639
2640unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2641 if (CIdx)
2642 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2643 return 0;
2644}
2645
2646void clang_toggleCrashRecovery(unsigned isEnabled) {
2647 if (isEnabled)
2648 llvm::CrashRecoveryContext::Enable();
2649 else
2650 llvm::CrashRecoveryContext::Disable();
2651}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002652
Guy Benyei11169dd2012-12-18 14:30:41 +00002653CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2654 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002655 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002656 enum CXErrorCode Result =
2657 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002658 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002659 assert((TU && Result == CXError_Success) ||
2660 (!TU && Result != CXError_Success));
2661 return TU;
2662}
2663
2664enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2665 const char *ast_filename,
2666 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002667 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002668 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002669
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002670 if (!CIdx || !ast_filename || !out_TU)
2671 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002672
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002673 LOG_FUNC_SECTION {
2674 *Log << ast_filename;
2675 }
2676
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2678 FileSystemOptions FileSystemOpts;
2679
2680 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002681 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002682 CXXIdx->getOnlyLocalDecls(), None,
2683 /*CaptureDiagnostics=*/true,
2684 /*AllowPCHWithCompilerErrors=*/true,
2685 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002686 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2687 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688}
2689
2690unsigned clang_defaultEditingTranslationUnitOptions() {
2691 return CXTranslationUnit_PrecompiledPreamble |
2692 CXTranslationUnit_CacheCompletionResults;
2693}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002694
Guy Benyei11169dd2012-12-18 14:30:41 +00002695CXTranslationUnit
2696clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2697 const char *source_filename,
2698 int num_command_line_args,
2699 const char * const *command_line_args,
2700 unsigned num_unsaved_files,
2701 struct CXUnsavedFile *unsaved_files) {
2702 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2703 return clang_parseTranslationUnit(CIdx, source_filename,
2704 command_line_args, num_command_line_args,
2705 unsaved_files, num_unsaved_files,
2706 Options);
2707}
2708
2709struct ParseTranslationUnitInfo {
2710 CXIndex CIdx;
2711 const char *source_filename;
2712 const char *const *command_line_args;
2713 int num_command_line_args;
2714 struct CXUnsavedFile *unsaved_files;
2715 unsigned num_unsaved_files;
2716 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002717 CXTranslationUnit *out_TU;
2718 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002719};
2720static void clang_parseTranslationUnit_Impl(void *UserData) {
2721 ParseTranslationUnitInfo *PTUI =
2722 static_cast<ParseTranslationUnitInfo*>(UserData);
2723 CXIndex CIdx = PTUI->CIdx;
2724 const char *source_filename = PTUI->source_filename;
2725 const char * const *command_line_args = PTUI->command_line_args;
2726 int num_command_line_args = PTUI->num_command_line_args;
2727 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2728 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2729 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002730 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002731
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002732 // Set up the initial return values.
2733 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002734 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002735 PTUI->result = CXError_Failure;
2736
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002737 // Check arguments.
2738 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002739 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002740 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002742 }
2743
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2745
2746 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2747 setThreadBackgroundPriority();
2748
2749 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2750 // FIXME: Add a flag for modules.
2751 TranslationUnitKind TUKind
2752 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002753 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 = options & CXTranslationUnit_CacheCompletionResults;
2755 bool IncludeBriefCommentsInCodeCompletion
2756 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2757 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2758 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2759
2760 // Configure the diagnostics.
2761 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002762 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002763
2764 // Recover resources if we crash before exiting this function.
2765 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2766 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2767 DiagCleanup(Diags.getPtr());
2768
Ahmed Charlesb8984322014-03-07 20:03:18 +00002769 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2770 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002771
2772 // Recover resources if we crash before exiting this function.
2773 llvm::CrashRecoveryContextCleanupRegistrar<
2774 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2775
2776 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2777 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2778 const llvm::MemoryBuffer *Buffer
2779 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2780 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2781 Buffer));
2782 }
2783
Ahmed Charlesb8984322014-03-07 20:03:18 +00002784 std::unique_ptr<std::vector<const char *>> Args(
2785 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002786
2787 // Recover resources if we crash before exiting this method.
2788 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2789 ArgsCleanup(Args.get());
2790
2791 // Since the Clang C library is primarily used by batch tools dealing with
2792 // (often very broken) source code, where spell-checking can have a
2793 // significant negative impact on performance (particularly when
2794 // precompiled headers are involved), we disable it by default.
2795 // Only do this if we haven't found a spell-checking-related argument.
2796 bool FoundSpellCheckingArgument = false;
2797 for (int I = 0; I != num_command_line_args; ++I) {
2798 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2799 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2800 FoundSpellCheckingArgument = true;
2801 break;
2802 }
2803 }
2804 if (!FoundSpellCheckingArgument)
2805 Args->push_back("-fno-spell-checking");
2806
2807 Args->insert(Args->end(), command_line_args,
2808 command_line_args + num_command_line_args);
2809
2810 // The 'source_filename' argument is optional. If the caller does not
2811 // specify it then it is assumed that the source file is specified
2812 // in the actual argument list.
2813 // Put the source file after command_line_args otherwise if '-x' flag is
2814 // present it will be unused.
2815 if (source_filename)
2816 Args->push_back(source_filename);
2817
2818 // Do we need the detailed preprocessing record?
2819 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2820 Args->push_back("-Xclang");
2821 Args->push_back("-detailed-preprocessing-record");
2822 }
2823
2824 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002825 std::unique_ptr<ASTUnit> ErrUnit;
2826 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002827 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002828 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2829 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2830 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2831 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2832 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2833 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002834
2835 if (NumErrors != Diags->getClient()->getNumErrors()) {
2836 // Make sure to check that 'Unit' is non-NULL.
2837 if (CXXIdx->getDisplayDiagnostics())
2838 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2839 }
2840
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002841 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2842 PTUI->result = CXError_ASTReadError;
2843 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002844 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002845 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2846 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002847}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002848
2849CXTranslationUnit
2850clang_parseTranslationUnit(CXIndex CIdx,
2851 const char *source_filename,
2852 const char *const *command_line_args,
2853 int num_command_line_args,
2854 struct CXUnsavedFile *unsaved_files,
2855 unsigned num_unsaved_files,
2856 unsigned options) {
2857 CXTranslationUnit TU;
2858 enum CXErrorCode Result = clang_parseTranslationUnit2(
2859 CIdx, source_filename, command_line_args, num_command_line_args,
2860 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002861 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002862 assert((TU && Result == CXError_Success) ||
2863 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002864 return TU;
2865}
2866
2867enum CXErrorCode clang_parseTranslationUnit2(
2868 CXIndex CIdx,
2869 const char *source_filename,
2870 const char *const *command_line_args,
2871 int num_command_line_args,
2872 struct CXUnsavedFile *unsaved_files,
2873 unsigned num_unsaved_files,
2874 unsigned options,
2875 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002876 LOG_FUNC_SECTION {
2877 *Log << source_filename << ": ";
2878 for (int i = 0; i != num_command_line_args; ++i)
2879 *Log << command_line_args[i] << " ";
2880 }
2881
Guy Benyei11169dd2012-12-18 14:30:41 +00002882 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2883 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002884 num_unsaved_files, options, out_TU,
2885 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002886 llvm::CrashRecoveryContext CRC;
2887
2888 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2889 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2890 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2891 fprintf(stderr, " 'command_line_args' : [");
2892 for (int i = 0; i != num_command_line_args; ++i) {
2893 if (i)
2894 fprintf(stderr, ", ");
2895 fprintf(stderr, "'%s'", command_line_args[i]);
2896 }
2897 fprintf(stderr, "],\n");
2898 fprintf(stderr, " 'unsaved_files' : [");
2899 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2900 if (i)
2901 fprintf(stderr, ", ");
2902 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2903 unsaved_files[i].Length);
2904 }
2905 fprintf(stderr, "],\n");
2906 fprintf(stderr, " 'options' : %d,\n", options);
2907 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002908
2909 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002911 if (CXTranslationUnit *TU = PTUI.out_TU)
2912 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 }
2914
2915 return PTUI.result;
2916}
2917
2918unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2919 return CXSaveTranslationUnit_None;
2920}
2921
2922namespace {
2923
2924struct SaveTranslationUnitInfo {
2925 CXTranslationUnit TU;
2926 const char *FileName;
2927 unsigned options;
2928 CXSaveError result;
2929};
2930
2931}
2932
2933static void clang_saveTranslationUnit_Impl(void *UserData) {
2934 SaveTranslationUnitInfo *STUI =
2935 static_cast<SaveTranslationUnitInfo*>(UserData);
2936
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002937 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002938 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2939 setThreadBackgroundPriority();
2940
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002941 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002942 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2943}
2944
2945int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2946 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002947 LOG_FUNC_SECTION {
2948 *Log << TU << ' ' << FileName;
2949 }
2950
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002951 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002952 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002953 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002954 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002955
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002956 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002957 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2958 if (!CXXUnit->hasSema())
2959 return CXSaveError_InvalidTU;
2960
2961 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2962
2963 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2964 getenv("LIBCLANG_NOTHREADS")) {
2965 clang_saveTranslationUnit_Impl(&STUI);
2966
2967 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2968 PrintLibclangResourceUsage(TU);
2969
2970 return STUI.result;
2971 }
2972
2973 // We have an AST that has invalid nodes due to compiler errors.
2974 // Use a crash recovery thread for protection.
2975
2976 llvm::CrashRecoveryContext CRC;
2977
2978 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2979 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2980 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2981 fprintf(stderr, " 'options' : %d,\n", options);
2982 fprintf(stderr, "}\n");
2983
2984 return CXSaveError_Unknown;
2985
2986 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2987 PrintLibclangResourceUsage(TU);
2988 }
2989
2990 return STUI.result;
2991}
2992
2993void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2994 if (CTUnit) {
2995 // If the translation unit has been marked as unsafe to free, just discard
2996 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002997 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2998 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002999 return;
3000
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003001 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003002 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3004 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003005 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003006 delete CTUnit;
3007 }
3008}
3009
3010unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3011 return CXReparse_None;
3012}
3013
3014struct ReparseTranslationUnitInfo {
3015 CXTranslationUnit TU;
3016 unsigned num_unsaved_files;
3017 struct CXUnsavedFile *unsaved_files;
3018 unsigned options;
3019 int result;
3020};
3021
3022static void clang_reparseTranslationUnit_Impl(void *UserData) {
3023 ReparseTranslationUnitInfo *RTUI =
3024 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003025 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003026
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003028 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3029 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3030 unsigned options = RTUI->options;
3031 (void) options;
3032
3033 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003034 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003035 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003036 RTUI->result = CXError_InvalidArguments;
3037 return;
3038 }
Craig Topper69186e72014-06-08 08:38:04 +00003039 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003041 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003042 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003043
3044 // Reset the associated diagnostics.
3045 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003046 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003047
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003048 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003049 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3050 setThreadBackgroundPriority();
3051
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003054
3055 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3056 new std::vector<ASTUnit::RemappedFile>());
3057
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 // Recover resources if we crash before exiting this function.
3059 llvm::CrashRecoveryContextCleanupRegistrar<
3060 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3061
3062 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3063 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3064 const llvm::MemoryBuffer *Buffer
3065 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3066 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3067 Buffer));
3068 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003070 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 RTUI->result = CXError_Success;
3072 else if (isASTReadError(CXXUnit))
3073 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003074}
3075
3076int clang_reparseTranslationUnit(CXTranslationUnit TU,
3077 unsigned num_unsaved_files,
3078 struct CXUnsavedFile *unsaved_files,
3079 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003080 LOG_FUNC_SECTION {
3081 *Log << TU;
3082 }
3083
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003085 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003086
3087 if (getenv("LIBCLANG_NOTHREADS")) {
3088 clang_reparseTranslationUnit_Impl(&RTUI);
3089 return RTUI.result;
3090 }
3091
3092 llvm::CrashRecoveryContext CRC;
3093
3094 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3095 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003096 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003097 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3099 PrintLibclangResourceUsage(TU);
3100
3101 return RTUI.result;
3102}
3103
3104
3105CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003106 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003107 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003108 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003109 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003111 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003112 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003113}
3114
3115CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003116 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003117 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003118 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003119 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003120
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003121 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3123}
3124
3125} // end: extern "C"
3126
3127//===----------------------------------------------------------------------===//
3128// CXFile Operations.
3129//===----------------------------------------------------------------------===//
3130
3131extern "C" {
3132CXString clang_getFileName(CXFile SFile) {
3133 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003134 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003135
3136 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003137 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003138}
3139
3140time_t clang_getFileTime(CXFile SFile) {
3141 if (!SFile)
3142 return 0;
3143
3144 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3145 return FEnt->getModificationTime();
3146}
3147
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003148CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003149 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003150 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003151 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003152 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003153
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003154 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003155
3156 FileManager &FMgr = CXXUnit->getFileManager();
3157 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3158}
3159
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003160unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3161 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003162 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003163 LOG_BAD_TU(TU);
3164 return 0;
3165 }
3166
3167 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 return 0;
3169
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003170 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 FileEntry *FEnt = static_cast<FileEntry *>(file);
3172 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3173 .isFileMultipleIncludeGuarded(FEnt);
3174}
3175
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003176int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3177 if (!file || !outID)
3178 return 1;
3179
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003180 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003181 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3182 outID->data[0] = ID.getDevice();
3183 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003184 outID->data[2] = FEnt->getModificationTime();
3185 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003186}
3187
Guy Benyei11169dd2012-12-18 14:30:41 +00003188} // end: extern "C"
3189
3190//===----------------------------------------------------------------------===//
3191// CXCursor Operations.
3192//===----------------------------------------------------------------------===//
3193
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194static const Decl *getDeclFromExpr(const Stmt *E) {
3195 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 return getDeclFromExpr(CE->getSubExpr());
3197
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003198 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003204 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (PRE->isExplicitProperty())
3206 return PRE->getExplicitProperty();
3207 // It could be messaging both getter and setter as in:
3208 // ++myobj.myprop;
3209 // in which case prefer to associate the setter since it is less obvious
3210 // from inspecting the source that the setter is going to get called.
3211 if (PRE->isMessagingSetter())
3212 return PRE->getImplicitPropertySetter();
3213 return PRE->getImplicitPropertyGetter();
3214 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003215 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003217 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 if (Expr *Src = OVE->getSourceExpr())
3219 return getDeclFromExpr(Src);
3220
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003221 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003223 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 if (!CE->isElidable())
3225 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003226 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return OME->getMethodDecl();
3228
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003229 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003231 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3233 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003234 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3236 isa<ParmVarDecl>(SizeOfPack->getPack()))
3237 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003238
3239 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003240}
3241
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003242static SourceLocation getLocationFromExpr(const Expr *E) {
3243 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 return getLocationFromExpr(CE->getSubExpr());
3245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003246 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003248 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003250 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003252 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003254 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003255 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003256 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 return PropRef->getLocation();
3258
3259 return E->getLocStart();
3260}
3261
3262extern "C" {
3263
3264unsigned clang_visitChildren(CXCursor parent,
3265 CXCursorVisitor visitor,
3266 CXClientData client_data) {
3267 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3268 /*VisitPreprocessorLast=*/false);
3269 return CursorVis.VisitChildren(parent);
3270}
3271
3272#ifndef __has_feature
3273#define __has_feature(x) 0
3274#endif
3275#if __has_feature(blocks)
3276typedef enum CXChildVisitResult
3277 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3278
3279static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3280 CXClientData client_data) {
3281 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3282 return block(cursor, parent);
3283}
3284#else
3285// If we are compiled with a compiler that doesn't have native blocks support,
3286// define and call the block manually, so the
3287typedef struct _CXChildVisitResult
3288{
3289 void *isa;
3290 int flags;
3291 int reserved;
3292 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3293 CXCursor);
3294} *CXCursorVisitorBlock;
3295
3296static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3297 CXClientData client_data) {
3298 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3299 return block->invoke(block, cursor, parent);
3300}
3301#endif
3302
3303
3304unsigned clang_visitChildrenWithBlock(CXCursor parent,
3305 CXCursorVisitorBlock block) {
3306 return clang_visitChildren(parent, visitWithBlock, block);
3307}
3308
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003309static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003311 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const ObjCPropertyImplDecl *PropImpl =
3316 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003318 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003320 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003322 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003323
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003328 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003330 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3332 // and returns different names. NamedDecl returns the class name and
3333 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003334 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335
3336 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003337 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003338
3339 SmallString<1024> S;
3340 llvm::raw_svector_ostream os(S);
3341 ND->printName(os);
3342
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344}
3345
3346CXString clang_getCursorSpelling(CXCursor C) {
3347 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003348 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003349
3350 if (clang_isReference(C.kind)) {
3351 switch (C.kind) {
3352 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003354 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003357 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003358 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 }
3360 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003361 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003363 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003366 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 }
3369 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003370 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 assert(Type && "Missing type decl");
3372
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003373 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 getAsString());
3375 }
3376 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003377 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 assert(Template && "Missing template decl");
3379
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 }
3382
3383 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003384 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 assert(NS && "Missing namespace decl");
3386
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003387 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389
3390 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003391 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 assert(Field && "Missing member decl");
3393
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003394 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 }
3396
3397 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003398 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 assert(Label && "Missing label");
3400
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003401 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 }
3403
3404 case CXCursor_OverloadedDeclRef: {
3405 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3407 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003408 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003409 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003412 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 OverloadedTemplateStorage *Ovl
3414 = Storage.get<OverloadedTemplateStorage*>();
3415 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003416 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003417 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 }
3419
3420 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003421 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 assert(Var && "Missing variable decl");
3423
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003424 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 }
3426
3427 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 }
3430 }
3431
3432 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003433 const Expr *E = getCursorExpr(C);
3434
3435 if (C.kind == CXCursor_ObjCStringLiteral ||
3436 C.kind == CXCursor_StringLiteral) {
3437 const StringLiteral *SLit;
3438 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3439 SLit = OSL->getString();
3440 } else {
3441 SLit = cast<StringLiteral>(E);
3442 }
3443 SmallString<256> Buf;
3444 llvm::raw_svector_ostream OS(Buf);
3445 SLit->outputString(OS);
3446 return cxstring::createDup(OS.str());
3447 }
3448
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003449 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 if (D)
3451 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003452 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454
3455 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003456 const Stmt *S = getCursorStmt(C);
3457 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003458 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003459
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003460 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 }
3462
3463 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003464 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 ->getNameStart());
3466
3467 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003468 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 ->getNameStart());
3470
3471 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003472 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003473
3474 if (clang_isDeclaration(C.kind))
3475 return getDeclSpelling(getCursorDecl(C));
3476
3477 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003478 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003479 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 }
3481
3482 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003483 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003484 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 }
3486
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003487 if (C.kind == CXCursor_PackedAttr) {
3488 return cxstring::createRef("packed");
3489 }
3490
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003491 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003492}
3493
3494CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3495 unsigned pieceIndex,
3496 unsigned options) {
3497 if (clang_Cursor_isNull(C))
3498 return clang_getNullRange();
3499
3500 ASTContext &Ctx = getCursorContext(C);
3501
3502 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003503 const Stmt *S = getCursorStmt(C);
3504 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 if (pieceIndex > 0)
3506 return clang_getNullRange();
3507 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3508 }
3509
3510 return clang_getNullRange();
3511 }
3512
3513 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003514 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3516 if (pieceIndex >= ME->getNumSelectorLocs())
3517 return clang_getNullRange();
3518 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3519 }
3520 }
3521
3522 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3523 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003524 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3526 if (pieceIndex >= MD->getNumSelectorLocs())
3527 return clang_getNullRange();
3528 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3529 }
3530 }
3531
3532 if (C.kind == CXCursor_ObjCCategoryDecl ||
3533 C.kind == CXCursor_ObjCCategoryImplDecl) {
3534 if (pieceIndex > 0)
3535 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3538 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3541 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3542 }
3543
3544 if (C.kind == CXCursor_ModuleImportDecl) {
3545 if (pieceIndex > 0)
3546 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003547 if (const ImportDecl *ImportD =
3548 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3550 if (!Locs.empty())
3551 return cxloc::translateSourceRange(Ctx,
3552 SourceRange(Locs.front(), Locs.back()));
3553 }
3554 return clang_getNullRange();
3555 }
3556
3557 // FIXME: A CXCursor_InclusionDirective should give the location of the
3558 // filename, but we don't keep track of this.
3559
3560 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3561 // but we don't keep track of this.
3562
3563 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3564 // but we don't keep track of this.
3565
3566 // Default handling, give the location of the cursor.
3567
3568 if (pieceIndex > 0)
3569 return clang_getNullRange();
3570
3571 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3572 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3573 return cxloc::translateSourceRange(Ctx, Loc);
3574}
3575
3576CXString clang_getCursorDisplayName(CXCursor C) {
3577 if (!clang_isDeclaration(C.kind))
3578 return clang_getCursorSpelling(C);
3579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003582 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003583
3584 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003585 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 D = FunTmpl->getTemplatedDecl();
3587
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003588 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 SmallString<64> Str;
3590 llvm::raw_svector_ostream OS(Str);
3591 OS << *Function;
3592 if (Function->getPrimaryTemplate())
3593 OS << "<>";
3594 OS << "(";
3595 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3596 if (I)
3597 OS << ", ";
3598 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3599 }
3600
3601 if (Function->isVariadic()) {
3602 if (Function->getNumParams())
3603 OS << ", ";
3604 OS << "...";
3605 }
3606 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003607 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 }
3609
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003610 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 SmallString<64> Str;
3612 llvm::raw_svector_ostream OS(Str);
3613 OS << *ClassTemplate;
3614 OS << "<";
3615 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3616 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3617 if (I)
3618 OS << ", ";
3619
3620 NamedDecl *Param = Params->getParam(I);
3621 if (Param->getIdentifier()) {
3622 OS << Param->getIdentifier()->getName();
3623 continue;
3624 }
3625
3626 // There is no parameter name, which makes this tricky. Try to come up
3627 // with something useful that isn't too long.
3628 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3629 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3630 else if (NonTypeTemplateParmDecl *NTTP
3631 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3632 OS << NTTP->getType().getAsString(Policy);
3633 else
3634 OS << "template<...> class";
3635 }
3636
3637 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003638 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 }
3640
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003641 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3643 // If the type was explicitly written, use that.
3644 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003645 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003646
Benjamin Kramer9170e912013-02-22 15:46:01 +00003647 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 llvm::raw_svector_ostream OS(Str);
3649 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003650 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 ClassSpec->getTemplateArgs().data(),
3652 ClassSpec->getTemplateArgs().size(),
3653 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003654 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 }
3656
3657 return clang_getCursorSpelling(C);
3658}
3659
3660CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3661 switch (Kind) {
3662 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003790 case CXCursor_ObjCSelfExpr:
3791 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003908 case CXCursor_PackedAttr:
3909 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003910 case CXCursor_PureAttr:
3911 return cxstring::createRef("attribute(pure)");
3912 case CXCursor_ConstAttr:
3913 return cxstring::createRef("attribute(const)");
3914 case CXCursor_NoDuplicateAttr:
3915 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003916 case CXCursor_CUDAConstantAttr:
3917 return cxstring::createRef("attribute(constant)");
3918 case CXCursor_CUDADeviceAttr:
3919 return cxstring::createRef("attribute(device)");
3920 case CXCursor_CUDAGlobalAttr:
3921 return cxstring::createRef("attribute(global)");
3922 case CXCursor_CUDAHostAttr:
3923 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003972 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003973 return cxstring::createRef("OMPParallelDirective");
3974 case CXCursor_OMPSimdDirective:
3975 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003976 case CXCursor_OMPForDirective:
3977 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003978 case CXCursor_OMPSectionsDirective:
3979 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003980 case CXCursor_OMPSectionDirective:
3981 return cxstring::createRef("OMPSectionDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 }
3983
3984 llvm_unreachable("Unhandled CXCursorKind");
3985}
3986
3987struct GetCursorData {
3988 SourceLocation TokenBeginLoc;
3989 bool PointsAtMacroArgExpansion;
3990 bool VisitedObjCPropertyImplDecl;
3991 SourceLocation VisitedDeclaratorDeclStartLoc;
3992 CXCursor &BestCursor;
3993
3994 GetCursorData(SourceManager &SM,
3995 SourceLocation tokenBegin, CXCursor &outputCursor)
3996 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3997 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3998 VisitedObjCPropertyImplDecl = false;
3999 }
4000};
4001
4002static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4003 CXCursor parent,
4004 CXClientData client_data) {
4005 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4006 CXCursor *BestCursor = &Data->BestCursor;
4007
4008 // If we point inside a macro argument we should provide info of what the
4009 // token is so use the actual cursor, don't replace it with a macro expansion
4010 // cursor.
4011 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4012 return CXChildVisit_Recurse;
4013
4014 if (clang_isDeclaration(cursor.kind)) {
4015 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004016 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4018 if (MD->isImplicit())
4019 return CXChildVisit_Break;
4020
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4023 // Check that when we have multiple @class references in the same line,
4024 // that later ones do not override the previous ones.
4025 // If we have:
4026 // @class Foo, Bar;
4027 // source ranges for both start at '@', so 'Bar' will end up overriding
4028 // 'Foo' even though the cursor location was at 'Foo'.
4029 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4030 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004031 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4033 if (PrevID != ID &&
4034 !PrevID->isThisDeclarationADefinition() &&
4035 !ID->isThisDeclarationADefinition())
4036 return CXChildVisit_Break;
4037 }
4038
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004039 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4041 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4042 // Check that when we have multiple declarators in the same line,
4043 // that later ones do not override the previous ones.
4044 // If we have:
4045 // int Foo, Bar;
4046 // source ranges for both start at 'int', so 'Bar' will end up overriding
4047 // 'Foo' even though the cursor location was at 'Foo'.
4048 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4049 return CXChildVisit_Break;
4050 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4051
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004052 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4054 (void)PropImp;
4055 // Check that when we have multiple @synthesize in the same line,
4056 // that later ones do not override the previous ones.
4057 // If we have:
4058 // @synthesize Foo, Bar;
4059 // source ranges for both start at '@', so 'Bar' will end up overriding
4060 // 'Foo' even though the cursor location was at 'Foo'.
4061 if (Data->VisitedObjCPropertyImplDecl)
4062 return CXChildVisit_Break;
4063 Data->VisitedObjCPropertyImplDecl = true;
4064 }
4065 }
4066
4067 if (clang_isExpression(cursor.kind) &&
4068 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004069 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 // Avoid having the cursor of an expression replace the declaration cursor
4071 // when the expression source range overlaps the declaration range.
4072 // This can happen for C++ constructor expressions whose range generally
4073 // include the variable declaration, e.g.:
4074 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4075 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4076 D->getLocation() == Data->TokenBeginLoc)
4077 return CXChildVisit_Break;
4078 }
4079 }
4080
4081 // If our current best cursor is the construction of a temporary object,
4082 // don't replace that cursor with a type reference, because we want
4083 // clang_getCursor() to point at the constructor.
4084 if (clang_isExpression(BestCursor->kind) &&
4085 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4086 cursor.kind == CXCursor_TypeRef) {
4087 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4088 // as having the actual point on the type reference.
4089 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4090 return CXChildVisit_Recurse;
4091 }
4092
4093 *BestCursor = cursor;
4094 return CXChildVisit_Recurse;
4095}
4096
4097CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004098 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004099 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004101 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004102
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004103 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4105
4106 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4107 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4108
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004109 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 CXFile SearchFile;
4111 unsigned SearchLine, SearchColumn;
4112 CXFile ResultFile;
4113 unsigned ResultLine, ResultColumn;
4114 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4115 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4116 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004117
4118 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4119 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004120 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004121 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 SearchFileName = clang_getFileName(SearchFile);
4123 ResultFileName = clang_getFileName(ResultFile);
4124 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4125 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004126 *Log << llvm::format("(%s:%d:%d) = %s",
4127 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4128 clang_getCString(KindSpelling))
4129 << llvm::format("(%s:%d:%d):%s%s",
4130 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4131 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 clang_disposeString(SearchFileName);
4133 clang_disposeString(ResultFileName);
4134 clang_disposeString(KindSpelling);
4135 clang_disposeString(USR);
4136
4137 CXCursor Definition = clang_getCursorDefinition(Result);
4138 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4139 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4140 CXString DefinitionKindSpelling
4141 = clang_getCursorKindSpelling(Definition.kind);
4142 CXFile DefinitionFile;
4143 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004144 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004145 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004147 *Log << llvm::format(" -> %s(%s:%d:%d)",
4148 clang_getCString(DefinitionKindSpelling),
4149 clang_getCString(DefinitionFileName),
4150 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 clang_disposeString(DefinitionFileName);
4152 clang_disposeString(DefinitionKindSpelling);
4153 }
4154 }
4155
4156 return Result;
4157}
4158
4159CXCursor clang_getNullCursor(void) {
4160 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4161}
4162
4163unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004164 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4165 // can't set consistently. For example, when visiting a DeclStmt we will set
4166 // it but we don't set it on the result of clang_getCursorDefinition for
4167 // a reference of the same declaration.
4168 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4169 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4170 // to provide that kind of info.
4171 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004172 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004173 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004174 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004175
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 return X == Y;
4177}
4178
4179unsigned clang_hashCursor(CXCursor C) {
4180 unsigned Index = 0;
4181 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4182 Index = 1;
4183
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004184 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 std::make_pair(C.kind, C.data[Index]));
4186}
4187
4188unsigned clang_isInvalid(enum CXCursorKind K) {
4189 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4190}
4191
4192unsigned clang_isDeclaration(enum CXCursorKind K) {
4193 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4194 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4195}
4196
4197unsigned clang_isReference(enum CXCursorKind K) {
4198 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4199}
4200
4201unsigned clang_isExpression(enum CXCursorKind K) {
4202 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4203}
4204
4205unsigned clang_isStatement(enum CXCursorKind K) {
4206 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4207}
4208
4209unsigned clang_isAttribute(enum CXCursorKind K) {
4210 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4211}
4212
4213unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4214 return K == CXCursor_TranslationUnit;
4215}
4216
4217unsigned clang_isPreprocessing(enum CXCursorKind K) {
4218 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4219}
4220
4221unsigned clang_isUnexposed(enum CXCursorKind K) {
4222 switch (K) {
4223 case CXCursor_UnexposedDecl:
4224 case CXCursor_UnexposedExpr:
4225 case CXCursor_UnexposedStmt:
4226 case CXCursor_UnexposedAttr:
4227 return true;
4228 default:
4229 return false;
4230 }
4231}
4232
4233CXCursorKind clang_getCursorKind(CXCursor C) {
4234 return C.kind;
4235}
4236
4237CXSourceLocation clang_getCursorLocation(CXCursor C) {
4238 if (clang_isReference(C.kind)) {
4239 switch (C.kind) {
4240 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004241 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 = getCursorObjCSuperClassRef(C);
4243 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4244 }
4245
4246 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004247 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 = getCursorObjCProtocolRef(C);
4249 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4250 }
4251
4252 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004253 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 = getCursorObjCClassRef(C);
4255 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4256 }
4257
4258 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004259 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4261 }
4262
4263 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004264 std::pair<const TemplateDecl *, SourceLocation> P =
4265 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4267 }
4268
4269 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004270 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4272 }
4273
4274 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004275 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4277 }
4278
4279 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004280 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4282 }
4283
4284 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004285 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 if (!BaseSpec)
4287 return clang_getNullLocation();
4288
4289 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4290 return cxloc::translateSourceLocation(getCursorContext(C),
4291 TSInfo->getTypeLoc().getBeginLoc());
4292
4293 return cxloc::translateSourceLocation(getCursorContext(C),
4294 BaseSpec->getLocStart());
4295 }
4296
4297 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004298 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4300 }
4301
4302 case CXCursor_OverloadedDeclRef:
4303 return cxloc::translateSourceLocation(getCursorContext(C),
4304 getCursorOverloadedDeclRef(C).second);
4305
4306 default:
4307 // FIXME: Need a way to enumerate all non-reference cases.
4308 llvm_unreachable("Missed a reference kind");
4309 }
4310 }
4311
4312 if (clang_isExpression(C.kind))
4313 return cxloc::translateSourceLocation(getCursorContext(C),
4314 getLocationFromExpr(getCursorExpr(C)));
4315
4316 if (clang_isStatement(C.kind))
4317 return cxloc::translateSourceLocation(getCursorContext(C),
4318 getCursorStmt(C)->getLocStart());
4319
4320 if (C.kind == CXCursor_PreprocessingDirective) {
4321 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4322 return cxloc::translateSourceLocation(getCursorContext(C), L);
4323 }
4324
4325 if (C.kind == CXCursor_MacroExpansion) {
4326 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004327 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 return cxloc::translateSourceLocation(getCursorContext(C), L);
4329 }
4330
4331 if (C.kind == CXCursor_MacroDefinition) {
4332 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4333 return cxloc::translateSourceLocation(getCursorContext(C), L);
4334 }
4335
4336 if (C.kind == CXCursor_InclusionDirective) {
4337 SourceLocation L
4338 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4339 return cxloc::translateSourceLocation(getCursorContext(C), L);
4340 }
4341
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004342 if (clang_isAttribute(C.kind)) {
4343 SourceLocation L
4344 = cxcursor::getCursorAttr(C)->getLocation();
4345 return cxloc::translateSourceLocation(getCursorContext(C), L);
4346 }
4347
Guy Benyei11169dd2012-12-18 14:30:41 +00004348 if (!clang_isDeclaration(C.kind))
4349 return clang_getNullLocation();
4350
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004351 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 if (!D)
4353 return clang_getNullLocation();
4354
4355 SourceLocation Loc = D->getLocation();
4356 // FIXME: Multiple variables declared in a single declaration
4357 // currently lack the information needed to correctly determine their
4358 // ranges when accounting for the type-specifier. We use context
4359 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4360 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004361 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 if (!cxcursor::isFirstInDeclGroup(C))
4363 Loc = VD->getLocation();
4364 }
4365
4366 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004367 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 Loc = MD->getSelectorStartLoc();
4369
4370 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4371}
4372
4373} // end extern "C"
4374
4375CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4376 assert(TU);
4377
4378 // Guard against an invalid SourceLocation, or we may assert in one
4379 // of the following calls.
4380 if (SLoc.isInvalid())
4381 return clang_getNullCursor();
4382
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004383 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004384
4385 // Translate the given source location to make it point at the beginning of
4386 // the token under the cursor.
4387 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4388 CXXUnit->getASTContext().getLangOpts());
4389
4390 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4391 if (SLoc.isValid()) {
4392 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4393 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4394 /*VisitPreprocessorLast=*/true,
4395 /*VisitIncludedEntities=*/false,
4396 SourceLocation(SLoc));
4397 CursorVis.visitFileRegion();
4398 }
4399
4400 return Result;
4401}
4402
4403static SourceRange getRawCursorExtent(CXCursor C) {
4404 if (clang_isReference(C.kind)) {
4405 switch (C.kind) {
4406 case CXCursor_ObjCSuperClassRef:
4407 return getCursorObjCSuperClassRef(C).second;
4408
4409 case CXCursor_ObjCProtocolRef:
4410 return getCursorObjCProtocolRef(C).second;
4411
4412 case CXCursor_ObjCClassRef:
4413 return getCursorObjCClassRef(C).second;
4414
4415 case CXCursor_TypeRef:
4416 return getCursorTypeRef(C).second;
4417
4418 case CXCursor_TemplateRef:
4419 return getCursorTemplateRef(C).second;
4420
4421 case CXCursor_NamespaceRef:
4422 return getCursorNamespaceRef(C).second;
4423
4424 case CXCursor_MemberRef:
4425 return getCursorMemberRef(C).second;
4426
4427 case CXCursor_CXXBaseSpecifier:
4428 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4429
4430 case CXCursor_LabelRef:
4431 return getCursorLabelRef(C).second;
4432
4433 case CXCursor_OverloadedDeclRef:
4434 return getCursorOverloadedDeclRef(C).second;
4435
4436 case CXCursor_VariableRef:
4437 return getCursorVariableRef(C).second;
4438
4439 default:
4440 // FIXME: Need a way to enumerate all non-reference cases.
4441 llvm_unreachable("Missed a reference kind");
4442 }
4443 }
4444
4445 if (clang_isExpression(C.kind))
4446 return getCursorExpr(C)->getSourceRange();
4447
4448 if (clang_isStatement(C.kind))
4449 return getCursorStmt(C)->getSourceRange();
4450
4451 if (clang_isAttribute(C.kind))
4452 return getCursorAttr(C)->getRange();
4453
4454 if (C.kind == CXCursor_PreprocessingDirective)
4455 return cxcursor::getCursorPreprocessingDirective(C);
4456
4457 if (C.kind == CXCursor_MacroExpansion) {
4458 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004459 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 return TU->mapRangeFromPreamble(Range);
4461 }
4462
4463 if (C.kind == CXCursor_MacroDefinition) {
4464 ASTUnit *TU = getCursorASTUnit(C);
4465 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4466 return TU->mapRangeFromPreamble(Range);
4467 }
4468
4469 if (C.kind == CXCursor_InclusionDirective) {
4470 ASTUnit *TU = getCursorASTUnit(C);
4471 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4472 return TU->mapRangeFromPreamble(Range);
4473 }
4474
4475 if (C.kind == CXCursor_TranslationUnit) {
4476 ASTUnit *TU = getCursorASTUnit(C);
4477 FileID MainID = TU->getSourceManager().getMainFileID();
4478 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4479 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4480 return SourceRange(Start, End);
4481 }
4482
4483 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004484 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 if (!D)
4486 return SourceRange();
4487
4488 SourceRange R = D->getSourceRange();
4489 // FIXME: Multiple variables declared in a single declaration
4490 // currently lack the information needed to correctly determine their
4491 // ranges when accounting for the type-specifier. We use context
4492 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4493 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004494 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 if (!cxcursor::isFirstInDeclGroup(C))
4496 R.setBegin(VD->getLocation());
4497 }
4498 return R;
4499 }
4500 return SourceRange();
4501}
4502
4503/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4504/// the decl-specifier-seq for declarations.
4505static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4506 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004507 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (!D)
4509 return SourceRange();
4510
4511 SourceRange R = D->getSourceRange();
4512
4513 // Adjust the start of the location for declarations preceded by
4514 // declaration specifiers.
4515 SourceLocation StartLoc;
4516 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4517 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4518 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4521 StartLoc = TI->getTypeLoc().getLocStart();
4522 }
4523
4524 if (StartLoc.isValid() && R.getBegin().isValid() &&
4525 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4526 R.setBegin(StartLoc);
4527
4528 // FIXME: Multiple variables declared in a single declaration
4529 // currently lack the information needed to correctly determine their
4530 // ranges when accounting for the type-specifier. We use context
4531 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4532 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004533 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 if (!cxcursor::isFirstInDeclGroup(C))
4535 R.setBegin(VD->getLocation());
4536 }
4537
4538 return R;
4539 }
4540
4541 return getRawCursorExtent(C);
4542}
4543
4544extern "C" {
4545
4546CXSourceRange clang_getCursorExtent(CXCursor C) {
4547 SourceRange R = getRawCursorExtent(C);
4548 if (R.isInvalid())
4549 return clang_getNullRange();
4550
4551 return cxloc::translateSourceRange(getCursorContext(C), R);
4552}
4553
4554CXCursor clang_getCursorReferenced(CXCursor C) {
4555 if (clang_isInvalid(C.kind))
4556 return clang_getNullCursor();
4557
4558 CXTranslationUnit tu = getCursorTU(C);
4559 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004560 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 if (!D)
4562 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004563 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004565 if (const ObjCPropertyImplDecl *PropImpl =
4566 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4568 return MakeCXCursor(Property, tu);
4569
4570 return C;
4571 }
4572
4573 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004574 const Expr *E = getCursorExpr(C);
4575 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 if (D) {
4577 CXCursor declCursor = MakeCXCursor(D, tu);
4578 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4579 declCursor);
4580 return declCursor;
4581 }
4582
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004583 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 return MakeCursorOverloadedDeclRef(Ovl, tu);
4585
4586 return clang_getNullCursor();
4587 }
4588
4589 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004590 const Stmt *S = getCursorStmt(C);
4591 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 if (LabelDecl *label = Goto->getLabel())
4593 if (LabelStmt *labelS = label->getStmt())
4594 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4595
4596 return clang_getNullCursor();
4597 }
4598
4599 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004600 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 return MakeMacroDefinitionCursor(Def, tu);
4602 }
4603
4604 if (!clang_isReference(C.kind))
4605 return clang_getNullCursor();
4606
4607 switch (C.kind) {
4608 case CXCursor_ObjCSuperClassRef:
4609 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4610
4611 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004612 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4613 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 return MakeCXCursor(Def, tu);
4615
4616 return MakeCXCursor(Prot, tu);
4617 }
4618
4619 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4621 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 return MakeCXCursor(Def, tu);
4623
4624 return MakeCXCursor(Class, tu);
4625 }
4626
4627 case CXCursor_TypeRef:
4628 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4629
4630 case CXCursor_TemplateRef:
4631 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4632
4633 case CXCursor_NamespaceRef:
4634 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4635
4636 case CXCursor_MemberRef:
4637 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4638
4639 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004640 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4642 tu ));
4643 }
4644
4645 case CXCursor_LabelRef:
4646 // FIXME: We end up faking the "parent" declaration here because we
4647 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004648 return MakeCXCursor(getCursorLabelRef(C).first,
4649 cxtu::getASTUnit(tu)->getASTContext()
4650 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 tu);
4652
4653 case CXCursor_OverloadedDeclRef:
4654 return C;
4655
4656 case CXCursor_VariableRef:
4657 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4658
4659 default:
4660 // We would prefer to enumerate all non-reference cursor kinds here.
4661 llvm_unreachable("Unhandled reference cursor kind");
4662 }
4663}
4664
4665CXCursor clang_getCursorDefinition(CXCursor C) {
4666 if (clang_isInvalid(C.kind))
4667 return clang_getNullCursor();
4668
4669 CXTranslationUnit TU = getCursorTU(C);
4670
4671 bool WasReference = false;
4672 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4673 C = clang_getCursorReferenced(C);
4674 WasReference = true;
4675 }
4676
4677 if (C.kind == CXCursor_MacroExpansion)
4678 return clang_getCursorReferenced(C);
4679
4680 if (!clang_isDeclaration(C.kind))
4681 return clang_getNullCursor();
4682
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004683 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 if (!D)
4685 return clang_getNullCursor();
4686
4687 switch (D->getKind()) {
4688 // Declaration kinds that don't really separate the notions of
4689 // declaration and definition.
4690 case Decl::Namespace:
4691 case Decl::Typedef:
4692 case Decl::TypeAlias:
4693 case Decl::TypeAliasTemplate:
4694 case Decl::TemplateTypeParm:
4695 case Decl::EnumConstant:
4696 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004697 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 case Decl::IndirectField:
4699 case Decl::ObjCIvar:
4700 case Decl::ObjCAtDefsField:
4701 case Decl::ImplicitParam:
4702 case Decl::ParmVar:
4703 case Decl::NonTypeTemplateParm:
4704 case Decl::TemplateTemplateParm:
4705 case Decl::ObjCCategoryImpl:
4706 case Decl::ObjCImplementation:
4707 case Decl::AccessSpec:
4708 case Decl::LinkageSpec:
4709 case Decl::ObjCPropertyImpl:
4710 case Decl::FileScopeAsm:
4711 case Decl::StaticAssert:
4712 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004713 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 case Decl::Label: // FIXME: Is this right??
4715 case Decl::ClassScopeFunctionSpecialization:
4716 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004717 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 return C;
4719
4720 // Declaration kinds that don't make any sense here, but are
4721 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004722 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case Decl::TranslationUnit:
4724 break;
4725
4726 // Declaration kinds for which the definition is not resolvable.
4727 case Decl::UnresolvedUsingTypename:
4728 case Decl::UnresolvedUsingValue:
4729 break;
4730
4731 case Decl::UsingDirective:
4732 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4733 TU);
4734
4735 case Decl::NamespaceAlias:
4736 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4737
4738 case Decl::Enum:
4739 case Decl::Record:
4740 case Decl::CXXRecord:
4741 case Decl::ClassTemplateSpecialization:
4742 case Decl::ClassTemplatePartialSpecialization:
4743 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4744 return MakeCXCursor(Def, TU);
4745 return clang_getNullCursor();
4746
4747 case Decl::Function:
4748 case Decl::CXXMethod:
4749 case Decl::CXXConstructor:
4750 case Decl::CXXDestructor:
4751 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004752 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004754 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 return clang_getNullCursor();
4756 }
4757
Larisse Voufo39a1e502013-08-06 01:03:05 +00004758 case Decl::Var:
4759 case Decl::VarTemplateSpecialization:
4760 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 return MakeCXCursor(Def, TU);
4764 return clang_getNullCursor();
4765 }
4766
4767 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004768 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4770 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4771 return clang_getNullCursor();
4772 }
4773
4774 case Decl::ClassTemplate: {
4775 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4776 ->getDefinition())
4777 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4778 TU);
4779 return clang_getNullCursor();
4780 }
4781
Larisse Voufo39a1e502013-08-06 01:03:05 +00004782 case Decl::VarTemplate: {
4783 if (VarDecl *Def =
4784 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4785 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4786 return clang_getNullCursor();
4787 }
4788
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case Decl::Using:
4790 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4791 D->getLocation(), TU);
4792
4793 case Decl::UsingShadow:
4794 return clang_getCursorDefinition(
4795 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4796 TU));
4797
4798 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004799 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 if (Method->isThisDeclarationADefinition())
4801 return C;
4802
4803 // Dig out the method definition in the associated
4804 // @implementation, if we have it.
4805 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004806 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4808 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4809 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4810 Method->isInstanceMethod()))
4811 if (Def->isThisDeclarationADefinition())
4812 return MakeCXCursor(Def, TU);
4813
4814 return clang_getNullCursor();
4815 }
4816
4817 case Decl::ObjCCategory:
4818 if (ObjCCategoryImplDecl *Impl
4819 = cast<ObjCCategoryDecl>(D)->getImplementation())
4820 return MakeCXCursor(Impl, TU);
4821 return clang_getNullCursor();
4822
4823 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004824 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 return MakeCXCursor(Def, TU);
4826 return clang_getNullCursor();
4827
4828 case Decl::ObjCInterface: {
4829 // There are two notions of a "definition" for an Objective-C
4830 // class: the interface and its implementation. When we resolved a
4831 // reference to an Objective-C class, produce the @interface as
4832 // the definition; when we were provided with the interface,
4833 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004834 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 return MakeCXCursor(Def, TU);
4838 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4839 return MakeCXCursor(Impl, TU);
4840 return clang_getNullCursor();
4841 }
4842
4843 case Decl::ObjCProperty:
4844 // FIXME: We don't really know where to find the
4845 // ObjCPropertyImplDecls that implement this property.
4846 return clang_getNullCursor();
4847
4848 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004849 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 return MakeCXCursor(Def, TU);
4853
4854 return clang_getNullCursor();
4855
4856 case Decl::Friend:
4857 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4858 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4859 return clang_getNullCursor();
4860
4861 case Decl::FriendTemplate:
4862 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4863 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4864 return clang_getNullCursor();
4865 }
4866
4867 return clang_getNullCursor();
4868}
4869
4870unsigned clang_isCursorDefinition(CXCursor C) {
4871 if (!clang_isDeclaration(C.kind))
4872 return 0;
4873
4874 return clang_getCursorDefinition(C) == C;
4875}
4876
4877CXCursor clang_getCanonicalCursor(CXCursor C) {
4878 if (!clang_isDeclaration(C.kind))
4879 return C;
4880
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004881 if (const Decl *D = getCursorDecl(C)) {
4882 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4884 return MakeCXCursor(CatD, getCursorTU(C));
4885
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4887 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004888 return MakeCXCursor(IFD, getCursorTU(C));
4889
4890 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4891 }
4892
4893 return C;
4894}
4895
4896int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4897 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4898}
4899
4900unsigned clang_getNumOverloadedDecls(CXCursor C) {
4901 if (C.kind != CXCursor_OverloadedDeclRef)
4902 return 0;
4903
4904 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 return E->getNumDecls();
4907
4908 if (OverloadedTemplateStorage *S
4909 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4910 return S->size();
4911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 const Decl *D = Storage.get<const Decl *>();
4913 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 return Using->shadow_size();
4915
4916 return 0;
4917}
4918
4919CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4920 if (cursor.kind != CXCursor_OverloadedDeclRef)
4921 return clang_getNullCursor();
4922
4923 if (index >= clang_getNumOverloadedDecls(cursor))
4924 return clang_getNullCursor();
4925
4926 CXTranslationUnit TU = getCursorTU(cursor);
4927 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004928 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 return MakeCXCursor(E->decls_begin()[index], TU);
4930
4931 if (OverloadedTemplateStorage *S
4932 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4933 return MakeCXCursor(S->begin()[index], TU);
4934
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004935 const Decl *D = Storage.get<const Decl *>();
4936 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 // FIXME: This is, unfortunately, linear time.
4938 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4939 std::advance(Pos, index);
4940 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4941 }
4942
4943 return clang_getNullCursor();
4944}
4945
4946void clang_getDefinitionSpellingAndExtent(CXCursor C,
4947 const char **startBuf,
4948 const char **endBuf,
4949 unsigned *startLine,
4950 unsigned *startColumn,
4951 unsigned *endLine,
4952 unsigned *endColumn) {
4953 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004954 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4956
4957 SourceManager &SM = FD->getASTContext().getSourceManager();
4958 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4959 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4960 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4961 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4962 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4963 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4964}
4965
4966
4967CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4968 unsigned PieceIndex) {
4969 RefNamePieces Pieces;
4970
4971 switch (C.kind) {
4972 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004973 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4975 E->getQualifierLoc().getSourceRange());
4976 break;
4977
4978 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004979 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4981 E->getQualifierLoc().getSourceRange(),
4982 E->getOptionalExplicitTemplateArgs());
4983 break;
4984
4985 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004986 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004988 const Expr *Callee = OCE->getCallee();
4989 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 Callee = ICE->getSubExpr();
4991
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004992 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4994 DRE->getQualifierLoc().getSourceRange());
4995 }
4996 break;
4997
4998 default:
4999 break;
5000 }
5001
5002 if (Pieces.empty()) {
5003 if (PieceIndex == 0)
5004 return clang_getCursorExtent(C);
5005 } else if (PieceIndex < Pieces.size()) {
5006 SourceRange R = Pieces[PieceIndex];
5007 if (R.isValid())
5008 return cxloc::translateSourceRange(getCursorContext(C), R);
5009 }
5010
5011 return clang_getNullRange();
5012}
5013
5014void clang_enableStackTraces(void) {
5015 llvm::sys::PrintStackTraceOnErrorSignal();
5016}
5017
5018void clang_executeOnThread(void (*fn)(void*), void *user_data,
5019 unsigned stack_size) {
5020 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5021}
5022
5023} // end: extern "C"
5024
5025//===----------------------------------------------------------------------===//
5026// Token-based Operations.
5027//===----------------------------------------------------------------------===//
5028
5029/* CXToken layout:
5030 * int_data[0]: a CXTokenKind
5031 * int_data[1]: starting token location
5032 * int_data[2]: token length
5033 * int_data[3]: reserved
5034 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5035 * otherwise unused.
5036 */
5037extern "C" {
5038
5039CXTokenKind clang_getTokenKind(CXToken CXTok) {
5040 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5041}
5042
5043CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5044 switch (clang_getTokenKind(CXTok)) {
5045 case CXToken_Identifier:
5046 case CXToken_Keyword:
5047 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005048 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 ->getNameStart());
5050
5051 case CXToken_Literal: {
5052 // We have stashed the starting pointer in the ptr_data field. Use it.
5053 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005054 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 }
5056
5057 case CXToken_Punctuation:
5058 case CXToken_Comment:
5059 break;
5060 }
5061
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005062 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005063 LOG_BAD_TU(TU);
5064 return cxstring::createEmpty();
5065 }
5066
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 // We have to find the starting buffer pointer the hard way, by
5068 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005069 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005070 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005071 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005072
5073 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5074 std::pair<FileID, unsigned> LocInfo
5075 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5076 bool Invalid = false;
5077 StringRef Buffer
5078 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5079 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005080 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005081
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005082 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005083}
5084
5085CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005086 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005087 LOG_BAD_TU(TU);
5088 return clang_getNullLocation();
5089 }
5090
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005091 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 if (!CXXUnit)
5093 return clang_getNullLocation();
5094
5095 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5096 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5097}
5098
5099CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005100 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005101 LOG_BAD_TU(TU);
5102 return clang_getNullRange();
5103 }
5104
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005105 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 if (!CXXUnit)
5107 return clang_getNullRange();
5108
5109 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5110 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5111}
5112
5113static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5114 SmallVectorImpl<CXToken> &CXTokens) {
5115 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5116 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005117 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005119 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005120
5121 // Cannot tokenize across files.
5122 if (BeginLocInfo.first != EndLocInfo.first)
5123 return;
5124
5125 // Create a lexer
5126 bool Invalid = false;
5127 StringRef Buffer
5128 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5129 if (Invalid)
5130 return;
5131
5132 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5133 CXXUnit->getASTContext().getLangOpts(),
5134 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5135 Lex.SetCommentRetentionState(true);
5136
5137 // Lex tokens until we hit the end of the range.
5138 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5139 Token Tok;
5140 bool previousWasAt = false;
5141 do {
5142 // Lex the next token
5143 Lex.LexFromRawLexer(Tok);
5144 if (Tok.is(tok::eof))
5145 break;
5146
5147 // Initialize the CXToken.
5148 CXToken CXTok;
5149
5150 // - Common fields
5151 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5152 CXTok.int_data[2] = Tok.getLength();
5153 CXTok.int_data[3] = 0;
5154
5155 // - Kind-specific fields
5156 if (Tok.isLiteral()) {
5157 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005158 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 } else if (Tok.is(tok::raw_identifier)) {
5160 // Lookup the identifier to determine whether we have a keyword.
5161 IdentifierInfo *II
5162 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5163
5164 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5165 CXTok.int_data[0] = CXToken_Keyword;
5166 }
5167 else {
5168 CXTok.int_data[0] = Tok.is(tok::identifier)
5169 ? CXToken_Identifier
5170 : CXToken_Keyword;
5171 }
5172 CXTok.ptr_data = II;
5173 } else if (Tok.is(tok::comment)) {
5174 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005175 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 } else {
5177 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005178 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 }
5180 CXTokens.push_back(CXTok);
5181 previousWasAt = Tok.is(tok::at);
5182 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5183}
5184
5185void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5186 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005187 LOG_FUNC_SECTION {
5188 *Log << TU << ' ' << Range;
5189 }
5190
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005192 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 if (NumTokens)
5194 *NumTokens = 0;
5195
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005196 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005197 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005198 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005199 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005200
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005201 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 if (!CXXUnit || !Tokens || !NumTokens)
5203 return;
5204
5205 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5206
5207 SourceRange R = cxloc::translateCXSourceRange(Range);
5208 if (R.isInvalid())
5209 return;
5210
5211 SmallVector<CXToken, 32> CXTokens;
5212 getTokens(CXXUnit, R, CXTokens);
5213
5214 if (CXTokens.empty())
5215 return;
5216
5217 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5218 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5219 *NumTokens = CXTokens.size();
5220}
5221
5222void clang_disposeTokens(CXTranslationUnit TU,
5223 CXToken *Tokens, unsigned NumTokens) {
5224 free(Tokens);
5225}
5226
5227} // end: extern "C"
5228
5229//===----------------------------------------------------------------------===//
5230// Token annotation APIs.
5231//===----------------------------------------------------------------------===//
5232
Guy Benyei11169dd2012-12-18 14:30:41 +00005233static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5234 CXCursor parent,
5235 CXClientData client_data);
5236static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5237 CXClientData client_data);
5238
5239namespace {
5240class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 CXToken *Tokens;
5242 CXCursor *Cursors;
5243 unsigned NumTokens;
5244 unsigned TokIdx;
5245 unsigned PreprocessingTokIdx;
5246 CursorVisitor AnnotateVis;
5247 SourceManager &SrcMgr;
5248 bool HasContextSensitiveKeywords;
5249
5250 struct PostChildrenInfo {
5251 CXCursor Cursor;
5252 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005253 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 unsigned BeforeChildrenTokenIdx;
5255 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005256 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005257
5258 CXToken &getTok(unsigned Idx) {
5259 assert(Idx < NumTokens);
5260 return Tokens[Idx];
5261 }
5262 const CXToken &getTok(unsigned Idx) const {
5263 assert(Idx < NumTokens);
5264 return Tokens[Idx];
5265 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 bool MoreTokens() const { return TokIdx < NumTokens; }
5267 unsigned NextToken() const { return TokIdx; }
5268 void AdvanceToken() { ++TokIdx; }
5269 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005270 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 }
5272 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005273 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 }
5275 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005276 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 }
5278
5279 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005280 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 SourceRange);
5282
5283public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005284 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005285 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005286 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005288 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 AnnotateTokensVisitor, this,
5290 /*VisitPreprocessorLast=*/true,
5291 /*VisitIncludedEntities=*/false,
5292 RegionOfInterest,
5293 /*VisitDeclsOnly=*/false,
5294 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005295 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 HasContextSensitiveKeywords(false) { }
5297
5298 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5299 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5300 bool postVisitChildren(CXCursor cursor);
5301 void AnnotateTokens();
5302
5303 /// \brief Determine whether the annotator saw any cursors that have
5304 /// context-sensitive keywords.
5305 bool hasContextSensitiveKeywords() const {
5306 return HasContextSensitiveKeywords;
5307 }
5308
5309 ~AnnotateTokensWorker() {
5310 assert(PostChildrenInfos.empty());
5311 }
5312};
5313}
5314
5315void AnnotateTokensWorker::AnnotateTokens() {
5316 // Walk the AST within the region of interest, annotating tokens
5317 // along the way.
5318 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005319}
Guy Benyei11169dd2012-12-18 14:30:41 +00005320
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005321static inline void updateCursorAnnotation(CXCursor &Cursor,
5322 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005323 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005325 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005326}
5327
5328/// \brief It annotates and advances tokens with a cursor until the comparison
5329//// between the cursor location and the source range is the same as
5330/// \arg compResult.
5331///
5332/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5333/// Pass RangeOverlap to annotate tokens inside a range.
5334void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5335 RangeComparisonResult compResult,
5336 SourceRange range) {
5337 while (MoreTokens()) {
5338 const unsigned I = NextToken();
5339 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005340 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5341 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005342
5343 SourceLocation TokLoc = GetTokenLoc(I);
5344 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005345 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 AdvanceToken();
5347 continue;
5348 }
5349 break;
5350 }
5351}
5352
5353/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005354/// \returns true if it advanced beyond all macro tokens, false otherwise.
5355bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 CXCursor updateC,
5357 RangeComparisonResult compResult,
5358 SourceRange range) {
5359 assert(MoreTokens());
5360 assert(isFunctionMacroToken(NextToken()) &&
5361 "Should be called only for macro arg tokens");
5362
5363 // This works differently than annotateAndAdvanceTokens; because expanded
5364 // macro arguments can have arbitrary translation-unit source order, we do not
5365 // advance the token index one by one until a token fails the range test.
5366 // We only advance once past all of the macro arg tokens if all of them
5367 // pass the range test. If one of them fails we keep the token index pointing
5368 // at the start of the macro arg tokens so that the failing token will be
5369 // annotated by a subsequent annotation try.
5370
5371 bool atLeastOneCompFail = false;
5372
5373 unsigned I = NextToken();
5374 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5375 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5376 if (TokLoc.isFileID())
5377 continue; // not macro arg token, it's parens or comma.
5378 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5379 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5380 Cursors[I] = updateC;
5381 } else
5382 atLeastOneCompFail = true;
5383 }
5384
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005385 if (atLeastOneCompFail)
5386 return false;
5387
5388 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5389 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005390}
5391
5392enum CXChildVisitResult
5393AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 SourceRange cursorRange = getRawCursorExtent(cursor);
5395 if (cursorRange.isInvalid())
5396 return CXChildVisit_Recurse;
5397
5398 if (!HasContextSensitiveKeywords) {
5399 // Objective-C properties can have context-sensitive keywords.
5400 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005401 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5403 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5404 }
5405 // Objective-C methods can have context-sensitive keywords.
5406 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5407 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005408 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5410 if (Method->getObjCDeclQualifier())
5411 HasContextSensitiveKeywords = true;
5412 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005413 for (const auto *P : Method->params()) {
5414 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 HasContextSensitiveKeywords = true;
5416 break;
5417 }
5418 }
5419 }
5420 }
5421 }
5422 // C++ methods can have context-sensitive keywords.
5423 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005424 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5426 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5427 HasContextSensitiveKeywords = true;
5428 }
5429 }
5430 // C++ classes can have context-sensitive keywords.
5431 else if (cursor.kind == CXCursor_StructDecl ||
5432 cursor.kind == CXCursor_ClassDecl ||
5433 cursor.kind == CXCursor_ClassTemplate ||
5434 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005435 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 if (D->hasAttr<FinalAttr>())
5437 HasContextSensitiveKeywords = true;
5438 }
5439 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005440
5441 // Don't override a property annotation with its getter/setter method.
5442 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5443 parent.kind == CXCursor_ObjCPropertyDecl)
5444 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005445
5446 if (clang_isPreprocessing(cursor.kind)) {
5447 // Items in the preprocessing record are kept separate from items in
5448 // declarations, so we keep a separate token index.
5449 unsigned SavedTokIdx = TokIdx;
5450 TokIdx = PreprocessingTokIdx;
5451
5452 // Skip tokens up until we catch up to the beginning of the preprocessing
5453 // entry.
5454 while (MoreTokens()) {
5455 const unsigned I = NextToken();
5456 SourceLocation TokLoc = GetTokenLoc(I);
5457 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5458 case RangeBefore:
5459 AdvanceToken();
5460 continue;
5461 case RangeAfter:
5462 case RangeOverlap:
5463 break;
5464 }
5465 break;
5466 }
5467
5468 // Look at all of the tokens within this range.
5469 while (MoreTokens()) {
5470 const unsigned I = NextToken();
5471 SourceLocation TokLoc = GetTokenLoc(I);
5472 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5473 case RangeBefore:
5474 llvm_unreachable("Infeasible");
5475 case RangeAfter:
5476 break;
5477 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005478 // For macro expansions, just note where the beginning of the macro
5479 // expansion occurs.
5480 if (cursor.kind == CXCursor_MacroExpansion) {
5481 if (TokLoc == cursorRange.getBegin())
5482 Cursors[I] = cursor;
5483 AdvanceToken();
5484 break;
5485 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005486 // We may have already annotated macro names inside macro definitions.
5487 if (Cursors[I].kind != CXCursor_MacroExpansion)
5488 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 continue;
5491 }
5492 break;
5493 }
5494
5495 // Save the preprocessing token index; restore the non-preprocessing
5496 // token index.
5497 PreprocessingTokIdx = TokIdx;
5498 TokIdx = SavedTokIdx;
5499 return CXChildVisit_Recurse;
5500 }
5501
5502 if (cursorRange.isInvalid())
5503 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005504
5505 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 const enum CXCursorKind K = clang_getCursorKind(parent);
5508 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005509 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5510 // Attributes are annotated out-of-order, skip tokens until we reach it.
5511 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 ? clang_getNullCursor() : parent;
5513
5514 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5515
5516 // Avoid having the cursor of an expression "overwrite" the annotation of the
5517 // variable declaration that it belongs to.
5518 // This can happen for C++ constructor expressions whose range generally
5519 // include the variable declaration, e.g.:
5520 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005521 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005522 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005523 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 const unsigned I = NextToken();
5525 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5526 E->getLocStart() == D->getLocation() &&
5527 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005528 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 AdvanceToken();
5530 }
5531 }
5532 }
5533
5534 // Before recursing into the children keep some state that we are going
5535 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5536 // extra work after the child nodes are visited.
5537 // Note that we don't call VisitChildren here to avoid traversing statements
5538 // code-recursively which can blow the stack.
5539
5540 PostChildrenInfo Info;
5541 Info.Cursor = cursor;
5542 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005543 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 Info.BeforeChildrenTokenIdx = NextToken();
5545 PostChildrenInfos.push_back(Info);
5546
5547 return CXChildVisit_Recurse;
5548}
5549
5550bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5551 if (PostChildrenInfos.empty())
5552 return false;
5553 const PostChildrenInfo &Info = PostChildrenInfos.back();
5554 if (!clang_equalCursors(Info.Cursor, cursor))
5555 return false;
5556
5557 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5558 const unsigned AfterChildren = NextToken();
5559 SourceRange cursorRange = Info.CursorRange;
5560
5561 // Scan the tokens that are at the end of the cursor, but are not captured
5562 // but the child cursors.
5563 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5564
5565 // Scan the tokens that are at the beginning of the cursor, but are not
5566 // capture by the child cursors.
5567 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5568 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5569 break;
5570
5571 Cursors[I] = cursor;
5572 }
5573
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005574 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5575 // encountered the attribute cursor.
5576 if (clang_isAttribute(cursor.kind))
5577 TokIdx = Info.BeforeReachingCursorIdx;
5578
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 PostChildrenInfos.pop_back();
5580 return false;
5581}
5582
5583static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5584 CXCursor parent,
5585 CXClientData client_data) {
5586 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5587}
5588
5589static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5590 CXClientData client_data) {
5591 return static_cast<AnnotateTokensWorker*>(client_data)->
5592 postVisitChildren(cursor);
5593}
5594
5595namespace {
5596
5597/// \brief Uses the macro expansions in the preprocessing record to find
5598/// and mark tokens that are macro arguments. This info is used by the
5599/// AnnotateTokensWorker.
5600class MarkMacroArgTokensVisitor {
5601 SourceManager &SM;
5602 CXToken *Tokens;
5603 unsigned NumTokens;
5604 unsigned CurIdx;
5605
5606public:
5607 MarkMacroArgTokensVisitor(SourceManager &SM,
5608 CXToken *tokens, unsigned numTokens)
5609 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5610
5611 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5612 if (cursor.kind != CXCursor_MacroExpansion)
5613 return CXChildVisit_Continue;
5614
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005615 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 if (macroRange.getBegin() == macroRange.getEnd())
5617 return CXChildVisit_Continue; // it's not a function macro.
5618
5619 for (; CurIdx < NumTokens; ++CurIdx) {
5620 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5621 macroRange.getBegin()))
5622 break;
5623 }
5624
5625 if (CurIdx == NumTokens)
5626 return CXChildVisit_Break;
5627
5628 for (; CurIdx < NumTokens; ++CurIdx) {
5629 SourceLocation tokLoc = getTokenLoc(CurIdx);
5630 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5631 break;
5632
5633 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5634 }
5635
5636 if (CurIdx == NumTokens)
5637 return CXChildVisit_Break;
5638
5639 return CXChildVisit_Continue;
5640 }
5641
5642private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005643 CXToken &getTok(unsigned Idx) {
5644 assert(Idx < NumTokens);
5645 return Tokens[Idx];
5646 }
5647 const CXToken &getTok(unsigned Idx) const {
5648 assert(Idx < NumTokens);
5649 return Tokens[Idx];
5650 }
5651
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005653 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 }
5655
5656 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5657 // The third field is reserved and currently not used. Use it here
5658 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005659 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 }
5661};
5662
5663} // end anonymous namespace
5664
5665static CXChildVisitResult
5666MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5667 CXClientData client_data) {
5668 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5669 parent);
5670}
5671
5672namespace {
5673 struct clang_annotateTokens_Data {
5674 CXTranslationUnit TU;
5675 ASTUnit *CXXUnit;
5676 CXToken *Tokens;
5677 unsigned NumTokens;
5678 CXCursor *Cursors;
5679 };
5680}
5681
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005682/// \brief Used by \c annotatePreprocessorTokens.
5683/// \returns true if lexing was finished, false otherwise.
5684static bool lexNext(Lexer &Lex, Token &Tok,
5685 unsigned &NextIdx, unsigned NumTokens) {
5686 if (NextIdx >= NumTokens)
5687 return true;
5688
5689 ++NextIdx;
5690 Lex.LexFromRawLexer(Tok);
5691 if (Tok.is(tok::eof))
5692 return true;
5693
5694 return false;
5695}
5696
Guy Benyei11169dd2012-12-18 14:30:41 +00005697static void annotatePreprocessorTokens(CXTranslationUnit TU,
5698 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699 CXCursor *Cursors,
5700 CXToken *Tokens,
5701 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005702 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005703
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005704 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5706 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005707 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005709 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005710
5711 if (BeginLocInfo.first != EndLocInfo.first)
5712 return;
5713
5714 StringRef Buffer;
5715 bool Invalid = false;
5716 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5717 if (Buffer.empty() || Invalid)
5718 return;
5719
5720 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5721 CXXUnit->getASTContext().getLangOpts(),
5722 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5723 Buffer.end());
5724 Lex.SetCommentRetentionState(true);
5725
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005726 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 // Lex tokens in raw mode until we hit the end of the range, to avoid
5728 // entering #includes or expanding macros.
5729 while (true) {
5730 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005731 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5732 break;
5733 unsigned TokIdx = NextIdx-1;
5734 assert(Tok.getLocation() ==
5735 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005736
5737 reprocess:
5738 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005739 // We have found a preprocessing directive. Annotate the tokens
5740 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 //
5742 // FIXME: Some simple tests here could identify macro definitions and
5743 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005744
5745 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005746 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5747 break;
5748
Craig Topper69186e72014-06-08 08:38:04 +00005749 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005750 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005751 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5752 break;
5753
5754 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005755 IdentifierInfo &II =
5756 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005757 SourceLocation MappedTokLoc =
5758 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5759 MI = getMacroInfo(II, MappedTokLoc, TU);
5760 }
5761 }
5762
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005763 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005765 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5766 finished = true;
5767 break;
5768 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005769 // If we are in a macro definition, check if the token was ever a
5770 // macro name and annotate it if that's the case.
5771 if (MI) {
5772 SourceLocation SaveLoc = Tok.getLocation();
5773 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5774 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5775 Tok.setLocation(SaveLoc);
5776 if (MacroDef)
5777 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5778 Tok.getLocation(), TU);
5779 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005780 } while (!Tok.isAtStartOfLine());
5781
5782 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5783 assert(TokIdx <= LastIdx);
5784 SourceLocation EndLoc =
5785 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5786 CXCursor Cursor =
5787 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5788
5789 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005790 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005791
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005792 if (finished)
5793 break;
5794 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 }
5797}
5798
5799// This gets run a separate thread to avoid stack blowout.
5800static void clang_annotateTokensImpl(void *UserData) {
5801 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5802 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5803 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5804 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5805 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5806
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005807 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5809 setThreadBackgroundPriority();
5810
5811 // Determine the region of interest, which contains all of the tokens.
5812 SourceRange RegionOfInterest;
5813 RegionOfInterest.setBegin(
5814 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5815 RegionOfInterest.setEnd(
5816 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5817 Tokens[NumTokens-1])));
5818
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 // Relex the tokens within the source range to look for preprocessing
5820 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005821 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005822
5823 // If begin location points inside a macro argument, set it to the expansion
5824 // location so we can have the full context when annotating semantically.
5825 {
5826 SourceManager &SM = CXXUnit->getSourceManager();
5827 SourceLocation Loc =
5828 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5829 if (Loc.isMacroID())
5830 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5831 }
5832
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5834 // Search and mark tokens that are macro argument expansions.
5835 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5836 Tokens, NumTokens);
5837 CursorVisitor MacroArgMarker(TU,
5838 MarkMacroArgTokensVisitorDelegate, &Visitor,
5839 /*VisitPreprocessorLast=*/true,
5840 /*VisitIncludedEntities=*/false,
5841 RegionOfInterest);
5842 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5843 }
5844
5845 // Annotate all of the source locations in the region of interest that map to
5846 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005847 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005848
5849 // FIXME: We use a ridiculous stack size here because the data-recursion
5850 // algorithm uses a large stack frame than the non-data recursive version,
5851 // and AnnotationTokensWorker currently transforms the data-recursion
5852 // algorithm back into a traditional recursion by explicitly calling
5853 // VisitChildren(). We will need to remove this explicit recursive call.
5854 W.AnnotateTokens();
5855
5856 // If we ran into any entities that involve context-sensitive keywords,
5857 // take another pass through the tokens to mark them as such.
5858 if (W.hasContextSensitiveKeywords()) {
5859 for (unsigned I = 0; I != NumTokens; ++I) {
5860 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5861 continue;
5862
5863 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5864 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005865 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005866 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5867 if (Property->getPropertyAttributesAsWritten() != 0 &&
5868 llvm::StringSwitch<bool>(II->getName())
5869 .Case("readonly", true)
5870 .Case("assign", true)
5871 .Case("unsafe_unretained", true)
5872 .Case("readwrite", true)
5873 .Case("retain", true)
5874 .Case("copy", true)
5875 .Case("nonatomic", true)
5876 .Case("atomic", true)
5877 .Case("getter", true)
5878 .Case("setter", true)
5879 .Case("strong", true)
5880 .Case("weak", true)
5881 .Default(false))
5882 Tokens[I].int_data[0] = CXToken_Keyword;
5883 }
5884 continue;
5885 }
5886
5887 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5888 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5889 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5890 if (llvm::StringSwitch<bool>(II->getName())
5891 .Case("in", true)
5892 .Case("out", true)
5893 .Case("inout", true)
5894 .Case("oneway", true)
5895 .Case("bycopy", true)
5896 .Case("byref", true)
5897 .Default(false))
5898 Tokens[I].int_data[0] = CXToken_Keyword;
5899 continue;
5900 }
5901
5902 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5903 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5904 Tokens[I].int_data[0] = CXToken_Keyword;
5905 continue;
5906 }
5907 }
5908 }
5909}
5910
5911extern "C" {
5912
5913void clang_annotateTokens(CXTranslationUnit TU,
5914 CXToken *Tokens, unsigned NumTokens,
5915 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005916 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005917 LOG_BAD_TU(TU);
5918 return;
5919 }
5920 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005921 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005923 }
5924
5925 LOG_FUNC_SECTION {
5926 *Log << TU << ' ';
5927 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5928 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5929 *Log << clang_getRange(bloc, eloc);
5930 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005931
5932 // Any token we don't specifically annotate will have a NULL cursor.
5933 CXCursor C = clang_getNullCursor();
5934 for (unsigned I = 0; I != NumTokens; ++I)
5935 Cursors[I] = C;
5936
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005937 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 if (!CXXUnit)
5939 return;
5940
5941 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5942
5943 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5944 llvm::CrashRecoveryContext CRC;
5945 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5946 GetSafetyThreadStackSize() * 2)) {
5947 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5948 }
5949}
5950
5951} // end: extern "C"
5952
5953//===----------------------------------------------------------------------===//
5954// Operations for querying linkage of a cursor.
5955//===----------------------------------------------------------------------===//
5956
5957extern "C" {
5958CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5959 if (!clang_isDeclaration(cursor.kind))
5960 return CXLinkage_Invalid;
5961
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005962 const Decl *D = cxcursor::getCursorDecl(cursor);
5963 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005964 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005965 case NoLinkage:
5966 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005967 case InternalLinkage: return CXLinkage_Internal;
5968 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5969 case ExternalLinkage: return CXLinkage_External;
5970 };
5971
5972 return CXLinkage_Invalid;
5973}
5974} // end: extern "C"
5975
5976//===----------------------------------------------------------------------===//
5977// Operations for querying language of a cursor.
5978//===----------------------------------------------------------------------===//
5979
5980static CXLanguageKind getDeclLanguage(const Decl *D) {
5981 if (!D)
5982 return CXLanguage_C;
5983
5984 switch (D->getKind()) {
5985 default:
5986 break;
5987 case Decl::ImplicitParam:
5988 case Decl::ObjCAtDefsField:
5989 case Decl::ObjCCategory:
5990 case Decl::ObjCCategoryImpl:
5991 case Decl::ObjCCompatibleAlias:
5992 case Decl::ObjCImplementation:
5993 case Decl::ObjCInterface:
5994 case Decl::ObjCIvar:
5995 case Decl::ObjCMethod:
5996 case Decl::ObjCProperty:
5997 case Decl::ObjCPropertyImpl:
5998 case Decl::ObjCProtocol:
5999 return CXLanguage_ObjC;
6000 case Decl::CXXConstructor:
6001 case Decl::CXXConversion:
6002 case Decl::CXXDestructor:
6003 case Decl::CXXMethod:
6004 case Decl::CXXRecord:
6005 case Decl::ClassTemplate:
6006 case Decl::ClassTemplatePartialSpecialization:
6007 case Decl::ClassTemplateSpecialization:
6008 case Decl::Friend:
6009 case Decl::FriendTemplate:
6010 case Decl::FunctionTemplate:
6011 case Decl::LinkageSpec:
6012 case Decl::Namespace:
6013 case Decl::NamespaceAlias:
6014 case Decl::NonTypeTemplateParm:
6015 case Decl::StaticAssert:
6016 case Decl::TemplateTemplateParm:
6017 case Decl::TemplateTypeParm:
6018 case Decl::UnresolvedUsingTypename:
6019 case Decl::UnresolvedUsingValue:
6020 case Decl::Using:
6021 case Decl::UsingDirective:
6022 case Decl::UsingShadow:
6023 return CXLanguage_CPlusPlus;
6024 }
6025
6026 return CXLanguage_C;
6027}
6028
6029extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006030
6031static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6032 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6033 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006034
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006035 switch (D->getAvailability()) {
6036 case AR_Available:
6037 case AR_NotYetIntroduced:
6038 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006039 return getCursorAvailabilityForDecl(
6040 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006041 return CXAvailability_Available;
6042
6043 case AR_Deprecated:
6044 return CXAvailability_Deprecated;
6045
6046 case AR_Unavailable:
6047 return CXAvailability_NotAvailable;
6048 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006049
6050 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006051}
6052
Guy Benyei11169dd2012-12-18 14:30:41 +00006053enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6054 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006055 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6056 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006057
6058 return CXAvailability_Available;
6059}
6060
6061static CXVersion convertVersion(VersionTuple In) {
6062 CXVersion Out = { -1, -1, -1 };
6063 if (In.empty())
6064 return Out;
6065
6066 Out.Major = In.getMajor();
6067
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006068 Optional<unsigned> Minor = In.getMinor();
6069 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006070 Out.Minor = *Minor;
6071 else
6072 return Out;
6073
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006074 Optional<unsigned> Subminor = In.getSubminor();
6075 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006076 Out.Subminor = *Subminor;
6077
6078 return Out;
6079}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006080
6081static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6082 int *always_deprecated,
6083 CXString *deprecated_message,
6084 int *always_unavailable,
6085 CXString *unavailable_message,
6086 CXPlatformAvailability *availability,
6087 int availability_size) {
6088 bool HadAvailAttr = false;
6089 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006090 for (auto A : D->attrs()) {
6091 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006092 HadAvailAttr = true;
6093 if (always_deprecated)
6094 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006095 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006096 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006098 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006099 continue;
6100 }
6101
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006102 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006103 HadAvailAttr = true;
6104 if (always_unavailable)
6105 *always_unavailable = 1;
6106 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006107 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006108 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6109 }
6110 continue;
6111 }
6112
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006113 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006114 HadAvailAttr = true;
6115 if (N < availability_size) {
6116 availability[N].Platform
6117 = cxstring::createDup(Avail->getPlatform()->getName());
6118 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6119 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6120 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6121 availability[N].Unavailable = Avail->getUnavailable();
6122 availability[N].Message = cxstring::createDup(Avail->getMessage());
6123 }
6124 ++N;
6125 }
6126 }
6127
6128 if (!HadAvailAttr)
6129 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6130 return getCursorPlatformAvailabilityForDecl(
6131 cast<Decl>(EnumConst->getDeclContext()),
6132 always_deprecated,
6133 deprecated_message,
6134 always_unavailable,
6135 unavailable_message,
6136 availability,
6137 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006138
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006139 return N;
6140}
6141
Guy Benyei11169dd2012-12-18 14:30:41 +00006142int clang_getCursorPlatformAvailability(CXCursor cursor,
6143 int *always_deprecated,
6144 CXString *deprecated_message,
6145 int *always_unavailable,
6146 CXString *unavailable_message,
6147 CXPlatformAvailability *availability,
6148 int availability_size) {
6149 if (always_deprecated)
6150 *always_deprecated = 0;
6151 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006152 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 if (always_unavailable)
6154 *always_unavailable = 0;
6155 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006156 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006157
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 if (!clang_isDeclaration(cursor.kind))
6159 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006160
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006161 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 if (!D)
6163 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006164
6165 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6166 deprecated_message,
6167 always_unavailable,
6168 unavailable_message,
6169 availability,
6170 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006171}
6172
6173void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6174 clang_disposeString(availability->Platform);
6175 clang_disposeString(availability->Message);
6176}
6177
6178CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6179 if (clang_isDeclaration(cursor.kind))
6180 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6181
6182 return CXLanguage_Invalid;
6183}
6184
6185 /// \brief If the given cursor is the "templated" declaration
6186 /// descibing a class or function template, return the class or
6187 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006188static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006190 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006192 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6194 return FunTmpl;
6195
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006196 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6198 return ClassTmpl;
6199
6200 return D;
6201}
6202
6203CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6204 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006205 if (const Decl *D = getCursorDecl(cursor)) {
6206 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006207 if (!DC)
6208 return clang_getNullCursor();
6209
6210 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6211 getCursorTU(cursor));
6212 }
6213 }
6214
6215 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 return MakeCXCursor(D, getCursorTU(cursor));
6218 }
6219
6220 return clang_getNullCursor();
6221}
6222
6223CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6224 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006225 if (const Decl *D = getCursorDecl(cursor)) {
6226 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 if (!DC)
6228 return clang_getNullCursor();
6229
6230 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6231 getCursorTU(cursor));
6232 }
6233 }
6234
6235 // FIXME: Note that we can't easily compute the lexical context of a
6236 // statement or expression, so we return nothing.
6237 return clang_getNullCursor();
6238}
6239
6240CXFile clang_getIncludedFile(CXCursor cursor) {
6241 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006242 return nullptr;
6243
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006244 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006245 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006246}
6247
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006248unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6249 if (C.kind != CXCursor_ObjCPropertyDecl)
6250 return CXObjCPropertyAttr_noattr;
6251
6252 unsigned Result = CXObjCPropertyAttr_noattr;
6253 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6254 ObjCPropertyDecl::PropertyAttributeKind Attr =
6255 PD->getPropertyAttributesAsWritten();
6256
6257#define SET_CXOBJCPROP_ATTR(A) \
6258 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6259 Result |= CXObjCPropertyAttr_##A
6260 SET_CXOBJCPROP_ATTR(readonly);
6261 SET_CXOBJCPROP_ATTR(getter);
6262 SET_CXOBJCPROP_ATTR(assign);
6263 SET_CXOBJCPROP_ATTR(readwrite);
6264 SET_CXOBJCPROP_ATTR(retain);
6265 SET_CXOBJCPROP_ATTR(copy);
6266 SET_CXOBJCPROP_ATTR(nonatomic);
6267 SET_CXOBJCPROP_ATTR(setter);
6268 SET_CXOBJCPROP_ATTR(atomic);
6269 SET_CXOBJCPROP_ATTR(weak);
6270 SET_CXOBJCPROP_ATTR(strong);
6271 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6272#undef SET_CXOBJCPROP_ATTR
6273
6274 return Result;
6275}
6276
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006277unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6278 if (!clang_isDeclaration(C.kind))
6279 return CXObjCDeclQualifier_None;
6280
6281 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6282 const Decl *D = getCursorDecl(C);
6283 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6284 QT = MD->getObjCDeclQualifier();
6285 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6286 QT = PD->getObjCDeclQualifier();
6287 if (QT == Decl::OBJC_TQ_None)
6288 return CXObjCDeclQualifier_None;
6289
6290 unsigned Result = CXObjCDeclQualifier_None;
6291 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6292 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6293 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6294 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6295 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6296 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6297
6298 return Result;
6299}
6300
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006301unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6302 if (!clang_isDeclaration(C.kind))
6303 return 0;
6304
6305 const Decl *D = getCursorDecl(C);
6306 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6307 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6308 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6309 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6310
6311 return 0;
6312}
6313
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006314unsigned clang_Cursor_isVariadic(CXCursor C) {
6315 if (!clang_isDeclaration(C.kind))
6316 return 0;
6317
6318 const Decl *D = getCursorDecl(C);
6319 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6320 return FD->isVariadic();
6321 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6322 return MD->isVariadic();
6323
6324 return 0;
6325}
6326
Guy Benyei11169dd2012-12-18 14:30:41 +00006327CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6328 if (!clang_isDeclaration(C.kind))
6329 return clang_getNullRange();
6330
6331 const Decl *D = getCursorDecl(C);
6332 ASTContext &Context = getCursorContext(C);
6333 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6334 if (!RC)
6335 return clang_getNullRange();
6336
6337 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6338}
6339
6340CXString clang_Cursor_getRawCommentText(CXCursor C) {
6341 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006342 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006343
6344 const Decl *D = getCursorDecl(C);
6345 ASTContext &Context = getCursorContext(C);
6346 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6347 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6348 StringRef();
6349
6350 // Don't duplicate the string because RawText points directly into source
6351 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006352 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006353}
6354
6355CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6356 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006357 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006358
6359 const Decl *D = getCursorDecl(C);
6360 const ASTContext &Context = getCursorContext(C);
6361 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6362
6363 if (RC) {
6364 StringRef BriefText = RC->getBriefText(Context);
6365
6366 // Don't duplicate the string because RawComment ensures that this memory
6367 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006368 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006369 }
6370
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006371 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006372}
6373
Guy Benyei11169dd2012-12-18 14:30:41 +00006374CXModule clang_Cursor_getModule(CXCursor C) {
6375 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006376 if (const ImportDecl *ImportD =
6377 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006378 return ImportD->getImportedModule();
6379 }
6380
Craig Topper69186e72014-06-08 08:38:04 +00006381 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006382}
6383
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006384CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6385 if (isNotUsableTU(TU)) {
6386 LOG_BAD_TU(TU);
6387 return nullptr;
6388 }
6389 if (!File)
6390 return nullptr;
6391 FileEntry *FE = static_cast<FileEntry *>(File);
6392
6393 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6394 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6395 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6396
6397 if (Module *Mod = Header.getModule()) {
6398 if (Header.getRole() != ModuleMap::ExcludedHeader)
6399 return Mod;
6400 }
6401 return nullptr;
6402}
6403
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006404CXFile clang_Module_getASTFile(CXModule CXMod) {
6405 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006406 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006407 Module *Mod = static_cast<Module*>(CXMod);
6408 return const_cast<FileEntry *>(Mod->getASTFile());
6409}
6410
Guy Benyei11169dd2012-12-18 14:30:41 +00006411CXModule clang_Module_getParent(CXModule CXMod) {
6412 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006413 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 Module *Mod = static_cast<Module*>(CXMod);
6415 return Mod->Parent;
6416}
6417
6418CXString clang_Module_getName(CXModule CXMod) {
6419 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006422 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006423}
6424
6425CXString clang_Module_getFullName(CXModule CXMod) {
6426 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006427 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006429 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006430}
6431
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006432int clang_Module_isSystem(CXModule CXMod) {
6433 if (!CXMod)
6434 return 0;
6435 Module *Mod = static_cast<Module*>(CXMod);
6436 return Mod->IsSystem;
6437}
6438
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006439unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6440 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006441 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006442 LOG_BAD_TU(TU);
6443 return 0;
6444 }
6445 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 return 0;
6447 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006448 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6449 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6450 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006451}
6452
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006453CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6454 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006455 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006456 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006457 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006458 }
6459 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006460 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006461 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006462 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006463
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006464 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6465 if (Index < TopHeaders.size())
6466 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006467
Craig Topper69186e72014-06-08 08:38:04 +00006468 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006469}
6470
6471} // end: extern "C"
6472
6473//===----------------------------------------------------------------------===//
6474// C++ AST instrospection.
6475//===----------------------------------------------------------------------===//
6476
6477extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006478unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6479 if (!clang_isDeclaration(C.kind))
6480 return 0;
6481
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006482 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006483 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006484 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006485 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6486}
6487
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006488unsigned clang_CXXMethod_isConst(CXCursor C) {
6489 if (!clang_isDeclaration(C.kind))
6490 return 0;
6491
6492 const Decl *D = cxcursor::getCursorDecl(C);
6493 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006494 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006495 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6496}
6497
Guy Benyei11169dd2012-12-18 14:30:41 +00006498unsigned clang_CXXMethod_isStatic(CXCursor C) {
6499 if (!clang_isDeclaration(C.kind))
6500 return 0;
6501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006502 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006503 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006504 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 return (Method && Method->isStatic()) ? 1 : 0;
6506}
6507
6508unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6509 if (!clang_isDeclaration(C.kind))
6510 return 0;
6511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006512 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006513 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006514 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 return (Method && Method->isVirtual()) ? 1 : 0;
6516}
6517} // end: extern "C"
6518
6519//===----------------------------------------------------------------------===//
6520// Attribute introspection.
6521//===----------------------------------------------------------------------===//
6522
6523extern "C" {
6524CXType clang_getIBOutletCollectionType(CXCursor C) {
6525 if (C.kind != CXCursor_IBOutletCollectionAttr)
6526 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6527
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006528 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6530
6531 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6532}
6533} // end: extern "C"
6534
6535//===----------------------------------------------------------------------===//
6536// Inspecting memory usage.
6537//===----------------------------------------------------------------------===//
6538
6539typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6540
6541static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6542 enum CXTUResourceUsageKind k,
6543 unsigned long amount) {
6544 CXTUResourceUsageEntry entry = { k, amount };
6545 entries.push_back(entry);
6546}
6547
6548extern "C" {
6549
6550const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6551 const char *str = "";
6552 switch (kind) {
6553 case CXTUResourceUsage_AST:
6554 str = "ASTContext: expressions, declarations, and types";
6555 break;
6556 case CXTUResourceUsage_Identifiers:
6557 str = "ASTContext: identifiers";
6558 break;
6559 case CXTUResourceUsage_Selectors:
6560 str = "ASTContext: selectors";
6561 break;
6562 case CXTUResourceUsage_GlobalCompletionResults:
6563 str = "Code completion: cached global results";
6564 break;
6565 case CXTUResourceUsage_SourceManagerContentCache:
6566 str = "SourceManager: content cache allocator";
6567 break;
6568 case CXTUResourceUsage_AST_SideTables:
6569 str = "ASTContext: side tables";
6570 break;
6571 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6572 str = "SourceManager: malloc'ed memory buffers";
6573 break;
6574 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6575 str = "SourceManager: mmap'ed memory buffers";
6576 break;
6577 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6578 str = "ExternalASTSource: malloc'ed memory buffers";
6579 break;
6580 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6581 str = "ExternalASTSource: mmap'ed memory buffers";
6582 break;
6583 case CXTUResourceUsage_Preprocessor:
6584 str = "Preprocessor: malloc'ed memory";
6585 break;
6586 case CXTUResourceUsage_PreprocessingRecord:
6587 str = "Preprocessor: PreprocessingRecord";
6588 break;
6589 case CXTUResourceUsage_SourceManager_DataStructures:
6590 str = "SourceManager: data structures and tables";
6591 break;
6592 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6593 str = "Preprocessor: header search tables";
6594 break;
6595 }
6596 return str;
6597}
6598
6599CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006600 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006601 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006602 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006603 return usage;
6604 }
6605
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006606 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006607 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 ASTContext &astContext = astUnit->getASTContext();
6609
6610 // How much memory is used by AST nodes and types?
6611 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6612 (unsigned long) astContext.getASTAllocatedMemory());
6613
6614 // How much memory is used by identifiers?
6615 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6616 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6617
6618 // How much memory is used for selectors?
6619 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6620 (unsigned long) astContext.Selectors.getTotalMemory());
6621
6622 // How much memory is used by ASTContext's side tables?
6623 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6624 (unsigned long) astContext.getSideTableAllocatedMemory());
6625
6626 // How much memory is used for caching global code completion results?
6627 unsigned long completionBytes = 0;
6628 if (GlobalCodeCompletionAllocator *completionAllocator =
6629 astUnit->getCachedCompletionAllocator().getPtr()) {
6630 completionBytes = completionAllocator->getTotalMemory();
6631 }
6632 createCXTUResourceUsageEntry(*entries,
6633 CXTUResourceUsage_GlobalCompletionResults,
6634 completionBytes);
6635
6636 // How much memory is being used by SourceManager's content cache?
6637 createCXTUResourceUsageEntry(*entries,
6638 CXTUResourceUsage_SourceManagerContentCache,
6639 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6640
6641 // How much memory is being used by the MemoryBuffer's in SourceManager?
6642 const SourceManager::MemoryBufferSizes &srcBufs =
6643 astUnit->getSourceManager().getMemoryBufferSizes();
6644
6645 createCXTUResourceUsageEntry(*entries,
6646 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6647 (unsigned long) srcBufs.malloc_bytes);
6648 createCXTUResourceUsageEntry(*entries,
6649 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6650 (unsigned long) srcBufs.mmap_bytes);
6651 createCXTUResourceUsageEntry(*entries,
6652 CXTUResourceUsage_SourceManager_DataStructures,
6653 (unsigned long) astContext.getSourceManager()
6654 .getDataStructureSizes());
6655
6656 // How much memory is being used by the ExternalASTSource?
6657 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6658 const ExternalASTSource::MemoryBufferSizes &sizes =
6659 esrc->getMemoryBufferSizes();
6660
6661 createCXTUResourceUsageEntry(*entries,
6662 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6663 (unsigned long) sizes.malloc_bytes);
6664 createCXTUResourceUsageEntry(*entries,
6665 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6666 (unsigned long) sizes.mmap_bytes);
6667 }
6668
6669 // How much memory is being used by the Preprocessor?
6670 Preprocessor &pp = astUnit->getPreprocessor();
6671 createCXTUResourceUsageEntry(*entries,
6672 CXTUResourceUsage_Preprocessor,
6673 pp.getTotalMemory());
6674
6675 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6676 createCXTUResourceUsageEntry(*entries,
6677 CXTUResourceUsage_PreprocessingRecord,
6678 pRec->getTotalMemory());
6679 }
6680
6681 createCXTUResourceUsageEntry(*entries,
6682 CXTUResourceUsage_Preprocessor_HeaderSearch,
6683 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006684
Guy Benyei11169dd2012-12-18 14:30:41 +00006685 CXTUResourceUsage usage = { (void*) entries.get(),
6686 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006687 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006688 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006689 return usage;
6690}
6691
6692void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6693 if (usage.data)
6694 delete (MemUsageEntries*) usage.data;
6695}
6696
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006697CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6698 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006699 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006700 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006701
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006702 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006703 LOG_BAD_TU(TU);
6704 return skipped;
6705 }
6706
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006707 if (!file)
6708 return skipped;
6709
6710 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6711 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6712 if (!ppRec)
6713 return skipped;
6714
6715 ASTContext &Ctx = astUnit->getASTContext();
6716 SourceManager &sm = Ctx.getSourceManager();
6717 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6718 FileID wantedFileID = sm.translateFile(fileEntry);
6719
6720 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6721 std::vector<SourceRange> wantedRanges;
6722 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6723 i != ei; ++i) {
6724 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6725 wantedRanges.push_back(*i);
6726 }
6727
6728 skipped->count = wantedRanges.size();
6729 skipped->ranges = new CXSourceRange[skipped->count];
6730 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6731 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6732
6733 return skipped;
6734}
6735
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006736void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6737 if (ranges) {
6738 delete[] ranges->ranges;
6739 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006740 }
6741}
6742
Guy Benyei11169dd2012-12-18 14:30:41 +00006743} // end extern "C"
6744
6745void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6746 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6747 for (unsigned I = 0; I != Usage.numEntries; ++I)
6748 fprintf(stderr, " %s: %lu\n",
6749 clang_getTUResourceUsageName(Usage.entries[I].kind),
6750 Usage.entries[I].amount);
6751
6752 clang_disposeCXTUResourceUsage(Usage);
6753}
6754
6755//===----------------------------------------------------------------------===//
6756// Misc. utility functions.
6757//===----------------------------------------------------------------------===//
6758
6759/// Default to using an 8 MB stack size on "safety" threads.
6760static unsigned SafetyStackThreadSize = 8 << 20;
6761
6762namespace clang {
6763
6764bool RunSafely(llvm::CrashRecoveryContext &CRC,
6765 void (*Fn)(void*), void *UserData,
6766 unsigned Size) {
6767 if (!Size)
6768 Size = GetSafetyThreadStackSize();
6769 if (Size)
6770 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6771 return CRC.RunSafely(Fn, UserData);
6772}
6773
6774unsigned GetSafetyThreadStackSize() {
6775 return SafetyStackThreadSize;
6776}
6777
6778void SetSafetyThreadStackSize(unsigned Value) {
6779 SafetyStackThreadSize = Value;
6780}
6781
6782}
6783
6784void clang::setThreadBackgroundPriority() {
6785 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6786 return;
6787
6788 // FIXME: Move to llvm/Support and make it cross-platform.
6789#ifdef __APPLE__
6790 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6791#endif
6792}
6793
6794void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6795 if (!Unit)
6796 return;
6797
6798 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6799 DEnd = Unit->stored_diag_end();
6800 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006801 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006802 CXString Msg = clang_formatDiagnostic(&Diag,
6803 clang_defaultDiagnosticDisplayOptions());
6804 fprintf(stderr, "%s\n", clang_getCString(Msg));
6805 clang_disposeString(Msg);
6806 }
6807#ifdef LLVM_ON_WIN32
6808 // On Windows, force a flush, since there may be multiple copies of
6809 // stderr and stdout in the file system, all with different buffers
6810 // but writing to the same device.
6811 fflush(stderr);
6812#endif
6813}
6814
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006815MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6816 SourceLocation MacroDefLoc,
6817 CXTranslationUnit TU){
6818 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006820 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006821 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006822
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006823 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006824 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006825 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006826 if (MD) {
6827 for (MacroDirective::DefInfo
6828 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6829 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6830 return Def.getMacroInfo();
6831 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006832 }
6833
Craig Topper69186e72014-06-08 08:38:04 +00006834 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006835}
6836
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006837const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6838 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006839 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006841 const IdentifierInfo *II = MacroDef->getName();
6842 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006843 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006844
6845 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6846}
6847
6848MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6849 const Token &Tok,
6850 CXTranslationUnit TU) {
6851 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006852 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006853 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006854 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006855
6856 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6859 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006860 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006861
6862 // Check that the token is inside the definition and not its argument list.
6863 SourceManager &SM = Unit->getSourceManager();
6864 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006865 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006867 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006868
6869 Preprocessor &PP = Unit->getPreprocessor();
6870 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6871 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873
Alp Toker2d57cea2014-05-17 04:53:25 +00006874 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006875 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006876 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877
6878 // Check that the identifier is not one of the macro arguments.
6879 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006881
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006882 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6883 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006884 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006885
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006886 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006887}
6888
6889MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6890 SourceLocation Loc,
6891 CXTranslationUnit TU) {
6892 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006893 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006894
6895 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006896 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006897 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006898 Preprocessor &PP = Unit->getPreprocessor();
6899 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006900 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006901 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6902 Token Tok;
6903 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006905
6906 return checkForMacroInMacroDefinition(MI, Tok, TU);
6907}
6908
Guy Benyei11169dd2012-12-18 14:30:41 +00006909extern "C" {
6910
6911CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006912 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006913}
6914
6915} // end: extern "C"
6916
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006917Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6918 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006919 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006920 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006921 if (Unit->isMainFileAST())
6922 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006923 return *this;
6924 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006925 } else {
6926 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006927 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006928 return *this;
6929}
6930
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006931Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6932 *this << FE->getName();
6933 return *this;
6934}
6935
6936Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6937 CXString cursorName = clang_getCursorDisplayName(cursor);
6938 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6939 clang_disposeString(cursorName);
6940 return *this;
6941}
6942
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006943Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6944 CXFile File;
6945 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006946 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006947 CXString FileName = clang_getFileName(File);
6948 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6949 clang_disposeString(FileName);
6950 return *this;
6951}
6952
6953Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6954 CXSourceLocation BLoc = clang_getRangeStart(range);
6955 CXSourceLocation ELoc = clang_getRangeEnd(range);
6956
6957 CXFile BFile;
6958 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006959 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006960
6961 CXFile EFile;
6962 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006963 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006964
6965 CXString BFileName = clang_getFileName(BFile);
6966 if (BFile == EFile) {
6967 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6968 BLine, BColumn, ELine, EColumn);
6969 } else {
6970 CXString EFileName = clang_getFileName(EFile);
6971 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6972 BLine, BColumn)
6973 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6974 ELine, EColumn);
6975 clang_disposeString(EFileName);
6976 }
6977 clang_disposeString(BFileName);
6978 return *this;
6979}
6980
6981Logger &cxindex::Logger::operator<<(CXString Str) {
6982 *this << clang_getCString(Str);
6983 return *this;
6984}
6985
6986Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6987 LogOS << Fmt;
6988 return *this;
6989}
6990
6991cxindex::Logger::~Logger() {
6992 LogOS.flush();
6993
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00006994 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006995
6996 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6997
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006998 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006999 OS << "[libclang:" << Name << ':';
7000
7001 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00007002#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007003 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7004 OS << tid << ':';
7005#endif
7006
7007 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7008 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7009 OS << Msg.str() << '\n';
7010
7011 if (Trace) {
7012 llvm::sys::PrintStackTrace(stderr);
7013 OS << "--------------------------------------------------\n";
7014 }
7015}