blob: ab0cd6fddaada150a8f5108641ab5aff43a84bae [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856
Guy Benyei11169dd2012-12-18 14:30:41 +00001857private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1860 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1862 void AddStmt(const Stmt *S);
1863 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001864 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867};
1868} // end anonyous namespace
1869
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001871 // 'S' should always be non-null, since it comes from the
1872 // statement we are visiting.
1873 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1874}
1875
1876void
1877EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1878 if (Qualifier)
1879 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1880}
1881
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001883 if (S)
1884 WL.push_back(StmtVisit(S, Parent));
1885}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001887 if (D)
1888 WL.push_back(DeclVisit(D, Parent, isFirst));
1889}
1890void EnqueueVisitor::
1891 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1892 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001894}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 if (D)
1897 WL.push_back(MemberRefVisit(D, L, Parent));
1898}
1899void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1900 if (TI)
1901 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1902 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 AddStmt(*Child);
1907 }
1908 if (size == WL.size())
1909 return;
1910 // Now reverse the entries we just added. This will match the DFS
1911 // ordering performed by the worklist.
1912 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1913 std::reverse(I, E);
1914}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001915namespace {
1916class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1917 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001918 /// \brief Process clauses with list of variables.
1919 template <typename T>
1920 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001921public:
1922 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1923#define OPENMP_CLAUSE(Name, Class) \
1924 void Visit##Class(const Class *C);
1925#include "clang/Basic/OpenMPKinds.def"
1926};
1927
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001928void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1929 Visitor->AddStmt(C->getCondition());
1930}
1931
Alexey Bataev568a8332014-03-06 06:15:19 +00001932void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1933 Visitor->AddStmt(C->getNumThreads());
1934}
1935
Alexey Bataev62c87d22014-03-21 04:51:18 +00001936void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1937 Visitor->AddStmt(C->getSafelen());
1938}
1939
Alexander Musman8bd31e62014-05-27 15:12:19 +00001940void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1941 Visitor->AddStmt(C->getNumForLoops());
1942}
1943
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001945
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001946void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1947
Alexey Bataev56dafe82014-06-20 07:16:17 +00001948void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1949 Visitor->AddStmt(C->getChunkSize());
1950}
1951
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001952void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1953
Alexey Bataev236070f2014-06-20 11:19:47 +00001954void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1955
Alexey Bataev756c1962013-09-24 03:17:45 +00001956template<typename T>
1957void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001958 for (const auto *I : Node->varlists())
1959 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001960}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961
1962void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001963 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001964}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001965void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1966 const OMPFirstprivateClause *C) {
1967 VisitOMPClauseList(C);
1968}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001969void OMPClauseEnqueue::VisitOMPLastprivateClause(
1970 const OMPLastprivateClause *C) {
1971 VisitOMPClauseList(C);
1972}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001973void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001974 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001975}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001976void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1977 VisitOMPClauseList(C);
1978}
Alexander Musman8dba6642014-04-22 13:09:42 +00001979void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1980 VisitOMPClauseList(C);
1981 Visitor->AddStmt(C->getStep());
1982}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001983void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1984 VisitOMPClauseList(C);
1985 Visitor->AddStmt(C->getAlignment());
1986}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001987void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1988 VisitOMPClauseList(C);
1989}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001990}
Alexey Bataev756c1962013-09-24 03:17:45 +00001991
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001992void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1993 unsigned size = WL.size();
1994 OMPClauseEnqueue Visitor(this);
1995 Visitor.Visit(S);
1996 if (size == WL.size())
1997 return;
1998 // Now reverse the entries we just added. This will match the DFS
1999 // ordering performed by the worklist.
2000 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2001 std::reverse(I, E);
2002}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002004 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2005}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002006void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002007 AddDecl(B->getBlockDecl());
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 EnqueueChildren(E);
2011 AddTypeLoc(E->getTypeSourceInfo());
2012}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002013void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2014 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002015 E = S->body_rend(); I != E; ++I) {
2016 AddStmt(*I);
2017 }
2018}
2019void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 AddStmt(S->getSubStmt());
2022 AddDeclarationNameInfo(S);
2023 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2024 AddNestedNameSpecifierLoc(QualifierLoc);
2025}
2026
2027void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002028VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2030 AddDeclarationNameInfo(E);
2031 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2032 AddNestedNameSpecifierLoc(QualifierLoc);
2033 if (!E->isImplicitAccess())
2034 AddStmt(E->getBase());
2035}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 // Enqueue the initializer , if any.
2038 AddStmt(E->getInitializer());
2039 // Enqueue the array size, if any.
2040 AddStmt(E->getArraySize());
2041 // Enqueue the allocated type.
2042 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2043 // Enqueue the placement arguments.
2044 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2045 AddStmt(E->getPlacementArg(I-1));
2046}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2049 AddStmt(CE->getArg(I-1));
2050 AddStmt(CE->getCallee());
2051 AddStmt(CE->getArg(0));
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2054 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 // Visit the name of the type being destroyed.
2056 AddTypeLoc(E->getDestroyedTypeInfo());
2057 // Visit the scope type that looks disturbingly like the nested-name-specifier
2058 // but isn't.
2059 AddTypeLoc(E->getScopeTypeInfo());
2060 // Visit the nested-name-specifier.
2061 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2062 AddNestedNameSpecifierLoc(QualifierLoc);
2063 // Visit base expression.
2064 AddStmt(E->getBase());
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2067 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 AddTypeLoc(E->getTypeSourceInfo());
2069}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2071 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 EnqueueChildren(E);
2073 AddTypeLoc(E->getTypeSourceInfo());
2074}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 EnqueueChildren(E);
2077 if (E->isTypeOperand())
2078 AddTypeLoc(E->getTypeOperandSourceInfo());
2079}
2080
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2082 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 EnqueueChildren(E);
2084 AddTypeLoc(E->getTypeSourceInfo());
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 EnqueueChildren(E);
2088 if (E->isTypeOperand())
2089 AddTypeLoc(E->getTypeOperandSourceInfo());
2090}
2091
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 EnqueueChildren(S);
2094 AddDecl(S->getExceptionDecl());
2095}
2096
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 if (DR->hasExplicitTemplateArgs()) {
2099 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2100 }
2101 WL.push_back(DeclRefExprParts(DR, Parent));
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2104 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2106 AddDeclarationNameInfo(E);
2107 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 unsigned size = WL.size();
2111 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002112 for (const auto *D : S->decls()) {
2113 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 isFirst = false;
2115 }
2116 if (size == WL.size())
2117 return;
2118 // Now reverse the entries we just added. This will match the DFS
2119 // ordering performed by the worklist.
2120 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2121 std::reverse(I, E);
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 D = E->designators_rbegin(), DEnd = E->designators_rend();
2127 D != DEnd; ++D) {
2128 if (D->isFieldDesignator()) {
2129 if (FieldDecl *Field = D->getField())
2130 AddMemberRef(Field, D->getFieldLoc());
2131 continue;
2132 }
2133 if (D->isArrayDesignator()) {
2134 AddStmt(E->getArrayIndex(*D));
2135 continue;
2136 }
2137 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2138 AddStmt(E->getArrayRangeEnd(*D));
2139 AddStmt(E->getArrayRangeStart(*D));
2140 }
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(E);
2144 AddTypeLoc(E->getTypeInfoAsWritten());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 AddStmt(FS->getBody());
2148 AddStmt(FS->getInc());
2149 AddStmt(FS->getCond());
2150 AddDecl(FS->getConditionVariable());
2151 AddStmt(FS->getInit());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 AddStmt(If->getElse());
2158 AddStmt(If->getThen());
2159 AddStmt(If->getCond());
2160 AddDecl(If->getConditionVariable());
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 // We care about the syntactic form of the initializer list, only.
2164 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2165 IE = Syntactic;
2166 EnqueueChildren(IE);
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 WL.push_back(MemberExprParts(M, Parent));
2170
2171 // If the base of the member access expression is an implicit 'this', don't
2172 // visit it.
2173 // FIXME: If we ever want to show these implicit accesses, this will be
2174 // unfortunate. However, clang_getCursor() relies on this behavior.
2175 if (!M->isImplicitAccess())
2176 AddStmt(M->getBase());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddTypeLoc(E->getEncodedTypeSourceInfo());
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 EnqueueChildren(M);
2183 AddTypeLoc(M->getClassReceiverTypeInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 // Visit the components of the offsetof expression.
2187 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2188 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2189 const OffsetOfNode &Node = E->getComponent(I-1);
2190 switch (Node.getKind()) {
2191 case OffsetOfNode::Array:
2192 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2193 break;
2194 case OffsetOfNode::Field:
2195 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2196 break;
2197 case OffsetOfNode::Identifier:
2198 case OffsetOfNode::Base:
2199 continue;
2200 }
2201 }
2202 // Visit the type into which we're computing the offset.
2203 AddTypeLoc(E->getTypeSourceInfo());
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2207 WL.push_back(OverloadExprParts(E, Parent));
2208}
2209void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 EnqueueChildren(E);
2212 if (E->isArgumentType())
2213 AddTypeLoc(E->getArgumentTypeInfo());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 EnqueueChildren(S);
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(S->getBody());
2220 AddStmt(S->getCond());
2221 AddDecl(S->getConditionVariable());
2222}
2223
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddStmt(W->getBody());
2226 AddStmt(W->getCond());
2227 AddDecl(W->getConditionVariable());
2228}
2229
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 for (unsigned I = E->getNumArgs(); I > 0; --I)
2232 AddTypeLoc(E->getArg(I-1));
2233}
2234
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddTypeLoc(E->getQueriedTypeSourceInfo());
2237}
2238
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 EnqueueChildren(E);
2241}
2242
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 VisitOverloadExpr(U);
2245 if (!U->isImplicitAccess())
2246 AddStmt(U->getBase());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddStmt(E->getSubExpr());
2250 AddTypeLoc(E->getWrittenTypeInfo());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 WL.push_back(SizeOfPackExprParts(E, Parent));
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 // If the opaque value has a source expression, just transparently
2257 // visit that. This is useful for (e.g.) pseudo-object expressions.
2258 if (Expr *SourceExpr = E->getSourceExpr())
2259 return Visit(SourceExpr);
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddStmt(E->getBody());
2263 WL.push_back(LambdaExprParts(E, Parent));
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 // Treat the expression like its syntactic form.
2267 Visit(E->getSyntacticForm());
2268}
2269
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002270void EnqueueVisitor::VisitOMPExecutableDirective(
2271 const OMPExecutableDirective *D) {
2272 EnqueueChildren(D);
2273 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2274 E = D->clauses().end();
2275 I != E; ++I)
2276 EnqueueChildren(*I);
2277}
2278
2279void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2280 VisitOMPExecutableDirective(D);
2281}
2282
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002283void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2284 VisitOMPExecutableDirective(D);
2285}
2286
Alexey Bataevf29276e2014-06-18 04:14:57 +00002287void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2288 VisitOMPExecutableDirective(D);
2289}
2290
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002291void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2292 VisitOMPExecutableDirective(D);
2293}
2294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2297}
2298
2299bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2300 if (RegionOfInterest.isValid()) {
2301 SourceRange Range = getRawCursorExtent(C);
2302 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2303 return false;
2304 }
2305 return true;
2306}
2307
2308bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2309 while (!WL.empty()) {
2310 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002311 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002312
2313 // Set the Parent field, then back to its old value once we're done.
2314 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2315
2316 switch (LI.getKind()) {
2317 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 if (!D)
2320 continue;
2321
2322 // For now, perform default visitation for Decls.
2323 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2324 cast<DeclVisit>(&LI)->isFirst())))
2325 return true;
2326
2327 continue;
2328 }
2329 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2330 const ASTTemplateArgumentListInfo *ArgList =
2331 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2332 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2333 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2334 Arg != ArgEnd; ++Arg) {
2335 if (VisitTemplateArgumentLoc(*Arg))
2336 return true;
2337 }
2338 continue;
2339 }
2340 case VisitorJob::TypeLocVisitKind: {
2341 // Perform default visitation for TypeLocs.
2342 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2343 return true;
2344 continue;
2345 }
2346 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 if (LabelStmt *stmt = LS->getStmt()) {
2349 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2350 TU))) {
2351 return true;
2352 }
2353 }
2354 continue;
2355 }
2356
2357 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2358 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2359 if (VisitNestedNameSpecifierLoc(V->get()))
2360 return true;
2361 continue;
2362 }
2363
2364 case VisitorJob::DeclarationNameInfoVisitKind: {
2365 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2366 ->get()))
2367 return true;
2368 continue;
2369 }
2370 case VisitorJob::MemberRefVisitKind: {
2371 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2372 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2373 return true;
2374 continue;
2375 }
2376 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 if (!S)
2379 continue;
2380
2381 // Update the current cursor.
2382 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2383 if (!IsInRegionOfInterest(Cursor))
2384 continue;
2385 switch (Visitor(Cursor, Parent, ClientData)) {
2386 case CXChildVisit_Break: return true;
2387 case CXChildVisit_Continue: break;
2388 case CXChildVisit_Recurse:
2389 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002390 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 EnqueueWorkList(WL, S);
2392 break;
2393 }
2394 continue;
2395 }
2396 case VisitorJob::MemberExprPartsKind: {
2397 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002399
2400 // Visit the nested-name-specifier
2401 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2402 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2403 return true;
2404
2405 // Visit the declaration name.
2406 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2407 return true;
2408
2409 // Visit the explicitly-specified template arguments, if any.
2410 if (M->hasExplicitTemplateArgs()) {
2411 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2412 *ArgEnd = Arg + M->getNumTemplateArgs();
2413 Arg != ArgEnd; ++Arg) {
2414 if (VisitTemplateArgumentLoc(*Arg))
2415 return true;
2416 }
2417 }
2418 continue;
2419 }
2420 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 // Visit nested-name-specifier, if present.
2423 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2424 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2425 return true;
2426 // Visit declaration name.
2427 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2428 return true;
2429 continue;
2430 }
2431 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 // Visit the nested-name-specifier.
2434 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2435 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2436 return true;
2437 // Visit the declaration name.
2438 if (VisitDeclarationNameInfo(O->getNameInfo()))
2439 return true;
2440 // Visit the overloaded declaration reference.
2441 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2442 return true;
2443 continue;
2444 }
2445 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 NamedDecl *Pack = E->getPack();
2448 if (isa<TemplateTypeParmDecl>(Pack)) {
2449 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2450 E->getPackLoc(), TU)))
2451 return true;
2452
2453 continue;
2454 }
2455
2456 if (isa<TemplateTemplateParmDecl>(Pack)) {
2457 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2458 E->getPackLoc(), TU)))
2459 return true;
2460
2461 continue;
2462 }
2463
2464 // Non-type template parameter packs and function parameter packs are
2465 // treated like DeclRefExpr cursors.
2466 continue;
2467 }
2468
2469 case VisitorJob::LambdaExprPartsKind: {
2470 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2473 CEnd = E->explicit_capture_end();
2474 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002475 // FIXME: Lambda init-captures.
2476 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002478
Guy Benyei11169dd2012-12-18 14:30:41 +00002479 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2480 C->getLocation(),
2481 TU)))
2482 return true;
2483 }
2484
2485 // Visit parameters and return type, if present.
2486 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2487 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2488 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2489 // Visit the whole type.
2490 if (Visit(TL))
2491 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002492 } else if (FunctionProtoTypeLoc Proto =
2493 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 if (E->hasExplicitParameters()) {
2495 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002496 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2497 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 return true;
2499 } else {
2500 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002501 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 return true;
2503 }
2504 }
2505 }
2506 break;
2507 }
2508
2509 case VisitorJob::PostChildrenVisitKind:
2510 if (PostChildrenVisitor(Parent, ClientData))
2511 return true;
2512 break;
2513 }
2514 }
2515 return false;
2516}
2517
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002518bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002519 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 if (!WorkListFreeList.empty()) {
2521 WL = WorkListFreeList.back();
2522 WL->clear();
2523 WorkListFreeList.pop_back();
2524 }
2525 else {
2526 WL = new VisitorWorkList();
2527 WorkListCache.push_back(WL);
2528 }
2529 EnqueueWorkList(*WL, S);
2530 bool result = RunVisitorWorkList(*WL);
2531 WorkListFreeList.push_back(WL);
2532 return result;
2533}
2534
2535namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002536typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002537RefNamePieces
2538buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2539 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2540 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002541 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2542 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2543 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2544
2545 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2546
2547 RefNamePieces Pieces;
2548
2549 if (WantQualifier && QLoc.isValid())
2550 Pieces.push_back(QLoc);
2551
2552 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2553 Pieces.push_back(NI.getLoc());
2554
2555 if (WantTemplateArgs && TemplateArgs)
2556 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2557 TemplateArgs->RAngleLoc));
2558
2559 if (Kind == DeclarationName::CXXOperatorName) {
2560 Pieces.push_back(SourceLocation::getFromRawEncoding(
2561 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2562 Pieces.push_back(SourceLocation::getFromRawEncoding(
2563 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2564 }
2565
2566 if (WantSinglePiece) {
2567 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2568 Pieces.clear();
2569 Pieces.push_back(R);
2570 }
2571
2572 return Pieces;
2573}
2574}
2575
2576//===----------------------------------------------------------------------===//
2577// Misc. API hooks.
2578//===----------------------------------------------------------------------===//
2579
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002580static llvm::sys::Mutex EnableMultithreadingMutex;
2581static bool EnabledMultithreading;
Guy Benyei11169dd2012-12-18 14:30:41 +00002582
Chad Rosier05c71aa2013-03-27 18:28:23 +00002583static void fatal_error_handler(void *user_data, const std::string& reason,
2584 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002585 // Write the result out to stderr avoiding errs() because raw_ostreams can
2586 // call report_fatal_error.
2587 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2588 ::abort();
2589}
2590
2591extern "C" {
2592CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2593 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 // We use crash recovery to make some of our APIs more reliable, implicitly
2595 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002596 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2597 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002598
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002599 // Enable support for multithreading in LLVM.
2600 {
2601 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2602 if (!EnabledMultithreading) {
2603 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2604 llvm::llvm_start_multithreaded();
2605 EnabledMultithreading = true;
2606 }
2607 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002608
2609 CIndexer *CIdxr = new CIndexer();
2610 if (excludeDeclarationsFromPCH)
2611 CIdxr->setOnlyLocalDecls();
2612 if (displayDiagnostics)
2613 CIdxr->setDisplayDiagnostics();
2614
2615 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2616 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2617 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2618 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2619 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2620 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2621
2622 return CIdxr;
2623}
2624
2625void clang_disposeIndex(CXIndex CIdx) {
2626 if (CIdx)
2627 delete static_cast<CIndexer *>(CIdx);
2628}
2629
2630void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2631 if (CIdx)
2632 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2633}
2634
2635unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2636 if (CIdx)
2637 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2638 return 0;
2639}
2640
2641void clang_toggleCrashRecovery(unsigned isEnabled) {
2642 if (isEnabled)
2643 llvm::CrashRecoveryContext::Enable();
2644 else
2645 llvm::CrashRecoveryContext::Disable();
2646}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002647
Guy Benyei11169dd2012-12-18 14:30:41 +00002648CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2649 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002650 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651 enum CXErrorCode Result =
2652 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002653 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002654 assert((TU && Result == CXError_Success) ||
2655 (!TU && Result != CXError_Success));
2656 return TU;
2657}
2658
2659enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2660 const char *ast_filename,
2661 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002662 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002663 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002664
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002665 if (!CIdx || !ast_filename || !out_TU)
2666 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002667
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002668 LOG_FUNC_SECTION {
2669 *Log << ast_filename;
2670 }
2671
Guy Benyei11169dd2012-12-18 14:30:41 +00002672 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2673 FileSystemOptions FileSystemOpts;
2674
2675 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002676 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002677 CXXIdx->getOnlyLocalDecls(), None,
2678 /*CaptureDiagnostics=*/true,
2679 /*AllowPCHWithCompilerErrors=*/true,
2680 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002681 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2682 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002683}
2684
2685unsigned clang_defaultEditingTranslationUnitOptions() {
2686 return CXTranslationUnit_PrecompiledPreamble |
2687 CXTranslationUnit_CacheCompletionResults;
2688}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002689
Guy Benyei11169dd2012-12-18 14:30:41 +00002690CXTranslationUnit
2691clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2692 const char *source_filename,
2693 int num_command_line_args,
2694 const char * const *command_line_args,
2695 unsigned num_unsaved_files,
2696 struct CXUnsavedFile *unsaved_files) {
2697 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2698 return clang_parseTranslationUnit(CIdx, source_filename,
2699 command_line_args, num_command_line_args,
2700 unsaved_files, num_unsaved_files,
2701 Options);
2702}
2703
2704struct ParseTranslationUnitInfo {
2705 CXIndex CIdx;
2706 const char *source_filename;
2707 const char *const *command_line_args;
2708 int num_command_line_args;
2709 struct CXUnsavedFile *unsaved_files;
2710 unsigned num_unsaved_files;
2711 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002712 CXTranslationUnit *out_TU;
2713 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002714};
2715static void clang_parseTranslationUnit_Impl(void *UserData) {
2716 ParseTranslationUnitInfo *PTUI =
2717 static_cast<ParseTranslationUnitInfo*>(UserData);
2718 CXIndex CIdx = PTUI->CIdx;
2719 const char *source_filename = PTUI->source_filename;
2720 const char * const *command_line_args = PTUI->command_line_args;
2721 int num_command_line_args = PTUI->num_command_line_args;
2722 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2723 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2724 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002725 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002726
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002727 // Set up the initial return values.
2728 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002729 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002730 PTUI->result = CXError_Failure;
2731
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002732 // Check arguments.
2733 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002734 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002735 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002736 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002737 }
2738
Guy Benyei11169dd2012-12-18 14:30:41 +00002739 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2740
2741 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2742 setThreadBackgroundPriority();
2743
2744 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2745 // FIXME: Add a flag for modules.
2746 TranslationUnitKind TUKind
2747 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002748 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 = options & CXTranslationUnit_CacheCompletionResults;
2750 bool IncludeBriefCommentsInCodeCompletion
2751 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2752 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2753 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2754
2755 // Configure the diagnostics.
2756 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002757 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002758
2759 // Recover resources if we crash before exiting this function.
2760 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2761 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2762 DiagCleanup(Diags.getPtr());
2763
Ahmed Charlesb8984322014-03-07 20:03:18 +00002764 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2765 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002766
2767 // Recover resources if we crash before exiting this function.
2768 llvm::CrashRecoveryContextCleanupRegistrar<
2769 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2770
2771 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2772 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2773 const llvm::MemoryBuffer *Buffer
2774 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2775 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2776 Buffer));
2777 }
2778
Ahmed Charlesb8984322014-03-07 20:03:18 +00002779 std::unique_ptr<std::vector<const char *>> Args(
2780 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002781
2782 // Recover resources if we crash before exiting this method.
2783 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2784 ArgsCleanup(Args.get());
2785
2786 // Since the Clang C library is primarily used by batch tools dealing with
2787 // (often very broken) source code, where spell-checking can have a
2788 // significant negative impact on performance (particularly when
2789 // precompiled headers are involved), we disable it by default.
2790 // Only do this if we haven't found a spell-checking-related argument.
2791 bool FoundSpellCheckingArgument = false;
2792 for (int I = 0; I != num_command_line_args; ++I) {
2793 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2794 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2795 FoundSpellCheckingArgument = true;
2796 break;
2797 }
2798 }
2799 if (!FoundSpellCheckingArgument)
2800 Args->push_back("-fno-spell-checking");
2801
2802 Args->insert(Args->end(), command_line_args,
2803 command_line_args + num_command_line_args);
2804
2805 // The 'source_filename' argument is optional. If the caller does not
2806 // specify it then it is assumed that the source file is specified
2807 // in the actual argument list.
2808 // Put the source file after command_line_args otherwise if '-x' flag is
2809 // present it will be unused.
2810 if (source_filename)
2811 Args->push_back(source_filename);
2812
2813 // Do we need the detailed preprocessing record?
2814 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2815 Args->push_back("-Xclang");
2816 Args->push_back("-detailed-preprocessing-record");
2817 }
2818
2819 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002820 std::unique_ptr<ASTUnit> ErrUnit;
2821 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002822 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002823 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2824 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2825 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2826 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2827 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2828 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002829
2830 if (NumErrors != Diags->getClient()->getNumErrors()) {
2831 // Make sure to check that 'Unit' is non-NULL.
2832 if (CXXIdx->getDisplayDiagnostics())
2833 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2834 }
2835
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002836 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2837 PTUI->result = CXError_ASTReadError;
2838 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002839 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002840 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2841 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002842}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002843
2844CXTranslationUnit
2845clang_parseTranslationUnit(CXIndex CIdx,
2846 const char *source_filename,
2847 const char *const *command_line_args,
2848 int num_command_line_args,
2849 struct CXUnsavedFile *unsaved_files,
2850 unsigned num_unsaved_files,
2851 unsigned options) {
2852 CXTranslationUnit TU;
2853 enum CXErrorCode Result = clang_parseTranslationUnit2(
2854 CIdx, source_filename, command_line_args, num_command_line_args,
2855 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002856 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002857 assert((TU && Result == CXError_Success) ||
2858 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002859 return TU;
2860}
2861
2862enum CXErrorCode clang_parseTranslationUnit2(
2863 CXIndex CIdx,
2864 const char *source_filename,
2865 const char *const *command_line_args,
2866 int num_command_line_args,
2867 struct CXUnsavedFile *unsaved_files,
2868 unsigned num_unsaved_files,
2869 unsigned options,
2870 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002871 LOG_FUNC_SECTION {
2872 *Log << source_filename << ": ";
2873 for (int i = 0; i != num_command_line_args; ++i)
2874 *Log << command_line_args[i] << " ";
2875 }
2876
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2878 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879 num_unsaved_files, options, out_TU,
2880 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 llvm::CrashRecoveryContext CRC;
2882
2883 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2884 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2885 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2886 fprintf(stderr, " 'command_line_args' : [");
2887 for (int i = 0; i != num_command_line_args; ++i) {
2888 if (i)
2889 fprintf(stderr, ", ");
2890 fprintf(stderr, "'%s'", command_line_args[i]);
2891 }
2892 fprintf(stderr, "],\n");
2893 fprintf(stderr, " 'unsaved_files' : [");
2894 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2895 if (i)
2896 fprintf(stderr, ", ");
2897 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2898 unsaved_files[i].Length);
2899 }
2900 fprintf(stderr, "],\n");
2901 fprintf(stderr, " 'options' : %d,\n", options);
2902 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002903
2904 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002906 if (CXTranslationUnit *TU = PTUI.out_TU)
2907 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 }
2909
2910 return PTUI.result;
2911}
2912
2913unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2914 return CXSaveTranslationUnit_None;
2915}
2916
2917namespace {
2918
2919struct SaveTranslationUnitInfo {
2920 CXTranslationUnit TU;
2921 const char *FileName;
2922 unsigned options;
2923 CXSaveError result;
2924};
2925
2926}
2927
2928static void clang_saveTranslationUnit_Impl(void *UserData) {
2929 SaveTranslationUnitInfo *STUI =
2930 static_cast<SaveTranslationUnitInfo*>(UserData);
2931
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002932 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2934 setThreadBackgroundPriority();
2935
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002936 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2938}
2939
2940int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2941 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002942 LOG_FUNC_SECTION {
2943 *Log << TU << ' ' << FileName;
2944 }
2945
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002946 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002947 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002948 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002949 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002950
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002951 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002952 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2953 if (!CXXUnit->hasSema())
2954 return CXSaveError_InvalidTU;
2955
2956 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2957
2958 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2959 getenv("LIBCLANG_NOTHREADS")) {
2960 clang_saveTranslationUnit_Impl(&STUI);
2961
2962 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2963 PrintLibclangResourceUsage(TU);
2964
2965 return STUI.result;
2966 }
2967
2968 // We have an AST that has invalid nodes due to compiler errors.
2969 // Use a crash recovery thread for protection.
2970
2971 llvm::CrashRecoveryContext CRC;
2972
2973 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2974 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2975 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2976 fprintf(stderr, " 'options' : %d,\n", options);
2977 fprintf(stderr, "}\n");
2978
2979 return CXSaveError_Unknown;
2980
2981 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2982 PrintLibclangResourceUsage(TU);
2983 }
2984
2985 return STUI.result;
2986}
2987
2988void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2989 if (CTUnit) {
2990 // If the translation unit has been marked as unsafe to free, just discard
2991 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2993 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002994 return;
2995
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002996 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002997 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002998 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2999 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003000 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 delete CTUnit;
3002 }
3003}
3004
3005unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3006 return CXReparse_None;
3007}
3008
3009struct ReparseTranslationUnitInfo {
3010 CXTranslationUnit TU;
3011 unsigned num_unsaved_files;
3012 struct CXUnsavedFile *unsaved_files;
3013 unsigned options;
3014 int result;
3015};
3016
3017static void clang_reparseTranslationUnit_Impl(void *UserData) {
3018 ReparseTranslationUnitInfo *RTUI =
3019 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003020 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003021
Guy Benyei11169dd2012-12-18 14:30:41 +00003022 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3024 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3025 unsigned options = RTUI->options;
3026 (void) options;
3027
3028 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003029 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003030 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003031 RTUI->result = CXError_InvalidArguments;
3032 return;
3033 }
Craig Topper69186e72014-06-08 08:38:04 +00003034 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003035 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003036 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003037 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003038
3039 // Reset the associated diagnostics.
3040 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003041 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003043 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3045 setThreadBackgroundPriority();
3046
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003047 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003048 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003049
3050 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3051 new std::vector<ASTUnit::RemappedFile>());
3052
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 // Recover resources if we crash before exiting this function.
3054 llvm::CrashRecoveryContextCleanupRegistrar<
3055 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3056
3057 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3058 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3059 const llvm::MemoryBuffer *Buffer
3060 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3061 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3062 Buffer));
3063 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003064
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003065 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003066 RTUI->result = CXError_Success;
3067 else if (isASTReadError(CXXUnit))
3068 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003069}
3070
3071int clang_reparseTranslationUnit(CXTranslationUnit TU,
3072 unsigned num_unsaved_files,
3073 struct CXUnsavedFile *unsaved_files,
3074 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003075 LOG_FUNC_SECTION {
3076 *Log << TU;
3077 }
3078
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003080 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003081
3082 if (getenv("LIBCLANG_NOTHREADS")) {
3083 clang_reparseTranslationUnit_Impl(&RTUI);
3084 return RTUI.result;
3085 }
3086
3087 llvm::CrashRecoveryContext CRC;
3088
3089 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3090 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003091 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003092 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3094 PrintLibclangResourceUsage(TU);
3095
3096 return RTUI.result;
3097}
3098
3099
3100CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003101 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003102 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003103 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003104 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003106 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003107 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003108}
3109
3110CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003111 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003112 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003113 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003114 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3118}
3119
3120} // end: extern "C"
3121
3122//===----------------------------------------------------------------------===//
3123// CXFile Operations.
3124//===----------------------------------------------------------------------===//
3125
3126extern "C" {
3127CXString clang_getFileName(CXFile SFile) {
3128 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003129 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003130
3131 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003132 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003133}
3134
3135time_t clang_getFileTime(CXFile SFile) {
3136 if (!SFile)
3137 return 0;
3138
3139 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3140 return FEnt->getModificationTime();
3141}
3142
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003143CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003144 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003145 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003146 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003147 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003148
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003149 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003150
3151 FileManager &FMgr = CXXUnit->getFileManager();
3152 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3153}
3154
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003155unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3156 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003157 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003158 LOG_BAD_TU(TU);
3159 return 0;
3160 }
3161
3162 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 return 0;
3164
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003165 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 FileEntry *FEnt = static_cast<FileEntry *>(file);
3167 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3168 .isFileMultipleIncludeGuarded(FEnt);
3169}
3170
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003171int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3172 if (!file || !outID)
3173 return 1;
3174
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003175 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003176 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3177 outID->data[0] = ID.getDevice();
3178 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003179 outID->data[2] = FEnt->getModificationTime();
3180 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003181}
3182
Guy Benyei11169dd2012-12-18 14:30:41 +00003183} // end: extern "C"
3184
3185//===----------------------------------------------------------------------===//
3186// CXCursor Operations.
3187//===----------------------------------------------------------------------===//
3188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189static const Decl *getDeclFromExpr(const Stmt *E) {
3190 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 return getDeclFromExpr(CE->getSubExpr());
3192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003195 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 if (PRE->isExplicitProperty())
3201 return PRE->getExplicitProperty();
3202 // It could be messaging both getter and setter as in:
3203 // ++myobj.myprop;
3204 // in which case prefer to associate the setter since it is less obvious
3205 // from inspecting the source that the setter is going to get called.
3206 if (PRE->isMessagingSetter())
3207 return PRE->getImplicitPropertySetter();
3208 return PRE->getImplicitPropertyGetter();
3209 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003210 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003212 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 if (Expr *Src = OVE->getSourceExpr())
3214 return getDeclFromExpr(Src);
3215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003218 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 if (!CE->isElidable())
3220 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003221 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 return OME->getMethodDecl();
3223
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003224 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003226 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3228 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003229 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3231 isa<ParmVarDecl>(SizeOfPack->getPack()))
3232 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003233
3234 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235}
3236
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003237static SourceLocation getLocationFromExpr(const Expr *E) {
3238 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 return getLocationFromExpr(CE->getSubExpr());
3240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003241 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003243 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003245 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003247 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003249 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003251 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 return PropRef->getLocation();
3253
3254 return E->getLocStart();
3255}
3256
3257extern "C" {
3258
3259unsigned clang_visitChildren(CXCursor parent,
3260 CXCursorVisitor visitor,
3261 CXClientData client_data) {
3262 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3263 /*VisitPreprocessorLast=*/false);
3264 return CursorVis.VisitChildren(parent);
3265}
3266
3267#ifndef __has_feature
3268#define __has_feature(x) 0
3269#endif
3270#if __has_feature(blocks)
3271typedef enum CXChildVisitResult
3272 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3273
3274static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3275 CXClientData client_data) {
3276 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3277 return block(cursor, parent);
3278}
3279#else
3280// If we are compiled with a compiler that doesn't have native blocks support,
3281// define and call the block manually, so the
3282typedef struct _CXChildVisitResult
3283{
3284 void *isa;
3285 int flags;
3286 int reserved;
3287 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3288 CXCursor);
3289} *CXCursorVisitorBlock;
3290
3291static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3292 CXClientData client_data) {
3293 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3294 return block->invoke(block, cursor, parent);
3295}
3296#endif
3297
3298
3299unsigned clang_visitChildrenWithBlock(CXCursor parent,
3300 CXCursorVisitorBlock block) {
3301 return clang_visitChildren(parent, visitWithBlock, block);
3302}
3303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003304static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003306 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003307
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003308 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003310 if (const ObjCPropertyImplDecl *PropImpl =
3311 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003313 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003317 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003319 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 }
3321
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003322 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003323 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003324
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3327 // and returns different names. NamedDecl returns the class name and
3328 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003329 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003330
3331 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003332 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003333
3334 SmallString<1024> S;
3335 llvm::raw_svector_ostream os(S);
3336 ND->printName(os);
3337
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003338 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003339}
3340
3341CXString clang_getCursorSpelling(CXCursor C) {
3342 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003343 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003344
3345 if (clang_isReference(C.kind)) {
3346 switch (C.kind) {
3347 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003348 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003349 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 }
3351 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003352 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003353 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003356 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003358 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 }
3360 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003361 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003362 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 }
3364 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003365 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 assert(Type && "Missing type decl");
3367
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 getAsString());
3370 }
3371 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003372 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 assert(Template && "Missing template decl");
3374
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003375 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377
3378 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003379 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 assert(NS && "Missing namespace decl");
3381
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 }
3384
3385 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003386 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 assert(Field && "Missing member decl");
3388
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003389 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 }
3391
3392 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003393 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 assert(Label && "Missing label");
3395
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003396 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398
3399 case CXCursor_OverloadedDeclRef: {
3400 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3402 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003403 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003404 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003407 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 OverloadedTemplateStorage *Ovl
3409 = Storage.get<OverloadedTemplateStorage*>();
3410 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003411 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003412 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414
3415 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003416 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 assert(Var && "Missing variable decl");
3418
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003419 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 }
3421
3422 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003423 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 }
3425 }
3426
3427 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003428 const Expr *E = getCursorExpr(C);
3429
3430 if (C.kind == CXCursor_ObjCStringLiteral ||
3431 C.kind == CXCursor_StringLiteral) {
3432 const StringLiteral *SLit;
3433 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3434 SLit = OSL->getString();
3435 } else {
3436 SLit = cast<StringLiteral>(E);
3437 }
3438 SmallString<256> Buf;
3439 llvm::raw_svector_ostream OS(Buf);
3440 SLit->outputString(OS);
3441 return cxstring::createDup(OS.str());
3442 }
3443
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003444 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 if (D)
3446 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003447 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449
3450 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003451 const Stmt *S = getCursorStmt(C);
3452 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003453 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003455 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 }
3457
3458 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003459 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 ->getNameStart());
3461
3462 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003463 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 ->getNameStart());
3465
3466 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003467 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468
3469 if (clang_isDeclaration(C.kind))
3470 return getDeclSpelling(getCursorDecl(C));
3471
3472 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003473 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003474 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 }
3476
3477 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003478 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003479 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 }
3481
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003482 if (C.kind == CXCursor_PackedAttr) {
3483 return cxstring::createRef("packed");
3484 }
3485
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003486 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003487}
3488
3489CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3490 unsigned pieceIndex,
3491 unsigned options) {
3492 if (clang_Cursor_isNull(C))
3493 return clang_getNullRange();
3494
3495 ASTContext &Ctx = getCursorContext(C);
3496
3497 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003498 const Stmt *S = getCursorStmt(C);
3499 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 if (pieceIndex > 0)
3501 return clang_getNullRange();
3502 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3503 }
3504
3505 return clang_getNullRange();
3506 }
3507
3508 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003509 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3511 if (pieceIndex >= ME->getNumSelectorLocs())
3512 return clang_getNullRange();
3513 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3514 }
3515 }
3516
3517 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3518 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003519 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3521 if (pieceIndex >= MD->getNumSelectorLocs())
3522 return clang_getNullRange();
3523 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3524 }
3525 }
3526
3527 if (C.kind == CXCursor_ObjCCategoryDecl ||
3528 C.kind == CXCursor_ObjCCategoryImplDecl) {
3529 if (pieceIndex > 0)
3530 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3533 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3536 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3537 }
3538
3539 if (C.kind == CXCursor_ModuleImportDecl) {
3540 if (pieceIndex > 0)
3541 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const ImportDecl *ImportD =
3543 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3545 if (!Locs.empty())
3546 return cxloc::translateSourceRange(Ctx,
3547 SourceRange(Locs.front(), Locs.back()));
3548 }
3549 return clang_getNullRange();
3550 }
3551
3552 // FIXME: A CXCursor_InclusionDirective should give the location of the
3553 // filename, but we don't keep track of this.
3554
3555 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3556 // but we don't keep track of this.
3557
3558 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3559 // but we don't keep track of this.
3560
3561 // Default handling, give the location of the cursor.
3562
3563 if (pieceIndex > 0)
3564 return clang_getNullRange();
3565
3566 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3567 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3568 return cxloc::translateSourceRange(Ctx, Loc);
3569}
3570
3571CXString clang_getCursorDisplayName(CXCursor C) {
3572 if (!clang_isDeclaration(C.kind))
3573 return clang_getCursorSpelling(C);
3574
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003575 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003577 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003578
3579 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 D = FunTmpl->getTemplatedDecl();
3582
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003583 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 SmallString<64> Str;
3585 llvm::raw_svector_ostream OS(Str);
3586 OS << *Function;
3587 if (Function->getPrimaryTemplate())
3588 OS << "<>";
3589 OS << "(";
3590 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3591 if (I)
3592 OS << ", ";
3593 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3594 }
3595
3596 if (Function->isVariadic()) {
3597 if (Function->getNumParams())
3598 OS << ", ";
3599 OS << "...";
3600 }
3601 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003602 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 }
3604
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003605 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 SmallString<64> Str;
3607 llvm::raw_svector_ostream OS(Str);
3608 OS << *ClassTemplate;
3609 OS << "<";
3610 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3611 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3612 if (I)
3613 OS << ", ";
3614
3615 NamedDecl *Param = Params->getParam(I);
3616 if (Param->getIdentifier()) {
3617 OS << Param->getIdentifier()->getName();
3618 continue;
3619 }
3620
3621 // There is no parameter name, which makes this tricky. Try to come up
3622 // with something useful that isn't too long.
3623 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3624 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3625 else if (NonTypeTemplateParmDecl *NTTP
3626 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3627 OS << NTTP->getType().getAsString(Policy);
3628 else
3629 OS << "template<...> class";
3630 }
3631
3632 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003633 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 }
3635
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003636 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3638 // If the type was explicitly written, use that.
3639 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003640 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003641
Benjamin Kramer9170e912013-02-22 15:46:01 +00003642 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 llvm::raw_svector_ostream OS(Str);
3644 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003645 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 ClassSpec->getTemplateArgs().data(),
3647 ClassSpec->getTemplateArgs().size(),
3648 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003649 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 }
3651
3652 return clang_getCursorSpelling(C);
3653}
3654
3655CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3656 switch (Kind) {
3657 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003785 case CXCursor_ObjCSelfExpr:
3786 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003903 case CXCursor_PackedAttr:
3904 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003905 case CXCursor_PureAttr:
3906 return cxstring::createRef("attribute(pure)");
3907 case CXCursor_ConstAttr:
3908 return cxstring::createRef("attribute(const)");
3909 case CXCursor_NoDuplicateAttr:
3910 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003911 case CXCursor_CUDAConstantAttr:
3912 return cxstring::createRef("attribute(constant)");
3913 case CXCursor_CUDADeviceAttr:
3914 return cxstring::createRef("attribute(device)");
3915 case CXCursor_CUDAGlobalAttr:
3916 return cxstring::createRef("attribute(global)");
3917 case CXCursor_CUDAHostAttr:
3918 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003967 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003968 return cxstring::createRef("OMPParallelDirective");
3969 case CXCursor_OMPSimdDirective:
3970 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003971 case CXCursor_OMPForDirective:
3972 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003973 case CXCursor_OMPSectionsDirective:
3974 return cxstring::createRef("OMPSectionsDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 }
3976
3977 llvm_unreachable("Unhandled CXCursorKind");
3978}
3979
3980struct GetCursorData {
3981 SourceLocation TokenBeginLoc;
3982 bool PointsAtMacroArgExpansion;
3983 bool VisitedObjCPropertyImplDecl;
3984 SourceLocation VisitedDeclaratorDeclStartLoc;
3985 CXCursor &BestCursor;
3986
3987 GetCursorData(SourceManager &SM,
3988 SourceLocation tokenBegin, CXCursor &outputCursor)
3989 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3990 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3991 VisitedObjCPropertyImplDecl = false;
3992 }
3993};
3994
3995static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3996 CXCursor parent,
3997 CXClientData client_data) {
3998 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3999 CXCursor *BestCursor = &Data->BestCursor;
4000
4001 // If we point inside a macro argument we should provide info of what the
4002 // token is so use the actual cursor, don't replace it with a macro expansion
4003 // cursor.
4004 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4005 return CXChildVisit_Recurse;
4006
4007 if (clang_isDeclaration(cursor.kind)) {
4008 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004009 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4011 if (MD->isImplicit())
4012 return CXChildVisit_Break;
4013
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004014 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4016 // Check that when we have multiple @class references in the same line,
4017 // that later ones do not override the previous ones.
4018 // If we have:
4019 // @class Foo, Bar;
4020 // source ranges for both start at '@', so 'Bar' will end up overriding
4021 // 'Foo' even though the cursor location was at 'Foo'.
4022 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4023 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004024 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4026 if (PrevID != ID &&
4027 !PrevID->isThisDeclarationADefinition() &&
4028 !ID->isThisDeclarationADefinition())
4029 return CXChildVisit_Break;
4030 }
4031
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004032 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4034 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4035 // Check that when we have multiple declarators in the same line,
4036 // that later ones do not override the previous ones.
4037 // If we have:
4038 // int Foo, Bar;
4039 // source ranges for both start at 'int', so 'Bar' will end up overriding
4040 // 'Foo' even though the cursor location was at 'Foo'.
4041 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4042 return CXChildVisit_Break;
4043 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4047 (void)PropImp;
4048 // Check that when we have multiple @synthesize in the same line,
4049 // that later ones do not override the previous ones.
4050 // If we have:
4051 // @synthesize Foo, Bar;
4052 // source ranges for both start at '@', so 'Bar' will end up overriding
4053 // 'Foo' even though the cursor location was at 'Foo'.
4054 if (Data->VisitedObjCPropertyImplDecl)
4055 return CXChildVisit_Break;
4056 Data->VisitedObjCPropertyImplDecl = true;
4057 }
4058 }
4059
4060 if (clang_isExpression(cursor.kind) &&
4061 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004062 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 // Avoid having the cursor of an expression replace the declaration cursor
4064 // when the expression source range overlaps the declaration range.
4065 // This can happen for C++ constructor expressions whose range generally
4066 // include the variable declaration, e.g.:
4067 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4068 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4069 D->getLocation() == Data->TokenBeginLoc)
4070 return CXChildVisit_Break;
4071 }
4072 }
4073
4074 // If our current best cursor is the construction of a temporary object,
4075 // don't replace that cursor with a type reference, because we want
4076 // clang_getCursor() to point at the constructor.
4077 if (clang_isExpression(BestCursor->kind) &&
4078 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4079 cursor.kind == CXCursor_TypeRef) {
4080 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4081 // as having the actual point on the type reference.
4082 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4083 return CXChildVisit_Recurse;
4084 }
4085
4086 *BestCursor = cursor;
4087 return CXChildVisit_Recurse;
4088}
4089
4090CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004091 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004092 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004094 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004095
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004096 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4098
4099 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4100 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4101
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004102 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 CXFile SearchFile;
4104 unsigned SearchLine, SearchColumn;
4105 CXFile ResultFile;
4106 unsigned ResultLine, ResultColumn;
4107 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4108 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4109 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004110
4111 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4112 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004113 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004114 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 SearchFileName = clang_getFileName(SearchFile);
4116 ResultFileName = clang_getFileName(ResultFile);
4117 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4118 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004119 *Log << llvm::format("(%s:%d:%d) = %s",
4120 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4121 clang_getCString(KindSpelling))
4122 << llvm::format("(%s:%d:%d):%s%s",
4123 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4124 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 clang_disposeString(SearchFileName);
4126 clang_disposeString(ResultFileName);
4127 clang_disposeString(KindSpelling);
4128 clang_disposeString(USR);
4129
4130 CXCursor Definition = clang_getCursorDefinition(Result);
4131 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4132 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4133 CXString DefinitionKindSpelling
4134 = clang_getCursorKindSpelling(Definition.kind);
4135 CXFile DefinitionFile;
4136 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004137 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004138 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004140 *Log << llvm::format(" -> %s(%s:%d:%d)",
4141 clang_getCString(DefinitionKindSpelling),
4142 clang_getCString(DefinitionFileName),
4143 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 clang_disposeString(DefinitionFileName);
4145 clang_disposeString(DefinitionKindSpelling);
4146 }
4147 }
4148
4149 return Result;
4150}
4151
4152CXCursor clang_getNullCursor(void) {
4153 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4154}
4155
4156unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004157 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4158 // can't set consistently. For example, when visiting a DeclStmt we will set
4159 // it but we don't set it on the result of clang_getCursorDefinition for
4160 // a reference of the same declaration.
4161 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4162 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4163 // to provide that kind of info.
4164 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004165 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004166 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004167 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004168
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 return X == Y;
4170}
4171
4172unsigned clang_hashCursor(CXCursor C) {
4173 unsigned Index = 0;
4174 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4175 Index = 1;
4176
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004177 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 std::make_pair(C.kind, C.data[Index]));
4179}
4180
4181unsigned clang_isInvalid(enum CXCursorKind K) {
4182 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4183}
4184
4185unsigned clang_isDeclaration(enum CXCursorKind K) {
4186 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4187 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4188}
4189
4190unsigned clang_isReference(enum CXCursorKind K) {
4191 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4192}
4193
4194unsigned clang_isExpression(enum CXCursorKind K) {
4195 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4196}
4197
4198unsigned clang_isStatement(enum CXCursorKind K) {
4199 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4200}
4201
4202unsigned clang_isAttribute(enum CXCursorKind K) {
4203 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4204}
4205
4206unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4207 return K == CXCursor_TranslationUnit;
4208}
4209
4210unsigned clang_isPreprocessing(enum CXCursorKind K) {
4211 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4212}
4213
4214unsigned clang_isUnexposed(enum CXCursorKind K) {
4215 switch (K) {
4216 case CXCursor_UnexposedDecl:
4217 case CXCursor_UnexposedExpr:
4218 case CXCursor_UnexposedStmt:
4219 case CXCursor_UnexposedAttr:
4220 return true;
4221 default:
4222 return false;
4223 }
4224}
4225
4226CXCursorKind clang_getCursorKind(CXCursor C) {
4227 return C.kind;
4228}
4229
4230CXSourceLocation clang_getCursorLocation(CXCursor C) {
4231 if (clang_isReference(C.kind)) {
4232 switch (C.kind) {
4233 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004234 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 = getCursorObjCSuperClassRef(C);
4236 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4237 }
4238
4239 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004240 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 = getCursorObjCProtocolRef(C);
4242 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4243 }
4244
4245 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004246 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 = getCursorObjCClassRef(C);
4248 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4249 }
4250
4251 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004252 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4254 }
4255
4256 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004257 std::pair<const TemplateDecl *, SourceLocation> P =
4258 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4260 }
4261
4262 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004263 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4265 }
4266
4267 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004268 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4270 }
4271
4272 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004273 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4275 }
4276
4277 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004278 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 if (!BaseSpec)
4280 return clang_getNullLocation();
4281
4282 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4283 return cxloc::translateSourceLocation(getCursorContext(C),
4284 TSInfo->getTypeLoc().getBeginLoc());
4285
4286 return cxloc::translateSourceLocation(getCursorContext(C),
4287 BaseSpec->getLocStart());
4288 }
4289
4290 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004291 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4293 }
4294
4295 case CXCursor_OverloadedDeclRef:
4296 return cxloc::translateSourceLocation(getCursorContext(C),
4297 getCursorOverloadedDeclRef(C).second);
4298
4299 default:
4300 // FIXME: Need a way to enumerate all non-reference cases.
4301 llvm_unreachable("Missed a reference kind");
4302 }
4303 }
4304
4305 if (clang_isExpression(C.kind))
4306 return cxloc::translateSourceLocation(getCursorContext(C),
4307 getLocationFromExpr(getCursorExpr(C)));
4308
4309 if (clang_isStatement(C.kind))
4310 return cxloc::translateSourceLocation(getCursorContext(C),
4311 getCursorStmt(C)->getLocStart());
4312
4313 if (C.kind == CXCursor_PreprocessingDirective) {
4314 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4315 return cxloc::translateSourceLocation(getCursorContext(C), L);
4316 }
4317
4318 if (C.kind == CXCursor_MacroExpansion) {
4319 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004320 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 return cxloc::translateSourceLocation(getCursorContext(C), L);
4322 }
4323
4324 if (C.kind == CXCursor_MacroDefinition) {
4325 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4326 return cxloc::translateSourceLocation(getCursorContext(C), L);
4327 }
4328
4329 if (C.kind == CXCursor_InclusionDirective) {
4330 SourceLocation L
4331 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4332 return cxloc::translateSourceLocation(getCursorContext(C), L);
4333 }
4334
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004335 if (clang_isAttribute(C.kind)) {
4336 SourceLocation L
4337 = cxcursor::getCursorAttr(C)->getLocation();
4338 return cxloc::translateSourceLocation(getCursorContext(C), L);
4339 }
4340
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 if (!clang_isDeclaration(C.kind))
4342 return clang_getNullLocation();
4343
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004344 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 if (!D)
4346 return clang_getNullLocation();
4347
4348 SourceLocation Loc = D->getLocation();
4349 // FIXME: Multiple variables declared in a single declaration
4350 // currently lack the information needed to correctly determine their
4351 // ranges when accounting for the type-specifier. We use context
4352 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4353 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004354 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004355 if (!cxcursor::isFirstInDeclGroup(C))
4356 Loc = VD->getLocation();
4357 }
4358
4359 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004360 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 Loc = MD->getSelectorStartLoc();
4362
4363 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4364}
4365
4366} // end extern "C"
4367
4368CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4369 assert(TU);
4370
4371 // Guard against an invalid SourceLocation, or we may assert in one
4372 // of the following calls.
4373 if (SLoc.isInvalid())
4374 return clang_getNullCursor();
4375
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004376 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004377
4378 // Translate the given source location to make it point at the beginning of
4379 // the token under the cursor.
4380 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4381 CXXUnit->getASTContext().getLangOpts());
4382
4383 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4384 if (SLoc.isValid()) {
4385 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4386 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4387 /*VisitPreprocessorLast=*/true,
4388 /*VisitIncludedEntities=*/false,
4389 SourceLocation(SLoc));
4390 CursorVis.visitFileRegion();
4391 }
4392
4393 return Result;
4394}
4395
4396static SourceRange getRawCursorExtent(CXCursor C) {
4397 if (clang_isReference(C.kind)) {
4398 switch (C.kind) {
4399 case CXCursor_ObjCSuperClassRef:
4400 return getCursorObjCSuperClassRef(C).second;
4401
4402 case CXCursor_ObjCProtocolRef:
4403 return getCursorObjCProtocolRef(C).second;
4404
4405 case CXCursor_ObjCClassRef:
4406 return getCursorObjCClassRef(C).second;
4407
4408 case CXCursor_TypeRef:
4409 return getCursorTypeRef(C).second;
4410
4411 case CXCursor_TemplateRef:
4412 return getCursorTemplateRef(C).second;
4413
4414 case CXCursor_NamespaceRef:
4415 return getCursorNamespaceRef(C).second;
4416
4417 case CXCursor_MemberRef:
4418 return getCursorMemberRef(C).second;
4419
4420 case CXCursor_CXXBaseSpecifier:
4421 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4422
4423 case CXCursor_LabelRef:
4424 return getCursorLabelRef(C).second;
4425
4426 case CXCursor_OverloadedDeclRef:
4427 return getCursorOverloadedDeclRef(C).second;
4428
4429 case CXCursor_VariableRef:
4430 return getCursorVariableRef(C).second;
4431
4432 default:
4433 // FIXME: Need a way to enumerate all non-reference cases.
4434 llvm_unreachable("Missed a reference kind");
4435 }
4436 }
4437
4438 if (clang_isExpression(C.kind))
4439 return getCursorExpr(C)->getSourceRange();
4440
4441 if (clang_isStatement(C.kind))
4442 return getCursorStmt(C)->getSourceRange();
4443
4444 if (clang_isAttribute(C.kind))
4445 return getCursorAttr(C)->getRange();
4446
4447 if (C.kind == CXCursor_PreprocessingDirective)
4448 return cxcursor::getCursorPreprocessingDirective(C);
4449
4450 if (C.kind == CXCursor_MacroExpansion) {
4451 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004452 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 return TU->mapRangeFromPreamble(Range);
4454 }
4455
4456 if (C.kind == CXCursor_MacroDefinition) {
4457 ASTUnit *TU = getCursorASTUnit(C);
4458 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4459 return TU->mapRangeFromPreamble(Range);
4460 }
4461
4462 if (C.kind == CXCursor_InclusionDirective) {
4463 ASTUnit *TU = getCursorASTUnit(C);
4464 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4465 return TU->mapRangeFromPreamble(Range);
4466 }
4467
4468 if (C.kind == CXCursor_TranslationUnit) {
4469 ASTUnit *TU = getCursorASTUnit(C);
4470 FileID MainID = TU->getSourceManager().getMainFileID();
4471 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4472 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4473 return SourceRange(Start, End);
4474 }
4475
4476 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004477 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 if (!D)
4479 return SourceRange();
4480
4481 SourceRange R = D->getSourceRange();
4482 // FIXME: Multiple variables declared in a single declaration
4483 // currently lack the information needed to correctly determine their
4484 // ranges when accounting for the type-specifier. We use context
4485 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4486 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004487 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 if (!cxcursor::isFirstInDeclGroup(C))
4489 R.setBegin(VD->getLocation());
4490 }
4491 return R;
4492 }
4493 return SourceRange();
4494}
4495
4496/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4497/// the decl-specifier-seq for declarations.
4498static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4499 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 if (!D)
4502 return SourceRange();
4503
4504 SourceRange R = D->getSourceRange();
4505
4506 // Adjust the start of the location for declarations preceded by
4507 // declaration specifiers.
4508 SourceLocation StartLoc;
4509 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4510 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4511 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4514 StartLoc = TI->getTypeLoc().getLocStart();
4515 }
4516
4517 if (StartLoc.isValid() && R.getBegin().isValid() &&
4518 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4519 R.setBegin(StartLoc);
4520
4521 // FIXME: Multiple variables declared in a single declaration
4522 // currently lack the information needed to correctly determine their
4523 // ranges when accounting for the type-specifier. We use context
4524 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4525 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 if (!cxcursor::isFirstInDeclGroup(C))
4528 R.setBegin(VD->getLocation());
4529 }
4530
4531 return R;
4532 }
4533
4534 return getRawCursorExtent(C);
4535}
4536
4537extern "C" {
4538
4539CXSourceRange clang_getCursorExtent(CXCursor C) {
4540 SourceRange R = getRawCursorExtent(C);
4541 if (R.isInvalid())
4542 return clang_getNullRange();
4543
4544 return cxloc::translateSourceRange(getCursorContext(C), R);
4545}
4546
4547CXCursor clang_getCursorReferenced(CXCursor C) {
4548 if (clang_isInvalid(C.kind))
4549 return clang_getNullCursor();
4550
4551 CXTranslationUnit tu = getCursorTU(C);
4552 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 if (!D)
4555 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004556 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004558 if (const ObjCPropertyImplDecl *PropImpl =
4559 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4561 return MakeCXCursor(Property, tu);
4562
4563 return C;
4564 }
4565
4566 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004567 const Expr *E = getCursorExpr(C);
4568 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 if (D) {
4570 CXCursor declCursor = MakeCXCursor(D, tu);
4571 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4572 declCursor);
4573 return declCursor;
4574 }
4575
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004576 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 return MakeCursorOverloadedDeclRef(Ovl, tu);
4578
4579 return clang_getNullCursor();
4580 }
4581
4582 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004583 const Stmt *S = getCursorStmt(C);
4584 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 if (LabelDecl *label = Goto->getLabel())
4586 if (LabelStmt *labelS = label->getStmt())
4587 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4588
4589 return clang_getNullCursor();
4590 }
4591
4592 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004593 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 return MakeMacroDefinitionCursor(Def, tu);
4595 }
4596
4597 if (!clang_isReference(C.kind))
4598 return clang_getNullCursor();
4599
4600 switch (C.kind) {
4601 case CXCursor_ObjCSuperClassRef:
4602 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4603
4604 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004605 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4606 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 return MakeCXCursor(Def, tu);
4608
4609 return MakeCXCursor(Prot, tu);
4610 }
4611
4612 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004613 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4614 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 return MakeCXCursor(Def, tu);
4616
4617 return MakeCXCursor(Class, tu);
4618 }
4619
4620 case CXCursor_TypeRef:
4621 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4622
4623 case CXCursor_TemplateRef:
4624 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4625
4626 case CXCursor_NamespaceRef:
4627 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4628
4629 case CXCursor_MemberRef:
4630 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4631
4632 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004633 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4635 tu ));
4636 }
4637
4638 case CXCursor_LabelRef:
4639 // FIXME: We end up faking the "parent" declaration here because we
4640 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004641 return MakeCXCursor(getCursorLabelRef(C).first,
4642 cxtu::getASTUnit(tu)->getASTContext()
4643 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 tu);
4645
4646 case CXCursor_OverloadedDeclRef:
4647 return C;
4648
4649 case CXCursor_VariableRef:
4650 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4651
4652 default:
4653 // We would prefer to enumerate all non-reference cursor kinds here.
4654 llvm_unreachable("Unhandled reference cursor kind");
4655 }
4656}
4657
4658CXCursor clang_getCursorDefinition(CXCursor C) {
4659 if (clang_isInvalid(C.kind))
4660 return clang_getNullCursor();
4661
4662 CXTranslationUnit TU = getCursorTU(C);
4663
4664 bool WasReference = false;
4665 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4666 C = clang_getCursorReferenced(C);
4667 WasReference = true;
4668 }
4669
4670 if (C.kind == CXCursor_MacroExpansion)
4671 return clang_getCursorReferenced(C);
4672
4673 if (!clang_isDeclaration(C.kind))
4674 return clang_getNullCursor();
4675
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004676 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 if (!D)
4678 return clang_getNullCursor();
4679
4680 switch (D->getKind()) {
4681 // Declaration kinds that don't really separate the notions of
4682 // declaration and definition.
4683 case Decl::Namespace:
4684 case Decl::Typedef:
4685 case Decl::TypeAlias:
4686 case Decl::TypeAliasTemplate:
4687 case Decl::TemplateTypeParm:
4688 case Decl::EnumConstant:
4689 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004690 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case Decl::IndirectField:
4692 case Decl::ObjCIvar:
4693 case Decl::ObjCAtDefsField:
4694 case Decl::ImplicitParam:
4695 case Decl::ParmVar:
4696 case Decl::NonTypeTemplateParm:
4697 case Decl::TemplateTemplateParm:
4698 case Decl::ObjCCategoryImpl:
4699 case Decl::ObjCImplementation:
4700 case Decl::AccessSpec:
4701 case Decl::LinkageSpec:
4702 case Decl::ObjCPropertyImpl:
4703 case Decl::FileScopeAsm:
4704 case Decl::StaticAssert:
4705 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004706 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case Decl::Label: // FIXME: Is this right??
4708 case Decl::ClassScopeFunctionSpecialization:
4709 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004710 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 return C;
4712
4713 // Declaration kinds that don't make any sense here, but are
4714 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004715 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 case Decl::TranslationUnit:
4717 break;
4718
4719 // Declaration kinds for which the definition is not resolvable.
4720 case Decl::UnresolvedUsingTypename:
4721 case Decl::UnresolvedUsingValue:
4722 break;
4723
4724 case Decl::UsingDirective:
4725 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4726 TU);
4727
4728 case Decl::NamespaceAlias:
4729 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4730
4731 case Decl::Enum:
4732 case Decl::Record:
4733 case Decl::CXXRecord:
4734 case Decl::ClassTemplateSpecialization:
4735 case Decl::ClassTemplatePartialSpecialization:
4736 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4737 return MakeCXCursor(Def, TU);
4738 return clang_getNullCursor();
4739
4740 case Decl::Function:
4741 case Decl::CXXMethod:
4742 case Decl::CXXConstructor:
4743 case Decl::CXXDestructor:
4744 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004745 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004747 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 return clang_getNullCursor();
4749 }
4750
Larisse Voufo39a1e502013-08-06 01:03:05 +00004751 case Decl::Var:
4752 case Decl::VarTemplateSpecialization:
4753 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004755 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 return MakeCXCursor(Def, TU);
4757 return clang_getNullCursor();
4758 }
4759
4760 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004761 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4763 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4764 return clang_getNullCursor();
4765 }
4766
4767 case Decl::ClassTemplate: {
4768 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4769 ->getDefinition())
4770 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4771 TU);
4772 return clang_getNullCursor();
4773 }
4774
Larisse Voufo39a1e502013-08-06 01:03:05 +00004775 case Decl::VarTemplate: {
4776 if (VarDecl *Def =
4777 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4778 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4779 return clang_getNullCursor();
4780 }
4781
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 case Decl::Using:
4783 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4784 D->getLocation(), TU);
4785
4786 case Decl::UsingShadow:
4787 return clang_getCursorDefinition(
4788 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4789 TU));
4790
4791 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004792 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 if (Method->isThisDeclarationADefinition())
4794 return C;
4795
4796 // Dig out the method definition in the associated
4797 // @implementation, if we have it.
4798 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004799 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4801 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4802 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4803 Method->isInstanceMethod()))
4804 if (Def->isThisDeclarationADefinition())
4805 return MakeCXCursor(Def, TU);
4806
4807 return clang_getNullCursor();
4808 }
4809
4810 case Decl::ObjCCategory:
4811 if (ObjCCategoryImplDecl *Impl
4812 = cast<ObjCCategoryDecl>(D)->getImplementation())
4813 return MakeCXCursor(Impl, TU);
4814 return clang_getNullCursor();
4815
4816 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 return MakeCXCursor(Def, TU);
4819 return clang_getNullCursor();
4820
4821 case Decl::ObjCInterface: {
4822 // There are two notions of a "definition" for an Objective-C
4823 // class: the interface and its implementation. When we resolved a
4824 // reference to an Objective-C class, produce the @interface as
4825 // the definition; when we were provided with the interface,
4826 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004827 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004829 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 return MakeCXCursor(Def, TU);
4831 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4832 return MakeCXCursor(Impl, TU);
4833 return clang_getNullCursor();
4834 }
4835
4836 case Decl::ObjCProperty:
4837 // FIXME: We don't really know where to find the
4838 // ObjCPropertyImplDecls that implement this property.
4839 return clang_getNullCursor();
4840
4841 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004842 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 return MakeCXCursor(Def, TU);
4846
4847 return clang_getNullCursor();
4848
4849 case Decl::Friend:
4850 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4851 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4852 return clang_getNullCursor();
4853
4854 case Decl::FriendTemplate:
4855 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4856 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4857 return clang_getNullCursor();
4858 }
4859
4860 return clang_getNullCursor();
4861}
4862
4863unsigned clang_isCursorDefinition(CXCursor C) {
4864 if (!clang_isDeclaration(C.kind))
4865 return 0;
4866
4867 return clang_getCursorDefinition(C) == C;
4868}
4869
4870CXCursor clang_getCanonicalCursor(CXCursor C) {
4871 if (!clang_isDeclaration(C.kind))
4872 return C;
4873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 if (const Decl *D = getCursorDecl(C)) {
4875 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4877 return MakeCXCursor(CatD, getCursorTU(C));
4878
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004879 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4880 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 return MakeCXCursor(IFD, getCursorTU(C));
4882
4883 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4884 }
4885
4886 return C;
4887}
4888
4889int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4890 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4891}
4892
4893unsigned clang_getNumOverloadedDecls(CXCursor C) {
4894 if (C.kind != CXCursor_OverloadedDeclRef)
4895 return 0;
4896
4897 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004898 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 return E->getNumDecls();
4900
4901 if (OverloadedTemplateStorage *S
4902 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4903 return S->size();
4904
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 const Decl *D = Storage.get<const Decl *>();
4906 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 return Using->shadow_size();
4908
4909 return 0;
4910}
4911
4912CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4913 if (cursor.kind != CXCursor_OverloadedDeclRef)
4914 return clang_getNullCursor();
4915
4916 if (index >= clang_getNumOverloadedDecls(cursor))
4917 return clang_getNullCursor();
4918
4919 CXTranslationUnit TU = getCursorTU(cursor);
4920 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004921 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 return MakeCXCursor(E->decls_begin()[index], TU);
4923
4924 if (OverloadedTemplateStorage *S
4925 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4926 return MakeCXCursor(S->begin()[index], TU);
4927
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004928 const Decl *D = Storage.get<const Decl *>();
4929 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 // FIXME: This is, unfortunately, linear time.
4931 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4932 std::advance(Pos, index);
4933 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4934 }
4935
4936 return clang_getNullCursor();
4937}
4938
4939void clang_getDefinitionSpellingAndExtent(CXCursor C,
4940 const char **startBuf,
4941 const char **endBuf,
4942 unsigned *startLine,
4943 unsigned *startColumn,
4944 unsigned *endLine,
4945 unsigned *endColumn) {
4946 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004947 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4949
4950 SourceManager &SM = FD->getASTContext().getSourceManager();
4951 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4952 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4953 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4954 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4955 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4956 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4957}
4958
4959
4960CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4961 unsigned PieceIndex) {
4962 RefNamePieces Pieces;
4963
4964 switch (C.kind) {
4965 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004966 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4968 E->getQualifierLoc().getSourceRange());
4969 break;
4970
4971 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004972 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4974 E->getQualifierLoc().getSourceRange(),
4975 E->getOptionalExplicitTemplateArgs());
4976 break;
4977
4978 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004979 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004981 const Expr *Callee = OCE->getCallee();
4982 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 Callee = ICE->getSubExpr();
4984
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004985 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4987 DRE->getQualifierLoc().getSourceRange());
4988 }
4989 break;
4990
4991 default:
4992 break;
4993 }
4994
4995 if (Pieces.empty()) {
4996 if (PieceIndex == 0)
4997 return clang_getCursorExtent(C);
4998 } else if (PieceIndex < Pieces.size()) {
4999 SourceRange R = Pieces[PieceIndex];
5000 if (R.isValid())
5001 return cxloc::translateSourceRange(getCursorContext(C), R);
5002 }
5003
5004 return clang_getNullRange();
5005}
5006
5007void clang_enableStackTraces(void) {
5008 llvm::sys::PrintStackTraceOnErrorSignal();
5009}
5010
5011void clang_executeOnThread(void (*fn)(void*), void *user_data,
5012 unsigned stack_size) {
5013 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5014}
5015
5016} // end: extern "C"
5017
5018//===----------------------------------------------------------------------===//
5019// Token-based Operations.
5020//===----------------------------------------------------------------------===//
5021
5022/* CXToken layout:
5023 * int_data[0]: a CXTokenKind
5024 * int_data[1]: starting token location
5025 * int_data[2]: token length
5026 * int_data[3]: reserved
5027 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5028 * otherwise unused.
5029 */
5030extern "C" {
5031
5032CXTokenKind clang_getTokenKind(CXToken CXTok) {
5033 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5034}
5035
5036CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5037 switch (clang_getTokenKind(CXTok)) {
5038 case CXToken_Identifier:
5039 case CXToken_Keyword:
5040 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005041 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 ->getNameStart());
5043
5044 case CXToken_Literal: {
5045 // We have stashed the starting pointer in the ptr_data field. Use it.
5046 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005047 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 }
5049
5050 case CXToken_Punctuation:
5051 case CXToken_Comment:
5052 break;
5053 }
5054
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005055 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005056 LOG_BAD_TU(TU);
5057 return cxstring::createEmpty();
5058 }
5059
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 // We have to find the starting buffer pointer the hard way, by
5061 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005062 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005064 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005065
5066 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5067 std::pair<FileID, unsigned> LocInfo
5068 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5069 bool Invalid = false;
5070 StringRef Buffer
5071 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5072 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005073 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005074
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005075 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005076}
5077
5078CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005079 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005080 LOG_BAD_TU(TU);
5081 return clang_getNullLocation();
5082 }
5083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005084 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 if (!CXXUnit)
5086 return clang_getNullLocation();
5087
5088 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5089 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5090}
5091
5092CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005093 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005094 LOG_BAD_TU(TU);
5095 return clang_getNullRange();
5096 }
5097
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005098 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 if (!CXXUnit)
5100 return clang_getNullRange();
5101
5102 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5103 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5104}
5105
5106static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5107 SmallVectorImpl<CXToken> &CXTokens) {
5108 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5109 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005110 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005112 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005113
5114 // Cannot tokenize across files.
5115 if (BeginLocInfo.first != EndLocInfo.first)
5116 return;
5117
5118 // Create a lexer
5119 bool Invalid = false;
5120 StringRef Buffer
5121 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5122 if (Invalid)
5123 return;
5124
5125 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5126 CXXUnit->getASTContext().getLangOpts(),
5127 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5128 Lex.SetCommentRetentionState(true);
5129
5130 // Lex tokens until we hit the end of the range.
5131 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5132 Token Tok;
5133 bool previousWasAt = false;
5134 do {
5135 // Lex the next token
5136 Lex.LexFromRawLexer(Tok);
5137 if (Tok.is(tok::eof))
5138 break;
5139
5140 // Initialize the CXToken.
5141 CXToken CXTok;
5142
5143 // - Common fields
5144 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5145 CXTok.int_data[2] = Tok.getLength();
5146 CXTok.int_data[3] = 0;
5147
5148 // - Kind-specific fields
5149 if (Tok.isLiteral()) {
5150 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005151 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 } else if (Tok.is(tok::raw_identifier)) {
5153 // Lookup the identifier to determine whether we have a keyword.
5154 IdentifierInfo *II
5155 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5156
5157 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5158 CXTok.int_data[0] = CXToken_Keyword;
5159 }
5160 else {
5161 CXTok.int_data[0] = Tok.is(tok::identifier)
5162 ? CXToken_Identifier
5163 : CXToken_Keyword;
5164 }
5165 CXTok.ptr_data = II;
5166 } else if (Tok.is(tok::comment)) {
5167 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005168 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 } else {
5170 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005171 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 }
5173 CXTokens.push_back(CXTok);
5174 previousWasAt = Tok.is(tok::at);
5175 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5176}
5177
5178void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5179 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005180 LOG_FUNC_SECTION {
5181 *Log << TU << ' ' << Range;
5182 }
5183
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005185 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 if (NumTokens)
5187 *NumTokens = 0;
5188
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005189 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005190 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005191 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005192 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005193
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005194 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 if (!CXXUnit || !Tokens || !NumTokens)
5196 return;
5197
5198 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5199
5200 SourceRange R = cxloc::translateCXSourceRange(Range);
5201 if (R.isInvalid())
5202 return;
5203
5204 SmallVector<CXToken, 32> CXTokens;
5205 getTokens(CXXUnit, R, CXTokens);
5206
5207 if (CXTokens.empty())
5208 return;
5209
5210 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5211 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5212 *NumTokens = CXTokens.size();
5213}
5214
5215void clang_disposeTokens(CXTranslationUnit TU,
5216 CXToken *Tokens, unsigned NumTokens) {
5217 free(Tokens);
5218}
5219
5220} // end: extern "C"
5221
5222//===----------------------------------------------------------------------===//
5223// Token annotation APIs.
5224//===----------------------------------------------------------------------===//
5225
Guy Benyei11169dd2012-12-18 14:30:41 +00005226static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5227 CXCursor parent,
5228 CXClientData client_data);
5229static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5230 CXClientData client_data);
5231
5232namespace {
5233class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 CXToken *Tokens;
5235 CXCursor *Cursors;
5236 unsigned NumTokens;
5237 unsigned TokIdx;
5238 unsigned PreprocessingTokIdx;
5239 CursorVisitor AnnotateVis;
5240 SourceManager &SrcMgr;
5241 bool HasContextSensitiveKeywords;
5242
5243 struct PostChildrenInfo {
5244 CXCursor Cursor;
5245 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005246 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 unsigned BeforeChildrenTokenIdx;
5248 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005249 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005250
5251 CXToken &getTok(unsigned Idx) {
5252 assert(Idx < NumTokens);
5253 return Tokens[Idx];
5254 }
5255 const CXToken &getTok(unsigned Idx) const {
5256 assert(Idx < NumTokens);
5257 return Tokens[Idx];
5258 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 bool MoreTokens() const { return TokIdx < NumTokens; }
5260 unsigned NextToken() const { return TokIdx; }
5261 void AdvanceToken() { ++TokIdx; }
5262 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005263 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 }
5265 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005266 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 }
5268 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005269 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 }
5271
5272 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005273 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 SourceRange);
5275
5276public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005277 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005278 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005279 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005281 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 AnnotateTokensVisitor, this,
5283 /*VisitPreprocessorLast=*/true,
5284 /*VisitIncludedEntities=*/false,
5285 RegionOfInterest,
5286 /*VisitDeclsOnly=*/false,
5287 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005288 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 HasContextSensitiveKeywords(false) { }
5290
5291 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5292 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5293 bool postVisitChildren(CXCursor cursor);
5294 void AnnotateTokens();
5295
5296 /// \brief Determine whether the annotator saw any cursors that have
5297 /// context-sensitive keywords.
5298 bool hasContextSensitiveKeywords() const {
5299 return HasContextSensitiveKeywords;
5300 }
5301
5302 ~AnnotateTokensWorker() {
5303 assert(PostChildrenInfos.empty());
5304 }
5305};
5306}
5307
5308void AnnotateTokensWorker::AnnotateTokens() {
5309 // Walk the AST within the region of interest, annotating tokens
5310 // along the way.
5311 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005312}
Guy Benyei11169dd2012-12-18 14:30:41 +00005313
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005314static inline void updateCursorAnnotation(CXCursor &Cursor,
5315 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005316 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005317 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005318 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005319}
5320
5321/// \brief It annotates and advances tokens with a cursor until the comparison
5322//// between the cursor location and the source range is the same as
5323/// \arg compResult.
5324///
5325/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5326/// Pass RangeOverlap to annotate tokens inside a range.
5327void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5328 RangeComparisonResult compResult,
5329 SourceRange range) {
5330 while (MoreTokens()) {
5331 const unsigned I = NextToken();
5332 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005333 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5334 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005335
5336 SourceLocation TokLoc = GetTokenLoc(I);
5337 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005338 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 AdvanceToken();
5340 continue;
5341 }
5342 break;
5343 }
5344}
5345
5346/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005347/// \returns true if it advanced beyond all macro tokens, false otherwise.
5348bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 CXCursor updateC,
5350 RangeComparisonResult compResult,
5351 SourceRange range) {
5352 assert(MoreTokens());
5353 assert(isFunctionMacroToken(NextToken()) &&
5354 "Should be called only for macro arg tokens");
5355
5356 // This works differently than annotateAndAdvanceTokens; because expanded
5357 // macro arguments can have arbitrary translation-unit source order, we do not
5358 // advance the token index one by one until a token fails the range test.
5359 // We only advance once past all of the macro arg tokens if all of them
5360 // pass the range test. If one of them fails we keep the token index pointing
5361 // at the start of the macro arg tokens so that the failing token will be
5362 // annotated by a subsequent annotation try.
5363
5364 bool atLeastOneCompFail = false;
5365
5366 unsigned I = NextToken();
5367 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5368 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5369 if (TokLoc.isFileID())
5370 continue; // not macro arg token, it's parens or comma.
5371 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5372 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5373 Cursors[I] = updateC;
5374 } else
5375 atLeastOneCompFail = true;
5376 }
5377
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005378 if (atLeastOneCompFail)
5379 return false;
5380
5381 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5382 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005383}
5384
5385enum CXChildVisitResult
5386AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 SourceRange cursorRange = getRawCursorExtent(cursor);
5388 if (cursorRange.isInvalid())
5389 return CXChildVisit_Recurse;
5390
5391 if (!HasContextSensitiveKeywords) {
5392 // Objective-C properties can have context-sensitive keywords.
5393 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005394 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5396 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5397 }
5398 // Objective-C methods can have context-sensitive keywords.
5399 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5400 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005401 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5403 if (Method->getObjCDeclQualifier())
5404 HasContextSensitiveKeywords = true;
5405 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005406 for (const auto *P : Method->params()) {
5407 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 HasContextSensitiveKeywords = true;
5409 break;
5410 }
5411 }
5412 }
5413 }
5414 }
5415 // C++ methods can have context-sensitive keywords.
5416 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005417 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5419 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5420 HasContextSensitiveKeywords = true;
5421 }
5422 }
5423 // C++ classes can have context-sensitive keywords.
5424 else if (cursor.kind == CXCursor_StructDecl ||
5425 cursor.kind == CXCursor_ClassDecl ||
5426 cursor.kind == CXCursor_ClassTemplate ||
5427 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005428 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 if (D->hasAttr<FinalAttr>())
5430 HasContextSensitiveKeywords = true;
5431 }
5432 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005433
5434 // Don't override a property annotation with its getter/setter method.
5435 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5436 parent.kind == CXCursor_ObjCPropertyDecl)
5437 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005438
5439 if (clang_isPreprocessing(cursor.kind)) {
5440 // Items in the preprocessing record are kept separate from items in
5441 // declarations, so we keep a separate token index.
5442 unsigned SavedTokIdx = TokIdx;
5443 TokIdx = PreprocessingTokIdx;
5444
5445 // Skip tokens up until we catch up to the beginning of the preprocessing
5446 // entry.
5447 while (MoreTokens()) {
5448 const unsigned I = NextToken();
5449 SourceLocation TokLoc = GetTokenLoc(I);
5450 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5451 case RangeBefore:
5452 AdvanceToken();
5453 continue;
5454 case RangeAfter:
5455 case RangeOverlap:
5456 break;
5457 }
5458 break;
5459 }
5460
5461 // Look at all of the tokens within this range.
5462 while (MoreTokens()) {
5463 const unsigned I = NextToken();
5464 SourceLocation TokLoc = GetTokenLoc(I);
5465 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5466 case RangeBefore:
5467 llvm_unreachable("Infeasible");
5468 case RangeAfter:
5469 break;
5470 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005471 // For macro expansions, just note where the beginning of the macro
5472 // expansion occurs.
5473 if (cursor.kind == CXCursor_MacroExpansion) {
5474 if (TokLoc == cursorRange.getBegin())
5475 Cursors[I] = cursor;
5476 AdvanceToken();
5477 break;
5478 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005479 // We may have already annotated macro names inside macro definitions.
5480 if (Cursors[I].kind != CXCursor_MacroExpansion)
5481 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 continue;
5484 }
5485 break;
5486 }
5487
5488 // Save the preprocessing token index; restore the non-preprocessing
5489 // token index.
5490 PreprocessingTokIdx = TokIdx;
5491 TokIdx = SavedTokIdx;
5492 return CXChildVisit_Recurse;
5493 }
5494
5495 if (cursorRange.isInvalid())
5496 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005497
5498 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 const enum CXCursorKind K = clang_getCursorKind(parent);
5501 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005502 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5503 // Attributes are annotated out-of-order, skip tokens until we reach it.
5504 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 ? clang_getNullCursor() : parent;
5506
5507 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5508
5509 // Avoid having the cursor of an expression "overwrite" the annotation of the
5510 // variable declaration that it belongs to.
5511 // This can happen for C++ constructor expressions whose range generally
5512 // include the variable declaration, e.g.:
5513 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005514 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005515 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005516 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 const unsigned I = NextToken();
5518 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5519 E->getLocStart() == D->getLocation() &&
5520 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005521 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 AdvanceToken();
5523 }
5524 }
5525 }
5526
5527 // Before recursing into the children keep some state that we are going
5528 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5529 // extra work after the child nodes are visited.
5530 // Note that we don't call VisitChildren here to avoid traversing statements
5531 // code-recursively which can blow the stack.
5532
5533 PostChildrenInfo Info;
5534 Info.Cursor = cursor;
5535 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005536 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005537 Info.BeforeChildrenTokenIdx = NextToken();
5538 PostChildrenInfos.push_back(Info);
5539
5540 return CXChildVisit_Recurse;
5541}
5542
5543bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5544 if (PostChildrenInfos.empty())
5545 return false;
5546 const PostChildrenInfo &Info = PostChildrenInfos.back();
5547 if (!clang_equalCursors(Info.Cursor, cursor))
5548 return false;
5549
5550 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5551 const unsigned AfterChildren = NextToken();
5552 SourceRange cursorRange = Info.CursorRange;
5553
5554 // Scan the tokens that are at the end of the cursor, but are not captured
5555 // but the child cursors.
5556 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5557
5558 // Scan the tokens that are at the beginning of the cursor, but are not
5559 // capture by the child cursors.
5560 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5561 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5562 break;
5563
5564 Cursors[I] = cursor;
5565 }
5566
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005567 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5568 // encountered the attribute cursor.
5569 if (clang_isAttribute(cursor.kind))
5570 TokIdx = Info.BeforeReachingCursorIdx;
5571
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 PostChildrenInfos.pop_back();
5573 return false;
5574}
5575
5576static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5577 CXCursor parent,
5578 CXClientData client_data) {
5579 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5580}
5581
5582static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5583 CXClientData client_data) {
5584 return static_cast<AnnotateTokensWorker*>(client_data)->
5585 postVisitChildren(cursor);
5586}
5587
5588namespace {
5589
5590/// \brief Uses the macro expansions in the preprocessing record to find
5591/// and mark tokens that are macro arguments. This info is used by the
5592/// AnnotateTokensWorker.
5593class MarkMacroArgTokensVisitor {
5594 SourceManager &SM;
5595 CXToken *Tokens;
5596 unsigned NumTokens;
5597 unsigned CurIdx;
5598
5599public:
5600 MarkMacroArgTokensVisitor(SourceManager &SM,
5601 CXToken *tokens, unsigned numTokens)
5602 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5603
5604 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5605 if (cursor.kind != CXCursor_MacroExpansion)
5606 return CXChildVisit_Continue;
5607
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005608 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 if (macroRange.getBegin() == macroRange.getEnd())
5610 return CXChildVisit_Continue; // it's not a function macro.
5611
5612 for (; CurIdx < NumTokens; ++CurIdx) {
5613 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5614 macroRange.getBegin()))
5615 break;
5616 }
5617
5618 if (CurIdx == NumTokens)
5619 return CXChildVisit_Break;
5620
5621 for (; CurIdx < NumTokens; ++CurIdx) {
5622 SourceLocation tokLoc = getTokenLoc(CurIdx);
5623 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5624 break;
5625
5626 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5627 }
5628
5629 if (CurIdx == NumTokens)
5630 return CXChildVisit_Break;
5631
5632 return CXChildVisit_Continue;
5633 }
5634
5635private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005636 CXToken &getTok(unsigned Idx) {
5637 assert(Idx < NumTokens);
5638 return Tokens[Idx];
5639 }
5640 const CXToken &getTok(unsigned Idx) const {
5641 assert(Idx < NumTokens);
5642 return Tokens[Idx];
5643 }
5644
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005646 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 }
5648
5649 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5650 // The third field is reserved and currently not used. Use it here
5651 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005652 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 }
5654};
5655
5656} // end anonymous namespace
5657
5658static CXChildVisitResult
5659MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5660 CXClientData client_data) {
5661 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5662 parent);
5663}
5664
5665namespace {
5666 struct clang_annotateTokens_Data {
5667 CXTranslationUnit TU;
5668 ASTUnit *CXXUnit;
5669 CXToken *Tokens;
5670 unsigned NumTokens;
5671 CXCursor *Cursors;
5672 };
5673}
5674
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005675/// \brief Used by \c annotatePreprocessorTokens.
5676/// \returns true if lexing was finished, false otherwise.
5677static bool lexNext(Lexer &Lex, Token &Tok,
5678 unsigned &NextIdx, unsigned NumTokens) {
5679 if (NextIdx >= NumTokens)
5680 return true;
5681
5682 ++NextIdx;
5683 Lex.LexFromRawLexer(Tok);
5684 if (Tok.is(tok::eof))
5685 return true;
5686
5687 return false;
5688}
5689
Guy Benyei11169dd2012-12-18 14:30:41 +00005690static void annotatePreprocessorTokens(CXTranslationUnit TU,
5691 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005692 CXCursor *Cursors,
5693 CXToken *Tokens,
5694 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005695 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005696
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005697 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5699 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005700 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005701 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005702 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005703
5704 if (BeginLocInfo.first != EndLocInfo.first)
5705 return;
5706
5707 StringRef Buffer;
5708 bool Invalid = false;
5709 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5710 if (Buffer.empty() || Invalid)
5711 return;
5712
5713 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5714 CXXUnit->getASTContext().getLangOpts(),
5715 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5716 Buffer.end());
5717 Lex.SetCommentRetentionState(true);
5718
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005719 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 // Lex tokens in raw mode until we hit the end of the range, to avoid
5721 // entering #includes or expanding macros.
5722 while (true) {
5723 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005724 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5725 break;
5726 unsigned TokIdx = NextIdx-1;
5727 assert(Tok.getLocation() ==
5728 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005729
5730 reprocess:
5731 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005732 // We have found a preprocessing directive. Annotate the tokens
5733 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 //
5735 // FIXME: Some simple tests here could identify macro definitions and
5736 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005737
5738 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005739 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5740 break;
5741
Craig Topper69186e72014-06-08 08:38:04 +00005742 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005743 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005744 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5745 break;
5746
5747 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005748 IdentifierInfo &II =
5749 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005750 SourceLocation MappedTokLoc =
5751 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5752 MI = getMacroInfo(II, MappedTokLoc, TU);
5753 }
5754 }
5755
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005756 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5759 finished = true;
5760 break;
5761 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005762 // If we are in a macro definition, check if the token was ever a
5763 // macro name and annotate it if that's the case.
5764 if (MI) {
5765 SourceLocation SaveLoc = Tok.getLocation();
5766 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5767 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5768 Tok.setLocation(SaveLoc);
5769 if (MacroDef)
5770 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5771 Tok.getLocation(), TU);
5772 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005773 } while (!Tok.isAtStartOfLine());
5774
5775 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5776 assert(TokIdx <= LastIdx);
5777 SourceLocation EndLoc =
5778 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5779 CXCursor Cursor =
5780 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5781
5782 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005783 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005784
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005785 if (finished)
5786 break;
5787 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 }
5790}
5791
5792// This gets run a separate thread to avoid stack blowout.
5793static void clang_annotateTokensImpl(void *UserData) {
5794 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5795 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5796 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5797 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5798 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5799
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005800 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5802 setThreadBackgroundPriority();
5803
5804 // Determine the region of interest, which contains all of the tokens.
5805 SourceRange RegionOfInterest;
5806 RegionOfInterest.setBegin(
5807 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5808 RegionOfInterest.setEnd(
5809 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5810 Tokens[NumTokens-1])));
5811
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 // Relex the tokens within the source range to look for preprocessing
5813 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005814 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005815
5816 // If begin location points inside a macro argument, set it to the expansion
5817 // location so we can have the full context when annotating semantically.
5818 {
5819 SourceManager &SM = CXXUnit->getSourceManager();
5820 SourceLocation Loc =
5821 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5822 if (Loc.isMacroID())
5823 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5824 }
5825
Guy Benyei11169dd2012-12-18 14:30:41 +00005826 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5827 // Search and mark tokens that are macro argument expansions.
5828 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5829 Tokens, NumTokens);
5830 CursorVisitor MacroArgMarker(TU,
5831 MarkMacroArgTokensVisitorDelegate, &Visitor,
5832 /*VisitPreprocessorLast=*/true,
5833 /*VisitIncludedEntities=*/false,
5834 RegionOfInterest);
5835 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5836 }
5837
5838 // Annotate all of the source locations in the region of interest that map to
5839 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005840 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005841
5842 // FIXME: We use a ridiculous stack size here because the data-recursion
5843 // algorithm uses a large stack frame than the non-data recursive version,
5844 // and AnnotationTokensWorker currently transforms the data-recursion
5845 // algorithm back into a traditional recursion by explicitly calling
5846 // VisitChildren(). We will need to remove this explicit recursive call.
5847 W.AnnotateTokens();
5848
5849 // If we ran into any entities that involve context-sensitive keywords,
5850 // take another pass through the tokens to mark them as such.
5851 if (W.hasContextSensitiveKeywords()) {
5852 for (unsigned I = 0; I != NumTokens; ++I) {
5853 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5854 continue;
5855
5856 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5857 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005858 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5860 if (Property->getPropertyAttributesAsWritten() != 0 &&
5861 llvm::StringSwitch<bool>(II->getName())
5862 .Case("readonly", true)
5863 .Case("assign", true)
5864 .Case("unsafe_unretained", true)
5865 .Case("readwrite", true)
5866 .Case("retain", true)
5867 .Case("copy", true)
5868 .Case("nonatomic", true)
5869 .Case("atomic", true)
5870 .Case("getter", true)
5871 .Case("setter", true)
5872 .Case("strong", true)
5873 .Case("weak", true)
5874 .Default(false))
5875 Tokens[I].int_data[0] = CXToken_Keyword;
5876 }
5877 continue;
5878 }
5879
5880 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5881 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5882 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5883 if (llvm::StringSwitch<bool>(II->getName())
5884 .Case("in", true)
5885 .Case("out", true)
5886 .Case("inout", true)
5887 .Case("oneway", true)
5888 .Case("bycopy", true)
5889 .Case("byref", true)
5890 .Default(false))
5891 Tokens[I].int_data[0] = CXToken_Keyword;
5892 continue;
5893 }
5894
5895 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5896 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5897 Tokens[I].int_data[0] = CXToken_Keyword;
5898 continue;
5899 }
5900 }
5901 }
5902}
5903
5904extern "C" {
5905
5906void clang_annotateTokens(CXTranslationUnit TU,
5907 CXToken *Tokens, unsigned NumTokens,
5908 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005909 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005910 LOG_BAD_TU(TU);
5911 return;
5912 }
5913 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005914 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005916 }
5917
5918 LOG_FUNC_SECTION {
5919 *Log << TU << ' ';
5920 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5921 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5922 *Log << clang_getRange(bloc, eloc);
5923 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005924
5925 // Any token we don't specifically annotate will have a NULL cursor.
5926 CXCursor C = clang_getNullCursor();
5927 for (unsigned I = 0; I != NumTokens; ++I)
5928 Cursors[I] = C;
5929
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005930 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 if (!CXXUnit)
5932 return;
5933
5934 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5935
5936 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5937 llvm::CrashRecoveryContext CRC;
5938 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5939 GetSafetyThreadStackSize() * 2)) {
5940 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5941 }
5942}
5943
5944} // end: extern "C"
5945
5946//===----------------------------------------------------------------------===//
5947// Operations for querying linkage of a cursor.
5948//===----------------------------------------------------------------------===//
5949
5950extern "C" {
5951CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5952 if (!clang_isDeclaration(cursor.kind))
5953 return CXLinkage_Invalid;
5954
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005955 const Decl *D = cxcursor::getCursorDecl(cursor);
5956 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005957 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005958 case NoLinkage:
5959 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005960 case InternalLinkage: return CXLinkage_Internal;
5961 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5962 case ExternalLinkage: return CXLinkage_External;
5963 };
5964
5965 return CXLinkage_Invalid;
5966}
5967} // end: extern "C"
5968
5969//===----------------------------------------------------------------------===//
5970// Operations for querying language of a cursor.
5971//===----------------------------------------------------------------------===//
5972
5973static CXLanguageKind getDeclLanguage(const Decl *D) {
5974 if (!D)
5975 return CXLanguage_C;
5976
5977 switch (D->getKind()) {
5978 default:
5979 break;
5980 case Decl::ImplicitParam:
5981 case Decl::ObjCAtDefsField:
5982 case Decl::ObjCCategory:
5983 case Decl::ObjCCategoryImpl:
5984 case Decl::ObjCCompatibleAlias:
5985 case Decl::ObjCImplementation:
5986 case Decl::ObjCInterface:
5987 case Decl::ObjCIvar:
5988 case Decl::ObjCMethod:
5989 case Decl::ObjCProperty:
5990 case Decl::ObjCPropertyImpl:
5991 case Decl::ObjCProtocol:
5992 return CXLanguage_ObjC;
5993 case Decl::CXXConstructor:
5994 case Decl::CXXConversion:
5995 case Decl::CXXDestructor:
5996 case Decl::CXXMethod:
5997 case Decl::CXXRecord:
5998 case Decl::ClassTemplate:
5999 case Decl::ClassTemplatePartialSpecialization:
6000 case Decl::ClassTemplateSpecialization:
6001 case Decl::Friend:
6002 case Decl::FriendTemplate:
6003 case Decl::FunctionTemplate:
6004 case Decl::LinkageSpec:
6005 case Decl::Namespace:
6006 case Decl::NamespaceAlias:
6007 case Decl::NonTypeTemplateParm:
6008 case Decl::StaticAssert:
6009 case Decl::TemplateTemplateParm:
6010 case Decl::TemplateTypeParm:
6011 case Decl::UnresolvedUsingTypename:
6012 case Decl::UnresolvedUsingValue:
6013 case Decl::Using:
6014 case Decl::UsingDirective:
6015 case Decl::UsingShadow:
6016 return CXLanguage_CPlusPlus;
6017 }
6018
6019 return CXLanguage_C;
6020}
6021
6022extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006023
6024static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6025 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6026 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006027
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006028 switch (D->getAvailability()) {
6029 case AR_Available:
6030 case AR_NotYetIntroduced:
6031 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006032 return getCursorAvailabilityForDecl(
6033 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006034 return CXAvailability_Available;
6035
6036 case AR_Deprecated:
6037 return CXAvailability_Deprecated;
6038
6039 case AR_Unavailable:
6040 return CXAvailability_NotAvailable;
6041 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006042
6043 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006044}
6045
Guy Benyei11169dd2012-12-18 14:30:41 +00006046enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6047 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006048 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6049 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006050
6051 return CXAvailability_Available;
6052}
6053
6054static CXVersion convertVersion(VersionTuple In) {
6055 CXVersion Out = { -1, -1, -1 };
6056 if (In.empty())
6057 return Out;
6058
6059 Out.Major = In.getMajor();
6060
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006061 Optional<unsigned> Minor = In.getMinor();
6062 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006063 Out.Minor = *Minor;
6064 else
6065 return Out;
6066
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006067 Optional<unsigned> Subminor = In.getSubminor();
6068 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006069 Out.Subminor = *Subminor;
6070
6071 return Out;
6072}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006073
6074static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6075 int *always_deprecated,
6076 CXString *deprecated_message,
6077 int *always_unavailable,
6078 CXString *unavailable_message,
6079 CXPlatformAvailability *availability,
6080 int availability_size) {
6081 bool HadAvailAttr = false;
6082 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006083 for (auto A : D->attrs()) {
6084 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006085 HadAvailAttr = true;
6086 if (always_deprecated)
6087 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006088 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006089 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006090 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006091 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006092 continue;
6093 }
6094
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006095 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006096 HadAvailAttr = true;
6097 if (always_unavailable)
6098 *always_unavailable = 1;
6099 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006100 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006101 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6102 }
6103 continue;
6104 }
6105
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006106 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006107 HadAvailAttr = true;
6108 if (N < availability_size) {
6109 availability[N].Platform
6110 = cxstring::createDup(Avail->getPlatform()->getName());
6111 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6112 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6113 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6114 availability[N].Unavailable = Avail->getUnavailable();
6115 availability[N].Message = cxstring::createDup(Avail->getMessage());
6116 }
6117 ++N;
6118 }
6119 }
6120
6121 if (!HadAvailAttr)
6122 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6123 return getCursorPlatformAvailabilityForDecl(
6124 cast<Decl>(EnumConst->getDeclContext()),
6125 always_deprecated,
6126 deprecated_message,
6127 always_unavailable,
6128 unavailable_message,
6129 availability,
6130 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006131
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006132 return N;
6133}
6134
Guy Benyei11169dd2012-12-18 14:30:41 +00006135int clang_getCursorPlatformAvailability(CXCursor cursor,
6136 int *always_deprecated,
6137 CXString *deprecated_message,
6138 int *always_unavailable,
6139 CXString *unavailable_message,
6140 CXPlatformAvailability *availability,
6141 int availability_size) {
6142 if (always_deprecated)
6143 *always_deprecated = 0;
6144 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006145 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 if (always_unavailable)
6147 *always_unavailable = 0;
6148 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006149 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006150
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 if (!clang_isDeclaration(cursor.kind))
6152 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006153
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006154 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 if (!D)
6156 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006157
6158 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6159 deprecated_message,
6160 always_unavailable,
6161 unavailable_message,
6162 availability,
6163 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006164}
6165
6166void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6167 clang_disposeString(availability->Platform);
6168 clang_disposeString(availability->Message);
6169}
6170
6171CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6172 if (clang_isDeclaration(cursor.kind))
6173 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6174
6175 return CXLanguage_Invalid;
6176}
6177
6178 /// \brief If the given cursor is the "templated" declaration
6179 /// descibing a class or function template, return the class or
6180 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006181static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006183 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006184
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006185 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006186 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6187 return FunTmpl;
6188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006189 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6191 return ClassTmpl;
6192
6193 return D;
6194}
6195
6196CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6197 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006198 if (const Decl *D = getCursorDecl(cursor)) {
6199 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 if (!DC)
6201 return clang_getNullCursor();
6202
6203 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6204 getCursorTU(cursor));
6205 }
6206 }
6207
6208 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006209 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 return MakeCXCursor(D, getCursorTU(cursor));
6211 }
6212
6213 return clang_getNullCursor();
6214}
6215
6216CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6217 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006218 if (const Decl *D = getCursorDecl(cursor)) {
6219 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 if (!DC)
6221 return clang_getNullCursor();
6222
6223 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6224 getCursorTU(cursor));
6225 }
6226 }
6227
6228 // FIXME: Note that we can't easily compute the lexical context of a
6229 // statement or expression, so we return nothing.
6230 return clang_getNullCursor();
6231}
6232
6233CXFile clang_getIncludedFile(CXCursor cursor) {
6234 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006235 return nullptr;
6236
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006237 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006238 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006239}
6240
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006241unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6242 if (C.kind != CXCursor_ObjCPropertyDecl)
6243 return CXObjCPropertyAttr_noattr;
6244
6245 unsigned Result = CXObjCPropertyAttr_noattr;
6246 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6247 ObjCPropertyDecl::PropertyAttributeKind Attr =
6248 PD->getPropertyAttributesAsWritten();
6249
6250#define SET_CXOBJCPROP_ATTR(A) \
6251 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6252 Result |= CXObjCPropertyAttr_##A
6253 SET_CXOBJCPROP_ATTR(readonly);
6254 SET_CXOBJCPROP_ATTR(getter);
6255 SET_CXOBJCPROP_ATTR(assign);
6256 SET_CXOBJCPROP_ATTR(readwrite);
6257 SET_CXOBJCPROP_ATTR(retain);
6258 SET_CXOBJCPROP_ATTR(copy);
6259 SET_CXOBJCPROP_ATTR(nonatomic);
6260 SET_CXOBJCPROP_ATTR(setter);
6261 SET_CXOBJCPROP_ATTR(atomic);
6262 SET_CXOBJCPROP_ATTR(weak);
6263 SET_CXOBJCPROP_ATTR(strong);
6264 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6265#undef SET_CXOBJCPROP_ATTR
6266
6267 return Result;
6268}
6269
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006270unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6271 if (!clang_isDeclaration(C.kind))
6272 return CXObjCDeclQualifier_None;
6273
6274 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6275 const Decl *D = getCursorDecl(C);
6276 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6277 QT = MD->getObjCDeclQualifier();
6278 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6279 QT = PD->getObjCDeclQualifier();
6280 if (QT == Decl::OBJC_TQ_None)
6281 return CXObjCDeclQualifier_None;
6282
6283 unsigned Result = CXObjCDeclQualifier_None;
6284 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6285 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6286 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6287 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6288 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6289 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6290
6291 return Result;
6292}
6293
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006294unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6295 if (!clang_isDeclaration(C.kind))
6296 return 0;
6297
6298 const Decl *D = getCursorDecl(C);
6299 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6300 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6301 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6302 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6303
6304 return 0;
6305}
6306
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006307unsigned clang_Cursor_isVariadic(CXCursor C) {
6308 if (!clang_isDeclaration(C.kind))
6309 return 0;
6310
6311 const Decl *D = getCursorDecl(C);
6312 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6313 return FD->isVariadic();
6314 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6315 return MD->isVariadic();
6316
6317 return 0;
6318}
6319
Guy Benyei11169dd2012-12-18 14:30:41 +00006320CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6321 if (!clang_isDeclaration(C.kind))
6322 return clang_getNullRange();
6323
6324 const Decl *D = getCursorDecl(C);
6325 ASTContext &Context = getCursorContext(C);
6326 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6327 if (!RC)
6328 return clang_getNullRange();
6329
6330 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6331}
6332
6333CXString clang_Cursor_getRawCommentText(CXCursor C) {
6334 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006335 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006336
6337 const Decl *D = getCursorDecl(C);
6338 ASTContext &Context = getCursorContext(C);
6339 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6340 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6341 StringRef();
6342
6343 // Don't duplicate the string because RawText points directly into source
6344 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006345 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006346}
6347
6348CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6349 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006350 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006351
6352 const Decl *D = getCursorDecl(C);
6353 const ASTContext &Context = getCursorContext(C);
6354 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6355
6356 if (RC) {
6357 StringRef BriefText = RC->getBriefText(Context);
6358
6359 // Don't duplicate the string because RawComment ensures that this memory
6360 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006361 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 }
6363
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006364 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006365}
6366
Guy Benyei11169dd2012-12-18 14:30:41 +00006367CXModule clang_Cursor_getModule(CXCursor C) {
6368 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006369 if (const ImportDecl *ImportD =
6370 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006371 return ImportD->getImportedModule();
6372 }
6373
Craig Topper69186e72014-06-08 08:38:04 +00006374 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006375}
6376
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006377CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6378 if (isNotUsableTU(TU)) {
6379 LOG_BAD_TU(TU);
6380 return nullptr;
6381 }
6382 if (!File)
6383 return nullptr;
6384 FileEntry *FE = static_cast<FileEntry *>(File);
6385
6386 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6387 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6388 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6389
6390 if (Module *Mod = Header.getModule()) {
6391 if (Header.getRole() != ModuleMap::ExcludedHeader)
6392 return Mod;
6393 }
6394 return nullptr;
6395}
6396
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006397CXFile clang_Module_getASTFile(CXModule CXMod) {
6398 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006399 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006400 Module *Mod = static_cast<Module*>(CXMod);
6401 return const_cast<FileEntry *>(Mod->getASTFile());
6402}
6403
Guy Benyei11169dd2012-12-18 14:30:41 +00006404CXModule clang_Module_getParent(CXModule CXMod) {
6405 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006406 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 Module *Mod = static_cast<Module*>(CXMod);
6408 return Mod->Parent;
6409}
6410
6411CXString clang_Module_getName(CXModule CXMod) {
6412 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006413 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006415 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006416}
6417
6418CXString clang_Module_getFullName(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->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006423}
6424
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006425int clang_Module_isSystem(CXModule CXMod) {
6426 if (!CXMod)
6427 return 0;
6428 Module *Mod = static_cast<Module*>(CXMod);
6429 return Mod->IsSystem;
6430}
6431
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006432unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6433 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006434 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006435 LOG_BAD_TU(TU);
6436 return 0;
6437 }
6438 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 return 0;
6440 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006441 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6442 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6443 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006444}
6445
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006446CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6447 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006448 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006449 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006450 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006451 }
6452 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006453 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006455 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006456
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006457 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6458 if (Index < TopHeaders.size())
6459 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006460
Craig Topper69186e72014-06-08 08:38:04 +00006461 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006462}
6463
6464} // end: extern "C"
6465
6466//===----------------------------------------------------------------------===//
6467// C++ AST instrospection.
6468//===----------------------------------------------------------------------===//
6469
6470extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006471unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6472 if (!clang_isDeclaration(C.kind))
6473 return 0;
6474
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006475 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006476 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006477 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006478 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6479}
6480
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006481unsigned clang_CXXMethod_isConst(CXCursor C) {
6482 if (!clang_isDeclaration(C.kind))
6483 return 0;
6484
6485 const Decl *D = cxcursor::getCursorDecl(C);
6486 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006487 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006488 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6489}
6490
Guy Benyei11169dd2012-12-18 14:30:41 +00006491unsigned clang_CXXMethod_isStatic(CXCursor C) {
6492 if (!clang_isDeclaration(C.kind))
6493 return 0;
6494
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006495 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006496 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006497 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 return (Method && Method->isStatic()) ? 1 : 0;
6499}
6500
6501unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6502 if (!clang_isDeclaration(C.kind))
6503 return 0;
6504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006505 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006506 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006507 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006508 return (Method && Method->isVirtual()) ? 1 : 0;
6509}
6510} // end: extern "C"
6511
6512//===----------------------------------------------------------------------===//
6513// Attribute introspection.
6514//===----------------------------------------------------------------------===//
6515
6516extern "C" {
6517CXType clang_getIBOutletCollectionType(CXCursor C) {
6518 if (C.kind != CXCursor_IBOutletCollectionAttr)
6519 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6520
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006521 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6523
6524 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6525}
6526} // end: extern "C"
6527
6528//===----------------------------------------------------------------------===//
6529// Inspecting memory usage.
6530//===----------------------------------------------------------------------===//
6531
6532typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6533
6534static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6535 enum CXTUResourceUsageKind k,
6536 unsigned long amount) {
6537 CXTUResourceUsageEntry entry = { k, amount };
6538 entries.push_back(entry);
6539}
6540
6541extern "C" {
6542
6543const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6544 const char *str = "";
6545 switch (kind) {
6546 case CXTUResourceUsage_AST:
6547 str = "ASTContext: expressions, declarations, and types";
6548 break;
6549 case CXTUResourceUsage_Identifiers:
6550 str = "ASTContext: identifiers";
6551 break;
6552 case CXTUResourceUsage_Selectors:
6553 str = "ASTContext: selectors";
6554 break;
6555 case CXTUResourceUsage_GlobalCompletionResults:
6556 str = "Code completion: cached global results";
6557 break;
6558 case CXTUResourceUsage_SourceManagerContentCache:
6559 str = "SourceManager: content cache allocator";
6560 break;
6561 case CXTUResourceUsage_AST_SideTables:
6562 str = "ASTContext: side tables";
6563 break;
6564 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6565 str = "SourceManager: malloc'ed memory buffers";
6566 break;
6567 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6568 str = "SourceManager: mmap'ed memory buffers";
6569 break;
6570 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6571 str = "ExternalASTSource: malloc'ed memory buffers";
6572 break;
6573 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6574 str = "ExternalASTSource: mmap'ed memory buffers";
6575 break;
6576 case CXTUResourceUsage_Preprocessor:
6577 str = "Preprocessor: malloc'ed memory";
6578 break;
6579 case CXTUResourceUsage_PreprocessingRecord:
6580 str = "Preprocessor: PreprocessingRecord";
6581 break;
6582 case CXTUResourceUsage_SourceManager_DataStructures:
6583 str = "SourceManager: data structures and tables";
6584 break;
6585 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6586 str = "Preprocessor: header search tables";
6587 break;
6588 }
6589 return str;
6590}
6591
6592CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006593 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006594 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006595 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 return usage;
6597 }
6598
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006599 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006600 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006601 ASTContext &astContext = astUnit->getASTContext();
6602
6603 // How much memory is used by AST nodes and types?
6604 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6605 (unsigned long) astContext.getASTAllocatedMemory());
6606
6607 // How much memory is used by identifiers?
6608 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6609 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6610
6611 // How much memory is used for selectors?
6612 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6613 (unsigned long) astContext.Selectors.getTotalMemory());
6614
6615 // How much memory is used by ASTContext's side tables?
6616 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6617 (unsigned long) astContext.getSideTableAllocatedMemory());
6618
6619 // How much memory is used for caching global code completion results?
6620 unsigned long completionBytes = 0;
6621 if (GlobalCodeCompletionAllocator *completionAllocator =
6622 astUnit->getCachedCompletionAllocator().getPtr()) {
6623 completionBytes = completionAllocator->getTotalMemory();
6624 }
6625 createCXTUResourceUsageEntry(*entries,
6626 CXTUResourceUsage_GlobalCompletionResults,
6627 completionBytes);
6628
6629 // How much memory is being used by SourceManager's content cache?
6630 createCXTUResourceUsageEntry(*entries,
6631 CXTUResourceUsage_SourceManagerContentCache,
6632 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6633
6634 // How much memory is being used by the MemoryBuffer's in SourceManager?
6635 const SourceManager::MemoryBufferSizes &srcBufs =
6636 astUnit->getSourceManager().getMemoryBufferSizes();
6637
6638 createCXTUResourceUsageEntry(*entries,
6639 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6640 (unsigned long) srcBufs.malloc_bytes);
6641 createCXTUResourceUsageEntry(*entries,
6642 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6643 (unsigned long) srcBufs.mmap_bytes);
6644 createCXTUResourceUsageEntry(*entries,
6645 CXTUResourceUsage_SourceManager_DataStructures,
6646 (unsigned long) astContext.getSourceManager()
6647 .getDataStructureSizes());
6648
6649 // How much memory is being used by the ExternalASTSource?
6650 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6651 const ExternalASTSource::MemoryBufferSizes &sizes =
6652 esrc->getMemoryBufferSizes();
6653
6654 createCXTUResourceUsageEntry(*entries,
6655 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6656 (unsigned long) sizes.malloc_bytes);
6657 createCXTUResourceUsageEntry(*entries,
6658 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6659 (unsigned long) sizes.mmap_bytes);
6660 }
6661
6662 // How much memory is being used by the Preprocessor?
6663 Preprocessor &pp = astUnit->getPreprocessor();
6664 createCXTUResourceUsageEntry(*entries,
6665 CXTUResourceUsage_Preprocessor,
6666 pp.getTotalMemory());
6667
6668 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6669 createCXTUResourceUsageEntry(*entries,
6670 CXTUResourceUsage_PreprocessingRecord,
6671 pRec->getTotalMemory());
6672 }
6673
6674 createCXTUResourceUsageEntry(*entries,
6675 CXTUResourceUsage_Preprocessor_HeaderSearch,
6676 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006677
Guy Benyei11169dd2012-12-18 14:30:41 +00006678 CXTUResourceUsage usage = { (void*) entries.get(),
6679 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006680 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006681 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006682 return usage;
6683}
6684
6685void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6686 if (usage.data)
6687 delete (MemUsageEntries*) usage.data;
6688}
6689
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006690CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6691 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006692 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006693 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006694
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006695 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006696 LOG_BAD_TU(TU);
6697 return skipped;
6698 }
6699
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006700 if (!file)
6701 return skipped;
6702
6703 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6704 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6705 if (!ppRec)
6706 return skipped;
6707
6708 ASTContext &Ctx = astUnit->getASTContext();
6709 SourceManager &sm = Ctx.getSourceManager();
6710 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6711 FileID wantedFileID = sm.translateFile(fileEntry);
6712
6713 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6714 std::vector<SourceRange> wantedRanges;
6715 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6716 i != ei; ++i) {
6717 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6718 wantedRanges.push_back(*i);
6719 }
6720
6721 skipped->count = wantedRanges.size();
6722 skipped->ranges = new CXSourceRange[skipped->count];
6723 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6724 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6725
6726 return skipped;
6727}
6728
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006729void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6730 if (ranges) {
6731 delete[] ranges->ranges;
6732 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006733 }
6734}
6735
Guy Benyei11169dd2012-12-18 14:30:41 +00006736} // end extern "C"
6737
6738void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6739 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6740 for (unsigned I = 0; I != Usage.numEntries; ++I)
6741 fprintf(stderr, " %s: %lu\n",
6742 clang_getTUResourceUsageName(Usage.entries[I].kind),
6743 Usage.entries[I].amount);
6744
6745 clang_disposeCXTUResourceUsage(Usage);
6746}
6747
6748//===----------------------------------------------------------------------===//
6749// Misc. utility functions.
6750//===----------------------------------------------------------------------===//
6751
6752/// Default to using an 8 MB stack size on "safety" threads.
6753static unsigned SafetyStackThreadSize = 8 << 20;
6754
6755namespace clang {
6756
6757bool RunSafely(llvm::CrashRecoveryContext &CRC,
6758 void (*Fn)(void*), void *UserData,
6759 unsigned Size) {
6760 if (!Size)
6761 Size = GetSafetyThreadStackSize();
6762 if (Size)
6763 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6764 return CRC.RunSafely(Fn, UserData);
6765}
6766
6767unsigned GetSafetyThreadStackSize() {
6768 return SafetyStackThreadSize;
6769}
6770
6771void SetSafetyThreadStackSize(unsigned Value) {
6772 SafetyStackThreadSize = Value;
6773}
6774
6775}
6776
6777void clang::setThreadBackgroundPriority() {
6778 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6779 return;
6780
6781 // FIXME: Move to llvm/Support and make it cross-platform.
6782#ifdef __APPLE__
6783 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6784#endif
6785}
6786
6787void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6788 if (!Unit)
6789 return;
6790
6791 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6792 DEnd = Unit->stored_diag_end();
6793 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006794 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006795 CXString Msg = clang_formatDiagnostic(&Diag,
6796 clang_defaultDiagnosticDisplayOptions());
6797 fprintf(stderr, "%s\n", clang_getCString(Msg));
6798 clang_disposeString(Msg);
6799 }
6800#ifdef LLVM_ON_WIN32
6801 // On Windows, force a flush, since there may be multiple copies of
6802 // stderr and stdout in the file system, all with different buffers
6803 // but writing to the same device.
6804 fflush(stderr);
6805#endif
6806}
6807
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006808MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6809 SourceLocation MacroDefLoc,
6810 CXTranslationUnit TU){
6811 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006812 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006813 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006814 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006815
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006816 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006817 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006818 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006819 if (MD) {
6820 for (MacroDirective::DefInfo
6821 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6822 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6823 return Def.getMacroInfo();
6824 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006825 }
6826
Craig Topper69186e72014-06-08 08:38:04 +00006827 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006828}
6829
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006830const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6831 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006832 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834 const IdentifierInfo *II = MacroDef->getName();
6835 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006836 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006837
6838 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6839}
6840
6841MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6842 const Token &Tok,
6843 CXTranslationUnit TU) {
6844 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006845 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006846 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006847 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006848
6849 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6852 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006853 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854
6855 // Check that the token is inside the definition and not its argument list.
6856 SourceManager &SM = Unit->getSourceManager();
6857 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006859 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006860 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006861
6862 Preprocessor &PP = Unit->getPreprocessor();
6863 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6864 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006865 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866
Alp Toker2d57cea2014-05-17 04:53:25 +00006867 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006868 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006869 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006870
6871 // Check that the identifier is not one of the macro arguments.
6872 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006874
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006875 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6876 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006877 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006878
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006879 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006880}
6881
6882MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6883 SourceLocation Loc,
6884 CXTranslationUnit TU) {
6885 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006886 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006887
6888 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006889 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006890 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006891 Preprocessor &PP = Unit->getPreprocessor();
6892 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006893 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006894 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6895 Token Tok;
6896 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006897 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006898
6899 return checkForMacroInMacroDefinition(MI, Tok, TU);
6900}
6901
Guy Benyei11169dd2012-12-18 14:30:41 +00006902extern "C" {
6903
6904CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006905 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006906}
6907
6908} // end: extern "C"
6909
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006910Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6911 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006912 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006913 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006914 if (Unit->isMainFileAST())
6915 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006916 return *this;
6917 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006918 } else {
6919 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006920 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006921 return *this;
6922}
6923
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006924Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6925 *this << FE->getName();
6926 return *this;
6927}
6928
6929Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6930 CXString cursorName = clang_getCursorDisplayName(cursor);
6931 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6932 clang_disposeString(cursorName);
6933 return *this;
6934}
6935
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006936Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6937 CXFile File;
6938 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006939 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006940 CXString FileName = clang_getFileName(File);
6941 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6942 clang_disposeString(FileName);
6943 return *this;
6944}
6945
6946Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6947 CXSourceLocation BLoc = clang_getRangeStart(range);
6948 CXSourceLocation ELoc = clang_getRangeEnd(range);
6949
6950 CXFile BFile;
6951 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006952 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006953
6954 CXFile EFile;
6955 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006956 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006957
6958 CXString BFileName = clang_getFileName(BFile);
6959 if (BFile == EFile) {
6960 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6961 BLine, BColumn, ELine, EColumn);
6962 } else {
6963 CXString EFileName = clang_getFileName(EFile);
6964 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6965 BLine, BColumn)
6966 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6967 ELine, EColumn);
6968 clang_disposeString(EFileName);
6969 }
6970 clang_disposeString(BFileName);
6971 return *this;
6972}
6973
6974Logger &cxindex::Logger::operator<<(CXString Str) {
6975 *this << clang_getCString(Str);
6976 return *this;
6977}
6978
6979Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6980 LogOS << Fmt;
6981 return *this;
6982}
6983
6984cxindex::Logger::~Logger() {
6985 LogOS.flush();
6986
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00006987 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006988
6989 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6990
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006991 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006992 OS << "[libclang:" << Name << ':';
6993
6994 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006995#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006996 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6997 OS << tid << ':';
6998#endif
6999
7000 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7001 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7002 OS << Msg.str() << '\n';
7003
7004 if (Trace) {
7005 llvm::sys::PrintStackTrace(stderr);
7006 OS << "--------------------------------------------------\n";
7007 }
7008}